mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-30 10:00:48 +00:00
Add strings
This commit is contained in:
parent
a1e8ad2c37
commit
09b321530d
@ -19,7 +19,6 @@ import androidx.compose.foundation.layout.Row
|
|||||||
import androidx.compose.foundation.layout.aspectRatio
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.requiredWidth
|
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.foundation.pager.HorizontalPager
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
@ -72,10 +71,12 @@ import org.thoughtcrime.securesms.ui.Cell
|
|||||||
import org.thoughtcrime.securesms.ui.CellNoMargin
|
import org.thoughtcrime.securesms.ui.CellNoMargin
|
||||||
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
|
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
|
||||||
import org.thoughtcrime.securesms.ui.Divider
|
import org.thoughtcrime.securesms.ui.Divider
|
||||||
|
import org.thoughtcrime.securesms.ui.GetString
|
||||||
import org.thoughtcrime.securesms.ui.HorizontalPagerIndicator
|
import org.thoughtcrime.securesms.ui.HorizontalPagerIndicator
|
||||||
import org.thoughtcrime.securesms.ui.ItemButton
|
import org.thoughtcrime.securesms.ui.ItemButton
|
||||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||||
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
|
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
|
||||||
|
import org.thoughtcrime.securesms.ui.TitledText
|
||||||
import org.thoughtcrime.securesms.ui.blackAlpha40
|
import org.thoughtcrime.securesms.ui.blackAlpha40
|
||||||
import org.thoughtcrime.securesms.ui.colorDestructive
|
import org.thoughtcrime.securesms.ui.colorDestructive
|
||||||
import org.thoughtcrime.securesms.ui.destructiveButtonColors
|
import org.thoughtcrime.securesms.ui.destructiveButtonColors
|
||||||
@ -160,22 +161,6 @@ class MessageDetailActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
JobQueue.shared.add(AttachmentDownloadJob(attachmentId, mmsId))
|
JobQueue.shared.add(AttachmentDownloadJob(attachmentId, mmsId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun PreviewMessageDetails() {
|
|
||||||
AppTheme {
|
|
||||||
MessageDetails(
|
|
||||||
state = MessageDetailsState(
|
|
||||||
attachments = listOf(),
|
|
||||||
sent = TitledText("Sent:", "6:12 AM Tue, 09/08/2022"),
|
|
||||||
received = TitledText("Received:", "6:12 AM Tue, 09/08/2022"),
|
|
||||||
error = TitledText("Error:", "Message failed to send"),
|
|
||||||
senderInfo = TitledText("Connor", "d4f1g54sdf5g1d5f4g65ds4564df65f4g65d54"),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@ -215,9 +200,9 @@ fun MessageDetails(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
Carousel(state.imageAttachments) { onClickImage(it) }
|
Carousel(state.imageAttachments) { onClickImage(it) }
|
||||||
state.nonImageAttachment?.fileDetails?.let { FileDetails(it) }
|
state.nonImageAttachmentFileDetails?.let { FileDetails(it) }
|
||||||
MetadataCell(state)
|
CellMetadata(state)
|
||||||
Buttons(
|
CellButtons(
|
||||||
onReply,
|
onReply,
|
||||||
onResend,
|
onResend,
|
||||||
onDelete,
|
onDelete,
|
||||||
@ -226,17 +211,18 @@ fun MessageDetails(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MetadataCell(
|
fun CellMetadata(
|
||||||
state: MessageDetailsState,
|
state: MessageDetailsState,
|
||||||
) {
|
) {
|
||||||
state.apply {
|
state.apply {
|
||||||
if (sent != null || received != null || senderInfo != null) CellWithPaddingAndMargin {
|
if (listOfNotNull(sent, received, error, senderInfo).isEmpty()) return
|
||||||
|
CellWithPaddingAndMargin {
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||||
sent?.let { TitledText(it) }
|
TitledText(sent)
|
||||||
received?.let { TitledText(it) }
|
TitledText(received)
|
||||||
error?.let { TitledErrorText(it) }
|
TitledErrorText(error)
|
||||||
senderInfo?.let {
|
senderInfo?.let {
|
||||||
TitledView(stringResource(id = R.string.message_details_header__from)) {
|
TitledView(state.fromTitle) {
|
||||||
Row {
|
Row {
|
||||||
sender?.let { Avatar(it) }
|
sender?.let { Avatar(it) }
|
||||||
TitledMonospaceText(it)
|
TitledMonospaceText(it)
|
||||||
@ -249,7 +235,7 @@ fun MetadataCell(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Buttons(
|
fun CellButtons(
|
||||||
onReply: () -> Unit = {},
|
onReply: () -> Unit = {},
|
||||||
onResend: (() -> Unit)? = null,
|
onResend: (() -> Unit)? = null,
|
||||||
onDelete: () -> Unit = {},
|
onDelete: () -> Unit = {},
|
||||||
@ -257,21 +243,21 @@ fun Buttons(
|
|||||||
Cell {
|
Cell {
|
||||||
Column {
|
Column {
|
||||||
ItemButton(
|
ItemButton(
|
||||||
stringResource(id = R.string.reply),
|
stringResource(R.string.reply),
|
||||||
R.drawable.ic_message_details__reply,
|
R.drawable.ic_message_details__reply,
|
||||||
onClick = onReply
|
onClick = onReply
|
||||||
)
|
)
|
||||||
Divider()
|
Divider()
|
||||||
onResend?.let {
|
onResend?.let {
|
||||||
ItemButton(
|
ItemButton(
|
||||||
stringResource(id = R.string.resend),
|
stringResource(R.string.resend),
|
||||||
R.drawable.ic_message_details__refresh,
|
R.drawable.ic_message_details__refresh,
|
||||||
onClick = it
|
onClick = it
|
||||||
)
|
)
|
||||||
Divider()
|
Divider()
|
||||||
}
|
}
|
||||||
ItemButton(
|
ItemButton(
|
||||||
stringResource(id = R.string.delete),
|
stringResource(R.string.delete),
|
||||||
R.drawable.ic_message_details__trash,
|
R.drawable.ic_message_details__trash,
|
||||||
colors = destructiveButtonColors(),
|
colors = destructiveButtonColors(),
|
||||||
onClick = onDelete
|
onClick = onDelete
|
||||||
@ -345,22 +331,6 @@ fun ExpandButton(modifier: Modifier = Modifier, onClick: () -> Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun PreviewFileDetails(
|
|
||||||
@PreviewParameter(ThemeResPreviewParameterProvider::class) themeResId: Int
|
|
||||||
) {
|
|
||||||
PreviewTheme(themeResId) {
|
|
||||||
FileDetails(
|
|
||||||
fileDetails = listOf(
|
|
||||||
TitledText("File Id:", "Screen Shot 2023-07-06 at 11.35.50 am.png"),
|
|
||||||
TitledText("File Type:", "image/png"),
|
|
||||||
TitledText("File Size:", "195.6kB"),
|
|
||||||
TitledText("Resolution:", "342x312"),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
@ -368,7 +338,20 @@ fun PreviewMessageDetails(
|
|||||||
@PreviewParameter(ThemeResPreviewParameterProvider::class) themeResId: Int
|
@PreviewParameter(ThemeResPreviewParameterProvider::class) themeResId: Int
|
||||||
) {
|
) {
|
||||||
PreviewTheme(themeResId) {
|
PreviewTheme(themeResId) {
|
||||||
PreviewMessageDetails()
|
MessageDetails(
|
||||||
|
state = MessageDetailsState(
|
||||||
|
nonImageAttachmentFileDetails = listOf(
|
||||||
|
TitledText(R.string.message_details_header__file_id, "Screen Shot 2023-07-06 at 11.35.50 am.png"),
|
||||||
|
TitledText(R.string.message_details_header__file_type, "image/png"),
|
||||||
|
TitledText(R.string.message_details_header__file_size, "195.6kB"),
|
||||||
|
TitledText(R.string.message_details_header__resolution, "342x312"),
|
||||||
|
),
|
||||||
|
sent = TitledText(R.string.message_details_header__sent, "6:12 AM Tue, 09/08/2022"),
|
||||||
|
received = TitledText(R.string.message_details_header__received, "6:12 AM Tue, 09/08/2022"),
|
||||||
|
error = TitledText(R.string.message_details_header__error, "Message failed to send"),
|
||||||
|
senderInfo = TitledText("Connor", "d4f1g54sdf5g1d5f4g65ds4564df65f4g65d54"),
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,37 +377,36 @@ fun FileDetails(fileDetails: List<TitledText>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TitledErrorText(titledText: TitledText, modifier: Modifier = Modifier) {
|
fun TitledErrorText(titledText: TitledText?) {
|
||||||
TitledText(
|
TitledText(
|
||||||
titledText,
|
titledText,
|
||||||
modifier = modifier,
|
|
||||||
valueStyle = LocalTextStyle.current.copy(color = colorDestructive)
|
valueStyle = LocalTextStyle.current.copy(color = colorDestructive)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TitledMonospaceText(titledText: TitledText, modifier: Modifier = Modifier) {
|
fun TitledMonospaceText(titledText: TitledText?) {
|
||||||
TitledText(
|
TitledText(
|
||||||
titledText,
|
titledText,
|
||||||
modifier = modifier,
|
|
||||||
valueStyle = LocalTextStyle.current.copy(fontFamily = FontFamily.Monospace)
|
valueStyle = LocalTextStyle.current.copy(fontFamily = FontFamily.Monospace)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TitledText(
|
fun TitledText(
|
||||||
titledText: TitledText,
|
titledText: TitledText?,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
valueStyle: TextStyle = LocalTextStyle.current
|
valueStyle: TextStyle = LocalTextStyle.current,
|
||||||
) {
|
) {
|
||||||
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
titledText?.apply {
|
||||||
Title(titledText.title)
|
TitledView(title, modifier) {
|
||||||
Text(titledText.value, style = valueStyle, modifier = Modifier.fillMaxWidth())
|
Text(text, style = valueStyle, modifier = Modifier.fillMaxWidth())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TitledView(title: String, modifier: Modifier = Modifier, content: @Composable () -> Unit) {
|
fun TitledView(title: GetString, modifier: Modifier = Modifier, content: @Composable () -> Unit) {
|
||||||
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||||
Title(title)
|
Title(title)
|
||||||
content()
|
content()
|
||||||
@ -432,6 +414,6 @@ fun TitledView(title: String, modifier: Modifier = Modifier, content: @Composabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Title(text: String, modifier: Modifier = Modifier) {
|
fun Title(title: GetString) {
|
||||||
Text(text, modifier = modifier, fontWeight = FontWeight.Bold)
|
Text(title.string(), fontWeight = FontWeight.Bold)
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,8 @@ package org.thoughtcrime.securesms.conversation.v2
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import network.loki.messenger.R
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.session.libsession.messaging.jobs.AttachmentDownloadJob
|
|
||||||
import org.session.libsession.messaging.jobs.JobQueue
|
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
|
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
|
||||||
import org.session.libsession.utilities.Util
|
import org.session.libsession.utilities.Util
|
||||||
import org.session.libsession.utilities.recipients.Recipient
|
import org.session.libsession.utilities.recipients.Recipient
|
||||||
@ -20,37 +16,12 @@ import org.thoughtcrime.securesms.database.model.MessageRecord
|
|||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.mms.ImageSlide
|
import org.thoughtcrime.securesms.mms.ImageSlide
|
||||||
import org.thoughtcrime.securesms.mms.Slide
|
import org.thoughtcrime.securesms.mms.Slide
|
||||||
import java.util.*
|
import org.thoughtcrime.securesms.ui.GetString
|
||||||
|
import org.thoughtcrime.securesms.ui.TitledText
|
||||||
|
import java.util.Date
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
data class TitledText(val title: String, val value: String)
|
|
||||||
|
|
||||||
data class MessageDetailsState(
|
|
||||||
val attachments: List<Attachment> = emptyList(),
|
|
||||||
val record: MessageRecord? = null,
|
|
||||||
val mmsRecord: MmsMessageRecord? = null,
|
|
||||||
val sent: TitledText? = null,
|
|
||||||
val received: TitledText? = null,
|
|
||||||
val error: TitledText? = null,
|
|
||||||
val senderInfo: TitledText? = null,
|
|
||||||
val sender: Recipient? = null,
|
|
||||||
val thread: Recipient? = null,
|
|
||||||
) {
|
|
||||||
val imageAttachments = attachments.filter { it.hasImage() }
|
|
||||||
val nonImageAttachment: Attachment? = attachments.firstOrNull { !it.hasImage() }
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Attachment(
|
|
||||||
val slide: Slide,
|
|
||||||
val fileDetails: List<TitledText>
|
|
||||||
) {
|
|
||||||
val fileName: String? get() = slide.fileName.orNull()
|
|
||||||
val uri get() = slide.uri
|
|
||||||
|
|
||||||
fun hasImage() = slide is ImageSlide
|
|
||||||
}
|
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class MessageDetailsViewModel @Inject constructor(
|
class MessageDetailsViewModel @Inject constructor(
|
||||||
private val attachmentDb: AttachmentDatabase,
|
private val attachmentDb: AttachmentDatabase,
|
||||||
@ -60,22 +31,18 @@ class MessageDetailsViewModel @Inject constructor(
|
|||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
fun setMessageTimestamp(timestamp: Long) {
|
fun setMessageTimestamp(timestamp: Long) {
|
||||||
mmsSmsDatabase.getMessageForTimestamp(timestamp).let(::setMessageRecord)
|
val record = mmsSmsDatabase.getMessageForTimestamp(timestamp) ?: return
|
||||||
}
|
|
||||||
|
|
||||||
fun setMessageRecord(record: MessageRecord?) {
|
|
||||||
val mmsRecord = record as? MmsMessageRecord
|
val mmsRecord = record as? MmsMessageRecord
|
||||||
|
|
||||||
val slides: List<Slide> = mmsRecord?.slideDeck?.thumbnailSlides?.toList() ?: emptyList()
|
_details.value = record.run {
|
||||||
|
val slides = mmsRecord?.slideDeck?.thumbnailSlides?.toList() ?: emptyList()
|
||||||
|
|
||||||
_details.value = record?.run {
|
|
||||||
MessageDetailsState(
|
MessageDetailsState(
|
||||||
attachments = slides.map { Attachment(it, it.details) },
|
attachments = slides.map { Attachment(it, it.details) },
|
||||||
record = record,
|
record = record,
|
||||||
mmsRecord = mmsRecord,
|
sent = dateSent.let(::Date).toString().let { TitledText(R.string.message_details_header__sent, it) },
|
||||||
sent = dateSent.let(::Date).toString().let { TitledText("Sent:", it) },
|
received = dateReceived.let(::Date).toString().let { TitledText(R.string.message_details_header__received, it) },
|
||||||
received = dateReceived.let(::Date).toString().let { TitledText("Received:", it) },
|
error = lokiMessageDatabase.getErrorMessage(id)?.let { TitledText(R.string.message_details_header__error, it) },
|
||||||
error = lokiMessageDatabase.getErrorMessage(id)?.let { TitledText("Error:", it) },
|
|
||||||
senderInfo = individualRecipient.run { name?.let { TitledText(it, address.serialize()) } },
|
senderInfo = individualRecipient.run { name?.let { TitledText(it, address.serialize()) } },
|
||||||
sender = individualRecipient,
|
sender = individualRecipient,
|
||||||
thread = threadDb.getRecipientForThreadId(threadId)!!,
|
thread = threadDb.getRecipientForThreadId(threadId)!!,
|
||||||
@ -88,13 +55,14 @@ class MessageDetailsViewModel @Inject constructor(
|
|||||||
|
|
||||||
private val Slide.details: List<TitledText>
|
private val Slide.details: List<TitledText>
|
||||||
get() = listOfNotNull(
|
get() = listOfNotNull(
|
||||||
fileName.orNull()?.let { TitledText("File Id:", it) },
|
fileName.orNull()?.let { TitledText(R.string.message_details_header__file_id, it) },
|
||||||
TitledText("File Type:", asAttachment().contentType),
|
TitledText(R.string.message_details_header__file_type, asAttachment().contentType),
|
||||||
TitledText("File Size:", Util.getPrettyFileSize(fileSize)),
|
TitledText(R.string.message_details_header__file_size, Util.getPrettyFileSize(fileSize)),
|
||||||
takeIf { it.hasImage() }
|
takeIf { it is ImageSlide }
|
||||||
.run { asAttachment().run { "${width}x$height" } }
|
?.let(Slide::asAttachment)
|
||||||
.let { TitledText("Resolution:", it) },
|
?.run { "${width}x$height" }
|
||||||
attachmentDb.duration(this)?.let { TitledText("Duration:", it) },
|
?.let { TitledText(R.string.message_details_header__resolution, it) },
|
||||||
|
attachmentDb.duration(this)?.let { TitledText(R.string.message_details_header__duration, it) },
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun AttachmentDatabase.duration(slide: Slide): String? =
|
private fun AttachmentDatabase.duration(slide: Slide): String? =
|
||||||
@ -111,3 +79,29 @@ class MessageDetailsViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class MessageDetailsState(
|
||||||
|
val attachments: List<Attachment> = emptyList(),
|
||||||
|
val imageAttachments: List<Attachment> = attachments.filter { it.hasImage() },
|
||||||
|
val nonImageAttachmentFileDetails: List<TitledText>? = attachments.firstOrNull { !it.hasImage() }?.fileDetails,
|
||||||
|
val record: MessageRecord? = null,
|
||||||
|
val mmsRecord: MmsMessageRecord? = record as? MmsMessageRecord,
|
||||||
|
val sent: TitledText? = null,
|
||||||
|
val received: TitledText? = null,
|
||||||
|
val error: TitledText? = null,
|
||||||
|
val senderInfo: TitledText? = null,
|
||||||
|
val sender: Recipient? = null,
|
||||||
|
val thread: Recipient? = null,
|
||||||
|
) {
|
||||||
|
val fromTitle = GetString(R.string.message_details_header__from)
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Attachment(
|
||||||
|
val slide: Slide,
|
||||||
|
val fileDetails: List<TitledText>
|
||||||
|
) {
|
||||||
|
val fileName: String? get() = slide.fileName.orNull()
|
||||||
|
val uri get() = slide.uri
|
||||||
|
|
||||||
|
fun hasImage() = slide is ImageSlide
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.thoughtcrime.securesms.ui
|
package org.thoughtcrime.securesms.ui
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.view.ContextThemeWrapper
|
import androidx.appcompat.view.ContextThemeWrapper
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.gestures.FlingBehavior
|
import androidx.compose.foundation.gestures.FlingBehavior
|
||||||
@ -46,6 +47,7 @@ import androidx.compose.ui.graphics.RectangleShape
|
|||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
@ -61,6 +63,7 @@ fun ItemButton(
|
|||||||
text: String,
|
text: String,
|
||||||
@DrawableRes icon: Int,
|
@DrawableRes icon: Int,
|
||||||
colors: ButtonColors = transparentButtonColors(),
|
colors: ButtonColors = transparentButtonColors(),
|
||||||
|
contentDescription: String = text,
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
TextButton(
|
TextButton(
|
||||||
@ -76,7 +79,7 @@ fun ItemButton(
|
|||||||
.fillMaxHeight()) {
|
.fillMaxHeight()) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(id = icon),
|
painter = painterResource(id = icon),
|
||||||
contentDescription = "",
|
contentDescription = contentDescription,
|
||||||
modifier = Modifier.align(Alignment.Center)
|
modifier = Modifier.align(Alignment.Center)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
34
app/src/main/java/org/thoughtcrime/securesms/ui/Data.kt
Normal file
34
app/src/main/java/org/thoughtcrime/securesms/ui/Data.kt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package org.thoughtcrime.securesms.ui
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compatibility class to allow ViewModels to use strings and string resources interchangeably.
|
||||||
|
*/
|
||||||
|
sealed class GetString {
|
||||||
|
@Composable
|
||||||
|
abstract fun string(): String
|
||||||
|
data class FromString(val string: String): GetString() {
|
||||||
|
@Composable
|
||||||
|
override fun string(): String = string
|
||||||
|
}
|
||||||
|
data class FromResId(@StringRes val resId: Int): GetString() {
|
||||||
|
@Composable
|
||||||
|
override fun string(): String = stringResource(resId)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun GetString(@StringRes resId: Int) = GetString.FromResId(resId)
|
||||||
|
fun GetString(string: String) = GetString.FromString(string)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents some text with an associated title.
|
||||||
|
*/
|
||||||
|
data class TitledText(val title: GetString, val text: String) {
|
||||||
|
constructor(title: String, text: String): this(GetString(title), text)
|
||||||
|
constructor(@StringRes title: Int, text: String): this(GetString(title), text)
|
||||||
|
}
|
@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.ui
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.StyleRes
|
|
||||||
import androidx.appcompat.view.ContextThemeWrapper
|
import androidx.appcompat.view.ContextThemeWrapper
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@ -13,13 +12,10 @@ import androidx.compose.runtime.staticCompositionLocalOf
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import com.google.accompanist.themeadapter.appcompat.AppCompatTheme
|
import com.google.accompanist.themeadapter.appcompat.AppCompatTheme
|
||||||
import com.google.android.material.color.MaterialColors
|
import com.google.android.material.color.MaterialColors
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.thoughtcrime.securesms.conversation.v2.PreviewMessageDetails
|
|
||||||
|
|
||||||
val LocalExtraColors = staticCompositionLocalOf<ExtraColors> { error("No Custom Attribute value provided") }
|
val LocalExtraColors = staticCompositionLocalOf<ExtraColors> { error("No Custom Attribute value provided") }
|
||||||
|
|
||||||
|
@ -520,6 +520,11 @@
|
|||||||
<string name="message_details_header__to">To:</string>
|
<string name="message_details_header__to">To:</string>
|
||||||
<string name="message_details_header__from">From:</string>
|
<string name="message_details_header__from">From:</string>
|
||||||
<string name="message_details_header__with">With:</string>
|
<string name="message_details_header__with">With:</string>
|
||||||
|
<string name="message_details_header__file_id">File Id:</string>
|
||||||
|
<string name="message_details_header__file_type">File Type:</string>
|
||||||
|
<string name="message_details_header__file_size">File Size:</string>
|
||||||
|
<string name="message_details_header__resolution">Resolution:</string>
|
||||||
|
<string name="message_details_header__duration">Duration:</string>
|
||||||
|
|
||||||
<!-- AndroidManifest.xml -->
|
<!-- AndroidManifest.xml -->
|
||||||
<string name="AndroidManifest__create_passphrase">Create passphrase</string>
|
<string name="AndroidManifest__create_passphrase">Create passphrase</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user