Refactor: Encapsulate MessageBubble colors
This commit refactors the `MessageBubble` composable by extracting the color logic into a private `messageBubbleColors` function. This function returns an immutable `MessageBubbleColors` data class, which holds the container, content, and reply container colors. This change cleans up the main composable, improves readability, and centralizes color definitions for both incoming and outgoing messages. Additionally, the background color logic for attachments has been simplified to make it transparent for media types like stickers and videos.
This commit is contained in:
+41
-33
@@ -16,6 +16,7 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.material3.surfaceColorAtElevation
|
import androidx.compose.material3.surfaceColorAtElevation
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
@@ -68,22 +69,7 @@ fun MessageBubble(
|
|||||||
val currentOnLongClick by rememberUpdatedState(onLongClick)
|
val currentOnLongClick by rememberUpdatedState(onLongClick)
|
||||||
|
|
||||||
val theme = LocalThemeConfig.current
|
val theme = LocalThemeConfig.current
|
||||||
val backgroundColor = if (!isOut) {
|
val colors = messageBubbleColors(isOut = isOut)
|
||||||
MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp)
|
|
||||||
} else {
|
|
||||||
MaterialTheme.colorScheme.primaryContainer
|
|
||||||
}
|
|
||||||
val replyBackgroundColor = if (!isOut) {
|
|
||||||
MaterialTheme.colorScheme.primaryContainer
|
|
||||||
} else {
|
|
||||||
MaterialTheme.colorScheme.inversePrimary
|
|
||||||
}
|
|
||||||
|
|
||||||
val contentColor = if (!isOut) {
|
|
||||||
MaterialTheme.colorScheme.onSurface
|
|
||||||
} else {
|
|
||||||
MaterialTheme.colorScheme.onPrimaryContainer
|
|
||||||
}
|
|
||||||
|
|
||||||
val shouldShowBubble = !text.isNullOrEmpty()
|
val shouldShowBubble = !text.isNullOrEmpty()
|
||||||
|
|
||||||
@@ -117,7 +103,7 @@ fun MessageBubble(
|
|||||||
label = "dateContainerWidth"
|
label = "dateContainerWidth"
|
||||||
)
|
)
|
||||||
|
|
||||||
CompositionLocalProvider(LocalContentColor provides contentColor) {
|
CompositionLocalProvider(LocalContentColor provides colors.content) {
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.wrapContentWidth()
|
.wrapContentWidth()
|
||||||
@@ -140,8 +126,8 @@ fun MessageBubble(
|
|||||||
onClick = onReplyClick,
|
onClick = onReplyClick,
|
||||||
title = replyTitle,
|
title = replyTitle,
|
||||||
summary = replySummary,
|
summary = replySummary,
|
||||||
backgroundColor = backgroundColor,
|
backgroundColor = colors.container,
|
||||||
innerBackgroundColor = replyBackgroundColor
|
innerBackgroundColor = colors.replyContainer
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +149,7 @@ fun MessageBubble(
|
|||||||
bottomEnd = if (attachments != null) 0.dp else 24.dp
|
bottomEnd = if (attachments != null) 0.dp else 24.dp
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.background(backgroundColor)
|
.background(colors.container)
|
||||||
.padding(
|
.padding(
|
||||||
start = 8.dp,
|
start = 8.dp,
|
||||||
end = 8.dp,
|
end = 8.dp,
|
||||||
@@ -204,6 +190,15 @@ fun MessageBubble(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (attachments != null) {
|
if (attachments != null) {
|
||||||
|
val firstAttachment = attachments.firstOrNull()
|
||||||
|
val isMediaAttachment = firstAttachment is VkStickerDomain ||
|
||||||
|
firstAttachment is VkVideoMessageDomain
|
||||||
|
val attachmentBackgroundColor = if (isMediaAttachment) {
|
||||||
|
Color.Transparent
|
||||||
|
} else {
|
||||||
|
colors.container
|
||||||
|
}
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.onGloballyPositioned {
|
.onGloballyPositioned {
|
||||||
@@ -218,18 +213,7 @@ fun MessageBubble(
|
|||||||
topEnd = 0.dp
|
topEnd = 0.dp
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.background(
|
.background(attachmentBackgroundColor)
|
||||||
backgroundColor.copy(
|
|
||||||
alpha = if ((attachments.firstOrNull()?.javaClass
|
|
||||||
?: Nothing::class.java)
|
|
||||||
in listOf(
|
|
||||||
VkStickerDomain::class.java,
|
|
||||||
VkVideoMessageDomain::class.java
|
|
||||||
)
|
|
||||||
) 0f
|
|
||||||
else 1f
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
Attachments(
|
Attachments(
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
@@ -241,7 +225,7 @@ fun MessageBubble(
|
|||||||
val dateStatusBackground = if (theme.darkMode) Color.Black.copy(alpha = 0.5f)
|
val dateStatusBackground = if (theme.darkMode) Color.Black.copy(alpha = 0.5f)
|
||||||
else Color.White.copy(alpha = 0.5f)
|
else Color.White.copy(alpha = 0.5f)
|
||||||
|
|
||||||
CompositionLocalProvider(LocalContentColor provides contentColor) {
|
CompositionLocalProvider(LocalContentColor provides colors.content) {
|
||||||
DateStatus(
|
DateStatus(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.BottomEnd)
|
.align(Alignment.BottomEnd)
|
||||||
@@ -266,6 +250,30 @@ fun MessageBubble(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
private data class MessageBubbleColors(
|
||||||
|
val container: Color,
|
||||||
|
val content: Color,
|
||||||
|
val replyContainer: Color,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun messageBubbleColors(isOut: Boolean): MessageBubbleColors {
|
||||||
|
return if (isOut) {
|
||||||
|
MessageBubbleColors(
|
||||||
|
container = MaterialTheme.colorScheme.primaryContainer,
|
||||||
|
content = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||||
|
replyContainer = MaterialTheme.colorScheme.inversePrimary
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
MessageBubbleColors(
|
||||||
|
container = MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp),
|
||||||
|
content = MaterialTheme.colorScheme.onSurface,
|
||||||
|
replyContainer = MaterialTheme.colorScheme.primaryContainer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
private fun Bubble() {
|
private fun Bubble() {
|
||||||
|
|||||||
Reference in New Issue
Block a user