Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c666bd46f3 | |||
| 421ca27758 | |||
| 8231062ca5 | |||
| 723555f634 | |||
| 3e05744a18 | |||
| 821ee46cef | |||
| dcddddea9b |
@@ -3,6 +3,9 @@ name: Android CI Build
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
|
||||
RELEASE_SIGN_KEY_ALIAS: ${{ secrets.RELEASE_SIGN_KEY_ALIAS }}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
name: Android CI Release
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -48,7 +48,7 @@ Unofficial messenger for russian social network VKontakte
|
||||
- [x] Send messages
|
||||
- [x] Pinned message
|
||||
- [x] Pin & unpin messages
|
||||
- [ ] Reply to message
|
||||
- [x] Reply to message
|
||||
- [x] Delete message
|
||||
- [x] Select multiple messages
|
||||
- [x] Delete
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.meloda.fast.common.util
|
||||
|
||||
import java.net.URLEncoder
|
||||
|
||||
fun String.urlEncode(encoding: String = "utf-8"): String {
|
||||
return URLEncoder.encode(this, encoding)
|
||||
}
|
||||
@@ -32,7 +32,7 @@ interface MessagesRepository {
|
||||
peerId: Long,
|
||||
randomId: Long,
|
||||
message: String?,
|
||||
replyTo: Long?,
|
||||
forward: String?,
|
||||
attachments: List<VkAttachment>?,
|
||||
formatData: VkMessage.FormatData?
|
||||
): ApiResult<MessagesSendResponse, RestApiErrorDomain>
|
||||
|
||||
+2
-2
@@ -195,7 +195,7 @@ class MessagesRepositoryImpl(
|
||||
peerId: Long,
|
||||
randomId: Long,
|
||||
message: String?,
|
||||
replyTo: Long?,
|
||||
forward: String?,
|
||||
attachments: List<VkAttachment>?,
|
||||
formatData: VkMessage.FormatData?
|
||||
): ApiResult<MessagesSendResponse, RestApiErrorDomain> = withContext(Dispatchers.IO) {
|
||||
@@ -203,7 +203,7 @@ class MessagesRepositoryImpl(
|
||||
peerId = peerId,
|
||||
randomId = randomId,
|
||||
message = message,
|
||||
replyTo = replyTo,
|
||||
forward = forward,
|
||||
attachments = attachments,
|
||||
formatData = formatData
|
||||
)
|
||||
|
||||
@@ -32,7 +32,7 @@ interface MessagesUseCase : BaseUseCase {
|
||||
peerId: Long,
|
||||
randomId: Long,
|
||||
message: String?,
|
||||
replyTo: Long?,
|
||||
forward: String?,
|
||||
attachments: List<VkAttachment>?,
|
||||
formatData: VkMessage.FormatData?
|
||||
): Flow<State<MessagesSendResponse>>
|
||||
|
||||
@@ -56,7 +56,7 @@ class MessagesUseCaseImpl(
|
||||
peerId: Long,
|
||||
randomId: Long,
|
||||
message: String?,
|
||||
replyTo: Long?,
|
||||
forward: String?,
|
||||
attachments: List<VkAttachment>?,
|
||||
formatData: VkMessage.FormatData?
|
||||
): Flow<State<MessagesSendResponse>> = flowNewState {
|
||||
@@ -64,7 +64,7 @@ class MessagesUseCaseImpl(
|
||||
peerId = peerId,
|
||||
randomId = randomId,
|
||||
message = message,
|
||||
replyTo = replyTo,
|
||||
forward = forward,
|
||||
attachments = attachments,
|
||||
formatData = formatData
|
||||
).mapToState()
|
||||
|
||||
@@ -34,7 +34,7 @@ data class MessagesSendRequest(
|
||||
val message: String?,
|
||||
val lat: Int? = null,
|
||||
val lon: Int? = null,
|
||||
val replyTo: Long? = null,
|
||||
val forward: String? = null,
|
||||
val stickerId: Long? = null,
|
||||
val disableMentions: Boolean? = null,
|
||||
val doNotParseLinks: Boolean? = null,
|
||||
@@ -51,7 +51,7 @@ data class MessagesSendRequest(
|
||||
message?.let { this["message"] = it }
|
||||
lat?.let { this["lat"] = it.toString() }
|
||||
lon?.let { this["lon"] = it.toString() }
|
||||
replyTo?.let { this["reply_to"] = it.toString() }
|
||||
forward?.let { this["forward"] = it }
|
||||
stickerId?.let { this["sticker_id"] = it.toString() }
|
||||
disableMentions?.let { this["disable_mentions"] = it.asInt().toString() }
|
||||
doNotParseLinks?.let { this["dont_parse_links"] = it.asInt().toString() }
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package dev.meloda.fast.ui.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.ripple
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun RippledClickContainer(
|
||||
modifier: Modifier = Modifier,
|
||||
shape: Shape = RoundedCornerShape(4.dp),
|
||||
onClick: () -> Unit,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.clip(shape)
|
||||
.clickable(
|
||||
interactionSource = null,
|
||||
indication = ripple(),
|
||||
onClick = onClick
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:autoMirrored="true"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M760,760L760,600Q760,550 725,515Q690,480 640,480L273,480L417,624L360,680L120,440L360,200L417,256L273,400L640,400Q723,400 781.5,458.5Q840,517 840,600L840,760L760,760Z" />
|
||||
</vector>
|
||||
+3
-1490
File diff suppressed because it is too large
Load Diff
+1563
File diff suppressed because it is too large
Load Diff
+6
-2
@@ -24,7 +24,9 @@ data class MessagesHistoryScreenState(
|
||||
val conversation: VkConversation,
|
||||
val pinnedMessage: VkMessage?,
|
||||
val pinnedTitle: String?,
|
||||
val pinnedSummary: AnnotatedString?
|
||||
val pinnedSummary: AnnotatedString?,
|
||||
val replyTitle: String?,
|
||||
val replyText: String?
|
||||
) {
|
||||
|
||||
companion object {
|
||||
@@ -43,7 +45,9 @@ data class MessagesHistoryScreenState(
|
||||
conversation = VkConversation.EMPTY,
|
||||
pinnedMessage = null,
|
||||
pinnedTitle = null,
|
||||
pinnedSummary = null
|
||||
pinnedSummary = null,
|
||||
replyTitle = null,
|
||||
replyText = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -117,7 +117,7 @@ fun MessageOptionsDialog(
|
||||
options += if (message.isPinned) MessageOption.Unpin else MessageOption.Pin
|
||||
}
|
||||
|
||||
if (!message.isRead(screenState.conversation)) {
|
||||
if (!message.isOut && !message.isRead(screenState.conversation)) {
|
||||
options += MessageOption.Read
|
||||
}
|
||||
|
||||
@@ -180,7 +180,13 @@ fun MessageOptionsDialog(
|
||||
onClick = {
|
||||
onDismissed()
|
||||
val pickedOption = options[index]
|
||||
onItemPicked(bundleOf("option" to pickedOption))
|
||||
onItemPicked(
|
||||
bundleOf(
|
||||
"option" to pickedOption,
|
||||
"messageId" to message.id,
|
||||
"cmId" to message.cmId
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
+44
-7
@@ -1,7 +1,9 @@
|
||||
package dev.meloda.fast.messageshistory.presentation
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.scaleIn
|
||||
@@ -32,10 +34,14 @@ import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@@ -54,9 +60,9 @@ import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
|
||||
import dev.chrisbanes.haze.materials.HazeMaterials
|
||||
import dev.meloda.fast.datastore.AppSettings
|
||||
import dev.meloda.fast.messageshistory.model.ActionMode
|
||||
import dev.meloda.fast.ui.R
|
||||
import dev.meloda.fast.ui.components.IconButton
|
||||
import dev.meloda.fast.ui.theme.LocalThemeConfig
|
||||
import dev.meloda.fast.ui.R
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class, ExperimentalHazeMaterialsApi::class)
|
||||
@Composable
|
||||
@@ -68,6 +74,9 @@ fun MessagesHistoryInputBar(
|
||||
showEmojiButton: Boolean,
|
||||
showAttachmentButton: Boolean,
|
||||
actionMode: ActionMode,
|
||||
replyTitle: String?,
|
||||
replyText: String?,
|
||||
inputFieldFocusRequester: Boolean,
|
||||
onMessageInputChanged: (TextFieldValue) -> Unit = {},
|
||||
onBoldRequested: () -> Unit = {},
|
||||
onItalicRequested: () -> Unit = {},
|
||||
@@ -77,16 +86,28 @@ fun MessagesHistoryInputBar(
|
||||
onSetMessageBarHeight: (Dp) -> Unit = {},
|
||||
onEmojiButtonLongClicked: () -> Unit = {},
|
||||
onAttachmentButtonClicked: () -> Unit = {},
|
||||
onActionButtonClicked: () -> Unit = {}
|
||||
onActionButtonClicked: () -> Unit = {},
|
||||
onReplyCloseClicked: () -> Unit = {}
|
||||
) {
|
||||
val view = LocalView.current
|
||||
val context = LocalContext.current
|
||||
val density = LocalDensity.current
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
|
||||
LaunchedEffect(inputFieldFocusRequester) {
|
||||
if (inputFieldFocusRequester) {
|
||||
focusRequester.requestFocus()
|
||||
}
|
||||
}
|
||||
|
||||
val theme = LocalThemeConfig.current
|
||||
|
||||
val inputBarTopCornerRadius by animateDpAsState(
|
||||
targetValue = if (replyTitle == null) 24.dp else 0.dp,
|
||||
label = "inputBarTopCornerRadius"
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
@@ -95,6 +116,14 @@ fun MessagesHistoryInputBar(
|
||||
.navigationBarsPadding()
|
||||
.imePadding()
|
||||
) {
|
||||
AnimatedVisibility(replyTitle != null) {
|
||||
ReplyContainer(
|
||||
title = replyTitle.orEmpty(),
|
||||
text = replyText.orEmpty(),
|
||||
onCloseClicked = onReplyCloseClicked,
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -102,10 +131,17 @@ fun MessagesHistoryInputBar(
|
||||
.imeNestedScroll(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Spacer(modifier = Modifier.width(10.dp))
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(36.dp))
|
||||
.clip(
|
||||
RoundedCornerShape(
|
||||
topStart = inputBarTopCornerRadius,
|
||||
topEnd = inputBarTopCornerRadius,
|
||||
bottomStart = 24.dp,
|
||||
bottomEnd = 24.dp
|
||||
)
|
||||
)
|
||||
.then(
|
||||
if (theme.enableBlur) {
|
||||
Modifier
|
||||
@@ -166,6 +202,7 @@ fun MessagesHistoryInputBar(
|
||||
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
.focusRequester(focusRequester)
|
||||
.weight(1f)
|
||||
.appendTextContextMenuComponents {
|
||||
separator()
|
||||
@@ -287,7 +324,7 @@ fun MessagesHistoryInputBar(
|
||||
Spacer(modifier = Modifier.width(6.dp))
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.width(10.dp))
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -4,7 +4,6 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import dev.meloda.fast.common.model.UiImage
|
||||
import dev.meloda.fast.datastore.AppSettings
|
||||
import dev.meloda.fast.messageshistory.MessagesHistoryViewModel
|
||||
import dev.meloda.fast.messageshistory.MessagesHistoryViewModelImpl
|
||||
@@ -30,6 +29,7 @@ fun MessagesHistoryRoute(
|
||||
val baseError by viewModel.baseError.collectAsStateWithLifecycle()
|
||||
val canPaginate by viewModel.canPaginate.collectAsStateWithLifecycle()
|
||||
val scrollIndex by viewModel.isNeedToScrollToIndex.collectAsStateWithLifecycle()
|
||||
val inputFieldFocusRequester by viewModel.inputFieldFocusRequester.collectAsStateWithLifecycle()
|
||||
|
||||
LaunchedEffect(navigationEvent) {
|
||||
val needToConsume = when (val navigation = navigationEvent) {
|
||||
@@ -56,6 +56,7 @@ fun MessagesHistoryRoute(
|
||||
showEmojiButton = AppSettings.General.showEmojiButton,
|
||||
showAttachmentButton = AppSettings.General.showAttachmentButton,
|
||||
enableHaptic = AppSettings.General.enableHaptic,
|
||||
inputFieldFocusRequester = inputFieldFocusRequester,
|
||||
onBack = onBack,
|
||||
onClose = viewModel::onCloseButtonClicked,
|
||||
onScrolledToIndex = viewModel::onScrolledToIndex,
|
||||
@@ -77,7 +78,8 @@ fun MessagesHistoryRoute(
|
||||
onItalicRequested = viewModel::onItalicClicked,
|
||||
onUnderlineRequested = viewModel::onUnderlineClicked,
|
||||
onLinkRequested = viewModel::onLinkClicked,
|
||||
onRegularRequested = viewModel::onRegularClicked
|
||||
onRegularRequested = viewModel::onRegularClicked,
|
||||
onReplyCloseClicked = viewModel::onReplyCloseClicked
|
||||
)
|
||||
|
||||
HandleDialogs(
|
||||
|
||||
+10
-3
@@ -44,13 +44,13 @@ import dev.meloda.fast.messageshistory.model.UiItem
|
||||
import dev.meloda.fast.messageshistory.util.indexOfMessageByCmId
|
||||
import dev.meloda.fast.model.BaseError
|
||||
import dev.meloda.fast.model.api.domain.VkMessage
|
||||
import dev.meloda.fast.ui.R
|
||||
import dev.meloda.fast.ui.components.Loader
|
||||
import dev.meloda.fast.ui.components.VkErrorView
|
||||
import dev.meloda.fast.ui.theme.LocalThemeConfig
|
||||
import dev.meloda.fast.ui.util.ImmutableList
|
||||
import dev.meloda.fast.ui.util.emptyImmutableList
|
||||
import kotlinx.coroutines.launch
|
||||
import dev.meloda.fast.ui.R
|
||||
|
||||
@OptIn(
|
||||
ExperimentalMaterial3Api::class,
|
||||
@@ -70,6 +70,7 @@ fun MessagesHistoryScreen(
|
||||
showEmojiButton: Boolean = false,
|
||||
showAttachmentButton: Boolean = false,
|
||||
enableHaptic: Boolean = false,
|
||||
inputFieldFocusRequester: Boolean,
|
||||
onBack: () -> Unit = {},
|
||||
onClose: () -> Unit = {},
|
||||
onScrolledToIndex: () -> Unit = {},
|
||||
@@ -91,7 +92,8 @@ fun MessagesHistoryScreen(
|
||||
onItalicRequested: () -> Unit = {},
|
||||
onLinkRequested: () -> Unit = {},
|
||||
onUnderlineRequested: () -> Unit = {},
|
||||
onRegularRequested: () -> Unit = {}
|
||||
onRegularRequested: () -> Unit = {},
|
||||
onReplyCloseClicked: () -> Unit = {},
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val view = LocalView.current
|
||||
@@ -215,6 +217,7 @@ fun MessagesHistoryScreen(
|
||||
uiMessages = uiMessages,
|
||||
isSelectedAtLeastOne = isSelectedAtLeastOne,
|
||||
isPaginating = screenState.isPaginating,
|
||||
isReplying = screenState.replyTitle != null,
|
||||
messageBarHeight = messageBarHeight,
|
||||
onRequestScrollToCmId = { cmId ->
|
||||
val index = uiMessages.values.indexOfMessageByCmId(cmId)
|
||||
@@ -252,10 +255,14 @@ fun MessagesHistoryScreen(
|
||||
showEmojiButton = showEmojiButton,
|
||||
showAttachmentButton = showAttachmentButton,
|
||||
actionMode = screenState.actionMode,
|
||||
replyTitle = screenState.replyTitle,
|
||||
replyText = screenState.replyText,
|
||||
inputFieldFocusRequester = inputFieldFocusRequester,
|
||||
onSetMessageBarHeight = { messageBarHeight = it },
|
||||
onEmojiButtonLongClicked = onEmojiButtonLongClicked,
|
||||
onAttachmentButtonClicked = onAttachmentButtonClicked,
|
||||
onActionButtonClicked = onActionButtonClicked
|
||||
onActionButtonClicked = onActionButtonClicked,
|
||||
onReplyCloseClicked = onReplyCloseClicked
|
||||
)
|
||||
|
||||
when {
|
||||
|
||||
+5
@@ -53,6 +53,7 @@ fun MessagesList(
|
||||
uiMessages: ImmutableList<UiItem>,
|
||||
isSelectedAtLeastOne: Boolean,
|
||||
isPaginating: Boolean,
|
||||
isReplying: Boolean,
|
||||
messageBarHeight: Dp,
|
||||
onRequestScrollToCmId: (cmId: Long) -> Unit = {},
|
||||
onMessageClicked: (Long) -> Unit = {},
|
||||
@@ -132,6 +133,10 @@ fun MessagesList(
|
||||
reverseLayout = true
|
||||
) {
|
||||
item {
|
||||
AnimatedVisibility(isReplying) {
|
||||
Spacer(modifier = Modifier.height(48.dp))
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(messageBarHeight.plus(18.dp)))
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package dev.meloda.fast.messageshistory.presentation
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.meloda.fast.ui.R
|
||||
import dev.meloda.fast.ui.components.RippledClickContainer
|
||||
|
||||
@Composable
|
||||
fun ReplyContainer(
|
||||
onCloseClicked: () -> Unit = {},
|
||||
title: String,
|
||||
text: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
backgroundColor: Color = MaterialTheme.colorScheme.surfaceColorAtElevation(5.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.padding(horizontal = 8.dp)
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 48.dp)
|
||||
.clip(
|
||||
RoundedCornerShape(
|
||||
topStart = 24.dp,
|
||||
topEnd = 24.dp,
|
||||
bottomStart = 0.dp,
|
||||
bottomEnd = 0.dp
|
||||
)
|
||||
)
|
||||
.background(backgroundColor)
|
||||
.padding(horizontal = 8.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.round_reply_24px),
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp)
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
|
||||
AnimatedVisibility(text != null) {
|
||||
Text(
|
||||
text = text.orEmpty(),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
RippledClickContainer(
|
||||
modifier = Modifier.size(36.dp),
|
||||
shape = CircleShape,
|
||||
onClick = onCloseClicked
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.round_close_24px),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun ReplyContainerPreview() {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color.White),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
ReplyContainer(
|
||||
onCloseClicked = {},
|
||||
title = "В ответ Ишак",
|
||||
text = "Приветствую тебя, Ишак!",
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user