From 4d645cfe949579e65843aa460b5e4ccf6624b276 Mon Sep 17 00:00:00 2001 From: sh Date: Tue, 13 Oct 2026 10:41:26 +0000 Subject: [PATCH] desktop: drop bubble chrome in flat layout --- .../common/views/chat/item/ChatItemView.kt | 23 +++++++++++-------- .../common/views/chat/item/FramedItemView.kt | 6 ++--- .../common/views/usersettings/Appearance.kt | 17 ++++++++------ 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt index eb9a12fca3..a0bf981dbf 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.* +import chat.simplex.common.LocalFlatLayout import chat.simplex.common.model.* import chat.simplex.common.model.ChatModel.controller import chat.simplex.common.model.ChatModel.currentUser @@ -117,7 +118,8 @@ fun ChatItemView( val cInfo = chat.chatInfo val uriHandler = LocalUriHandler.current val sent = cItem.chatDir.sent - val alignment = if (sent) Alignment.CenterEnd else Alignment.CenterStart + val flat = LocalFlatLayout.current + val alignment = if (sent && !flat) Alignment.CenterEnd else Alignment.CenterStart val showMenu = remember { mutableStateOf(false) } val fullDeleteAllowed = remember(cInfo) { cInfo.featureEnabled(ChatFeature.FullDelete) } val onLinkLongClick = { _: String -> showMenu.value = true } @@ -301,14 +303,14 @@ fun ChatItemView( } } - Column(horizontalAlignment = if (cItem.chatDir.sent) Alignment.End else Alignment.Start) { + Column(horizontalAlignment = if (sent && !flat) Alignment.End else Alignment.Start) { val canReply = (cItem.content is CIContent.SndMsgContent || cItem.content is CIContent.RcvMsgContent) && cInfo !is ChatInfo.Local && !cItem.isReport && !cItem.meta.isLive && cItem.meta.itemDeleted == null Box { Row(verticalAlignment = Alignment.CenterVertically) { val bubbleInteractionSource = remember { MutableInteractionSource() } val bubbleHovered = bubbleInteractionSource.collectIsHoveredAsState() - if (cItem.chatDir.sent) { + if (sent && !flat) { GoToItemButton(true, bubbleHovered) } Column(Modifier.weight(1f, fill = false)) { @@ -331,7 +333,7 @@ fun ChatItemView( hoveredItemId.value = if (hoveredItemId.value == cItem.id) null else cItem.id } onClick() - }, interactionSource = bubbleInteractionSource, indication = LocalIndication.current) + }, interactionSource = bubbleInteractionSource, indication = if (flat) null else LocalIndication.current) .onRightClick { showMenu.value = true }, ) { @Composable @@ -543,7 +545,7 @@ fun ChatItemView( if (mc is MsgContent.MCText && isShortEmoji(cItem.content.text)) { EmojiItemView(cItem, cInfo.timedMessagesTTL, showViaProxy = showViaProxy, showTimestamp = showTimestamp) } else if (mc is MsgContent.MCVoice && cItem.content.text.isEmpty()) { - CIVoiceView(mc.duration, cItem.file, cItem.meta.itemEdited, cItem.chatDir.sent, hasText = false, cItem, cInfo.timedMessagesTTL, showViaProxy = showViaProxy, showTimestamp = showTimestamp, longClick = { onLinkLongClick("") }, receiveFile = receiveFile) + CIVoiceView(mc.duration, cItem.file, cItem.meta.itemEdited, sent && !flat, hasText = false, cItem, cInfo.timedMessagesTTL, showViaProxy = showViaProxy, showTimestamp = showTimestamp, longClick = { onLinkLongClick("") }, receiveFile = receiveFile) } else { framedItemView() } @@ -771,7 +773,7 @@ fun ChatItemView( } } } - if (!cItem.chatDir.sent) { + if (!sent || flat) { GoToItemButton(false, bubbleHovered) } } @@ -1215,10 +1217,12 @@ fun ItemAction(text: String, color: Color = Color.Unspecified, onClick: () -> Un } } +@Composable +fun chatItemTailEnabled(): Boolean = remember { appPreferences.chatItemTail.state }.value && !LocalFlatLayout.current + @Composable fun Modifier.chatItemOffset(cItem: ChatItem, tailVisible: Boolean, inverted: Boolean = false, revealed: Boolean): Modifier { - val chatItemTail = remember { appPreferences.chatItemTail.state } - val style = shapeStyle(cItem, chatItemTail.value, tailVisible, revealed) + val style = shapeStyle(cItem, chatItemTailEnabled(), tailVisible, revealed) val offset = if (style is ShapeStyle.Bubble) { if (style.tailVisible) { @@ -1234,8 +1238,7 @@ fun Modifier.chatItemOffset(cItem: ChatItem, tailVisible: Boolean, inverted: Boo @Composable fun Modifier.clipChatItem(chatItem: ChatItem? = null, tailVisible: Boolean = false, revealed: Boolean = false): Modifier { val chatItemRoundness = remember { appPreferences.chatItemRoundness.state } - val chatItemTail = remember { appPreferences.chatItemTail.state } - val style = shapeStyle(chatItem, chatItemTail.value, tailVisible, revealed) + val style = shapeStyle(chatItem, chatItemTailEnabled(), tailVisible, revealed) val cornerRoundness = chatItemRoundness.value.coerceIn(0f, 1f) return when (style) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/FramedItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/FramedItemView.kt index fd422b649a..b952128924 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/FramedItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/FramedItemView.kt @@ -18,6 +18,7 @@ import androidx.compose.ui.text.* import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.* +import chat.simplex.common.LocalFlatLayout import chat.simplex.common.model.* import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* @@ -235,15 +236,14 @@ fun FramedItemView( .clipChatItem(ci, tailVisible, revealed = true) .background( when { - transparentBackground -> Color.Transparent + transparentBackground || LocalFlatLayout.current -> Color.Transparent sent -> sentColor else -> receivedColor } )) { var metaColor = MaterialTheme.colors.secondary Box(contentAlignment = Alignment.BottomEnd) { - val chatItemTail = remember { appPreferences.chatItemTail.state } - val style = shapeStyle(ci, chatItemTail.value, tailVisible, true) + val style = shapeStyle(ci, chatItemTailEnabled(), tailVisible, true) val tailRendered = style is ShapeStyle.Bubble && style.tailVisible Column( Modifier diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt index a661568a0d..d2841d6a53 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.* import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource +import chat.simplex.common.LocalFlatLayout import chat.simplex.common.model.* import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.ui.theme.* @@ -294,14 +295,16 @@ object AppearanceScope { if (withMessages) { val chatItemTail = remember { appPreferences.chatItemTail.state } - Column(verticalArrangement = Arrangement.spacedBy(4.dp), modifier = if (chatItemTail.value) Modifier else Modifier.padding(horizontal = msgTailWidthDp)) { - val alice = remember { ChatItem.getSampleData(1, CIDirection.DirectRcv(), Clock.System.now(), generalGetString(MR.strings.wallpaper_preview_hello_bob)) } - PreviewChatItemView(alice) - PreviewChatItemView( - ChatItem.getSampleData(2, CIDirection.DirectSnd(), Clock.System.now(), stringResource(MR.strings.wallpaper_preview_hello_alice), - quotedItem = CIQuote(alice.chatDir, alice.id, sentAt = alice.meta.itemTs, formattedText = alice.formattedText, content = MsgContent.MCText(alice.content.text)) + CompositionLocalProvider(LocalFlatLayout provides false) { + Column(verticalArrangement = Arrangement.spacedBy(4.dp), modifier = if (chatItemTail.value) Modifier else Modifier.padding(horizontal = msgTailWidthDp)) { + val alice = remember { ChatItem.getSampleData(1, CIDirection.DirectRcv(), Clock.System.now(), generalGetString(MR.strings.wallpaper_preview_hello_bob)) } + PreviewChatItemView(alice) + PreviewChatItemView( + ChatItem.getSampleData(2, CIDirection.DirectSnd(), Clock.System.now(), stringResource(MR.strings.wallpaper_preview_hello_alice), + quotedItem = CIQuote(alice.chatDir, alice.id, sentAt = alice.meta.itemTs, formattedText = alice.formattedText, content = MsgContent.MCText(alice.content.text)) + ) ) - ) + } } } else { Box(Modifier.fillMaxSize())