From 29941729d2078b8a1facf852278e816c61f65e17 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Fri, 12 Apr 2024 12:56:09 +0400 Subject: [PATCH] ui: forwarded item header (#4017) --- apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift | 6 ++++-- apps/ios/Shared/Views/Chat/ChatItemView.swift | 2 +- apps/ios/Shared/Views/Chat/ChatView.swift | 2 +- .../kotlin/chat/simplex/common/model/ChatModel.kt | 9 +++++++-- .../kotlin/chat/simplex/common/views/chat/ChatView.kt | 2 +- .../chat/simplex/common/views/chat/item/ChatItemView.kt | 2 +- .../simplex/common/views/chat/item/FramedItemView.kt | 9 +++++++-- .../common/src/commonMain/resources/MR/base/strings.xml | 1 + .../src/commonMain/resources/MR/images/ic_forward.svg | 1 + 9 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_forward.svg diff --git a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift index 3475e7a8b6..3e292c131b 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift @@ -65,6 +65,8 @@ struct FramedItemView: View { } } } + } else if chatItem.meta.itemForwarded != nil { + framedItemHeader(icon: "arrowshape.turn.up.forward", caption: Text("forwarded").italic()) } ChatItemContentView(chat: chat, chatItem: chatItem, revealed: $revealed, msgContentView: framedMsgContentView) @@ -353,9 +355,9 @@ private struct MetaColorPreferenceKey: PreferenceKey { func onlyImageOrVideo(_ ci: ChatItem) -> Bool { if case let .image(text, _) = ci.content.msgContent { - return ci.meta.itemDeleted == nil && !ci.meta.isLive && ci.quotedItem == nil && text == "" + return ci.meta.itemDeleted == nil && !ci.meta.isLive && ci.quotedItem == nil && ci.meta.itemForwarded == nil && text == "" } else if case let .video(text, _, _) = ci.content.msgContent { - return ci.meta.itemDeleted == nil && !ci.meta.isLive && ci.quotedItem == nil && text == "" + return ci.meta.itemDeleted == nil && !ci.meta.isLive && ci.quotedItem == nil && ci.meta.itemForwarded == nil && text == "" } return false } diff --git a/apps/ios/Shared/Views/Chat/ChatItemView.swift b/apps/ios/Shared/Views/Chat/ChatItemView.swift index da9dc523e1..8fe2b71d09 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemView.swift @@ -46,7 +46,7 @@ struct ChatItemView: View { let ci = chatItem if chatItem.meta.itemDeleted != nil && (!revealed || chatItem.isDeletedContent) { MarkedDeletedItemView(chat: chat, chatItem: chatItem, revealed: $revealed) - } else if ci.quotedItem == nil && ci.meta.itemDeleted == nil && !ci.meta.isLive { + } else if ci.quotedItem == nil && ci.meta.itemForwarded == nil && ci.meta.itemDeleted == nil && !ci.meta.isLive { if let mc = ci.content.msgContent, mc.isText && isShortEmoji(ci.content.text) { EmojiItemView(chat: chat, chatItem: ci) } else if ci.content.text.isEmpty, case let .voice(_, duration) = ci.content.msgContent { diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index cd2aa55bc3..21b9fa00b3 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -296,7 +296,7 @@ struct ChatView: View { } private func voiceWithoutFrame(_ ci: ChatItem) -> Bool { - ci.content.msgContent?.isVoice == true && ci.content.text.count == 0 && ci.quotedItem == nil + ci.content.msgContent?.isVoice == true && ci.content.text.count == 0 && ci.quotedItem == nil && ci.meta.itemForwarded == nil } private func chatItemsList() -> some View { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index 9636199a14..bdda519c2b 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -1892,7 +1892,7 @@ data class ChatItem ( ) = ChatItem( chatDir = dir, - meta = CIMeta.getSample(id, ts, text, status, itemDeleted, itemEdited, itemTimed, editable), + meta = CIMeta.getSample(id, ts, text, status, itemForwarded, itemDeleted, itemEdited, itemTimed, editable), content = CIContent.SndMsgContent(msgContent = MsgContent.MCText(text)), quotedItem = quotedItem, reactions = listOf(), @@ -1976,6 +1976,7 @@ data class ChatItem ( itemStatus = CIStatus.RcvRead(), createdAt = Clock.System.now(), updatedAt = Clock.System.now(), + itemForwarded = null, itemDeleted = null, itemEdited = false, itemTimed = null, @@ -1997,6 +1998,7 @@ data class ChatItem ( itemStatus = CIStatus.RcvRead(), createdAt = Clock.System.now(), updatedAt = Clock.System.now(), + itemForwarded = null, itemDeleted = null, itemEdited = false, itemTimed = null, @@ -2097,6 +2099,7 @@ data class CIMeta ( val itemStatus: CIStatus, val createdAt: Instant, val updatedAt: Instant, + val itemForwarded: CIForwardedFrom?, val itemDeleted: CIDeleted?, val itemEdited: Boolean, val itemTimed: CITimed?, @@ -2120,7 +2123,7 @@ data class CIMeta ( companion object { fun getSample( id: Long, ts: Instant, text: String, status: CIStatus = CIStatus.SndNew(), - itemDeleted: CIDeleted? = null, itemEdited: Boolean = false, itemTimed: CITimed? = null, itemLive: Boolean = false, editable: Boolean = true + itemForwarded: CIForwardedFrom? = null, itemDeleted: CIDeleted? = null, itemEdited: Boolean = false, itemTimed: CITimed? = null, itemLive: Boolean = false, editable: Boolean = true ): CIMeta = CIMeta( itemId = id, @@ -2129,6 +2132,7 @@ data class CIMeta ( itemStatus = status, createdAt = ts, updatedAt = ts, + itemForwarded = itemForwarded, itemDeleted = itemDeleted, itemEdited = itemEdited, itemTimed = itemTimed, @@ -2145,6 +2149,7 @@ data class CIMeta ( itemStatus = CIStatus.SndNew(), createdAt = Clock.System.now(), updatedAt = Clock.System.now(), + itemForwarded = null, itemDeleted = null, itemEdited = false, itemTimed = null, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt index 702dd9fec5..4761b938b9 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt @@ -962,7 +962,7 @@ fun BoxWithConstraintsScope.ChatItemsList( @Composable fun ChatItemView(cItem: ChatItem, range: IntRange?, prevItem: ChatItem?) { - val voiceWithTransparentBack = cItem.content.msgContent is MsgContent.MCVoice && cItem.content.text.isEmpty() && cItem.quotedItem == null + val voiceWithTransparentBack = cItem.content.msgContent is MsgContent.MCVoice && cItem.content.text.isEmpty() && cItem.quotedItem == null && cItem.meta.itemForwarded == null if (chat.chatInfo is ChatInfo.Group) { if (cItem.chatDir is CIDirection.GroupRcv) { val member = cItem.chatDir.groupMember 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 64741f7466..b4f7410da2 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 @@ -304,7 +304,7 @@ fun ChatItemView( MarkedDeletedItemView(cItem, cInfo.timedMessagesTTL, revealed) MarkedDeletedItemDropdownMenu() } else { - if (cItem.quotedItem == null && cItem.meta.itemDeleted == null && !cItem.meta.isLive) { + if (cItem.quotedItem == null && cItem.meta.itemForwarded == null && cItem.meta.itemDeleted == null && !cItem.meta.isLive) { if (mc is MsgContent.MCText && isShortEmoji(cItem.content.text)) { EmojiItemView(cItem, cInfo.timedMessagesTTL) } else if (mc is MsgContent.MCVoice && cItem.content.text.isEmpty()) { 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 641e6affab..3535c8fe26 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 @@ -96,6 +96,7 @@ fun FramedItemView( .fillMaxWidth() .padding(start = 8.dp, top = 6.dp, end = 12.dp, bottom = if (ci.quotedItem == null) 6.dp else 0.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), + verticalAlignment = Alignment.CenterVertically ) { if (icon != null) { Icon( @@ -184,7 +185,7 @@ fun FramedItemView( } val transparentBackground = (ci.content.msgContent is MsgContent.MCImage || ci.content.msgContent is MsgContent.MCVideo) && - !ci.meta.isLive && ci.content.text.isEmpty() && ci.quotedItem == null + !ci.meta.isLive && ci.content.text.isEmpty() && ci.quotedItem == null && ci.meta.itemForwarded == null val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage @@ -219,7 +220,11 @@ fun FramedItemView( } else if (ci.meta.isLive) { FramedItemHeader(stringResource(MR.strings.live), false) } - ci.quotedItem?.let { ciQuoteView(it) } + if (ci.quotedItem != null) { + ciQuoteView(ci.quotedItem) + } else if (ci.meta.itemForwarded != null) { + FramedItemHeader(stringResource(MR.strings.forwarded_description), true, painterResource(MR.images.ic_forward)) + } if (ci.file == null && ci.formattedText == null && !ci.meta.isLive && isShortEmoji(ci.content.text)) { Box(Modifier.padding(vertical = 6.dp, horizontal = 12.dp)) { Column( diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index eafe959640..c4d9e191c6 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -46,6 +46,7 @@ invalid message format LIVE moderated + forwarded invalid chat invalid data error showing message diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_forward.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_forward.svg new file mode 100644 index 0000000000..7ad0b14b70 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_forward.svg @@ -0,0 +1 @@ + \ No newline at end of file