diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupConversationViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupConversationViewModel.kt index 501c155c41de3e98b0d898839c156cf1ea14636a..d803d29109dd732dc53fe3317feb896980ae88a4 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupConversationViewModel.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupConversationViewModel.kt @@ -78,11 +78,10 @@ class PrivateGroupConversationViewModel @Inject constructor( override fun loadThreadItems(txn: Transaction, groupId: GroupId) = privateGroupManager.getHeaders(txn, groupId).map { header -> - PrivateGroupMessageItem( - header, - if (header !is JoinMessageHeader) privateGroupManager.getMessageText(txn, header.id) - else "" // todo - ) + if (header is JoinMessageHeader) + PrivateGroupJoinItem(header) + else + PrivateGroupMessageItem(header, privateGroupManager.getMessageText(txn, header.id)) } @UiExecutor diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupMessageItem.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupMessageItem.kt index 546ff08f3441e4074a3433c877665e4a0aabb93b..aef62faf056b40d5109b75fb363f3560610deee5 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupMessageItem.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupMessageItem.kt @@ -18,12 +18,16 @@ package org.briarproject.briar.desktop.privategroup.conversation +import org.briarproject.briar.api.identity.AuthorInfo.Status.OURSELVES import org.briarproject.briar.api.privategroup.GroupMessageHeader +import org.briarproject.briar.api.privategroup.JoinMessageHeader import org.briarproject.briar.desktop.threadedgroup.conversation.ThreadItem +import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n +import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nF import javax.annotation.concurrent.NotThreadSafe @NotThreadSafe -class PrivateGroupMessageItem(h: GroupMessageHeader, text: String) : ThreadItem( +open class PrivateGroupMessageItem(h: GroupMessageHeader, text: String) : ThreadItem( messageId = h.id, parentId = h.parentId, text = text, @@ -32,3 +36,21 @@ class PrivateGroupMessageItem(h: GroupMessageHeader, text: String) : ThreadItem( authorInfo = h.authorInfo, isRead = h.isRead ) + +class PrivateGroupJoinItem(h: JoinMessageHeader) : PrivateGroupMessageItem(h, "") { + val isInitial = h.isInitial +} + +val ThreadItem.isMeta: Boolean get() = this is PrivateGroupJoinItem + +val ThreadItem.metaText: String + get() { + if (this !is PrivateGroupJoinItem) throw IllegalArgumentException() + return if (isInitial) { + if (authorInfo.status == OURSELVES) i18n("group.meta.created.you") + else i18nF("group.meta.created.other", authorName) + } else { + if (authorInfo.status == OURSELVES) i18n("group.meta.joined.you") + else i18nF("group.meta.joined.other", authorName) + } + } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadItemView.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadItemView.kt index 64cc1ec225e0b2ee8ca12e0b909308266c98cd94..2a0b46e0828199dbe3d4d91c3d12469728ef74f1 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadItemView.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadItemView.kt @@ -47,6 +47,7 @@ import androidx.compose.ui.Alignment.Companion.Center import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight.Companion.Bold import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow @@ -54,6 +55,8 @@ import androidx.compose.ui.unit.dp import org.briarproject.briar.api.identity.AuthorInfo.Status.OURSELVES import org.briarproject.briar.desktop.contact.ProfileCircle import org.briarproject.briar.desktop.forum.conversation.ForumPostItem +import org.briarproject.briar.desktop.privategroup.conversation.isMeta +import org.briarproject.briar.desktop.privategroup.conversation.metaText import org.briarproject.briar.desktop.theme.Blue500 import org.briarproject.briar.desktop.theme.divider import org.briarproject.briar.desktop.ui.Constants.COLUMN_WIDTH @@ -65,6 +68,7 @@ import org.briarproject.briar.desktop.ui.VerticalDivider import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n import org.briarproject.briar.desktop.utils.PreviewUtils.preview import org.briarproject.briar.desktop.utils.TimeUtils.getFormattedTimestamp +import org.briarproject.briar.desktop.utils.UiUtils.modifyIf import org.briarproject.briar.desktop.utils.getRandomForumPostHeader import org.briarproject.briar.desktop.utils.getRandomString import kotlin.math.min @@ -110,24 +114,24 @@ fun ThreadItemView( Column( modifier = Modifier .fillMaxWidth() - .then( - if (isSelected) { - Modifier.border(3.dp, Blue500) - } else Modifier - ).selectable( - selected = isSelected, - onClick = { onPostSelected(item) } + // only make normal thread items selectable + .modifyIf( + !item.isMeta, + Modifier.selectable( + selected = isSelected, + onClick = { onPostSelected(item) } + ).modifyIf(isSelected, Modifier.border(3.dp, Blue500)) ), ) { HorizontalDivider() - ThreadItemContentComposable(item) + ThreadItemContent(item) } } } @Composable @OptIn(ExperimentalFoundationApi::class) -fun ThreadItemContentComposable( +fun ThreadItemContent( item: ThreadItem, modifier: Modifier = Modifier, isPreview: Boolean = false, @@ -167,7 +171,15 @@ fun ThreadItemContentComposable( // should be changed back to verticalArrangement = spacedBy(8.dp) on the containing Column // when https://github.com/JetBrains/compose-jb/issues/2729 is fixed Spacer(Modifier.height(8.dp)) - if (!isPreview) { + if (item.isMeta) { + // italicised text for special thread items + Text( + modifier = Modifier.fillMaxWidth(), + text = item.metaText, + fontStyle = FontStyle.Italic, + ) + } else if (!isPreview) { + // selectable text for normal thread items which are not previewed for reply SelectionContainer { Text( modifier = Modifier.fillMaxWidth(), @@ -175,6 +187,7 @@ fun ThreadItemContentComposable( ) } } else { + // shorten normal thread items when previewed for reply Text( modifier = Modifier.fillMaxWidth(), text = item.text, diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationInput.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationInput.kt index 89b77665cb5f6c0d40571853fca21bf753ca2a0c..f61e6445c377bf209bba054afe4aecd4085d3ff8 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationInput.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationInput.kt @@ -83,7 +83,7 @@ fun ThreadedGroupConversationInput( text = strings.messageReplyIntro, modifier = Modifier.padding(bottom = 8.dp), ) - ThreadItemContentComposable( + ThreadItemContent( item = selectedThreadItem, isPreview = true, modifier = Modifier diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/UiUtils.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/UiUtils.kt index cd88bf24c6910b3bf1d2f0d0db5c7f1e9c60ebd5..2e5be7248705468649ee08ab90ad4323fec9289c 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/UiUtils.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/UiUtils.kt @@ -1,6 +1,6 @@ /* * Briar Desktop - * Copyright (C) 2021-2022 The Briar Project + * Copyright (C) 2021-2023 The Briar Project * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -19,6 +19,7 @@ package org.briarproject.briar.desktop.utils import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp @@ -78,4 +79,9 @@ object UiUtils { return Dimension(width.dp.roundToPx(), height.dp.roundToPx()) } } + + fun Modifier.modifyIf( + condition: Boolean, + modifier: Modifier, + ) = if (condition) then(modifier) else this } diff --git a/briar-desktop/src/main/resources/strings/BriarDesktop.properties b/briar-desktop/src/main/resources/strings/BriarDesktop.properties index a088ec95c26ab4a51d8932a38c3e500a22622bca..a16d623948c096b66b647693bb2c109d1cb6902f 100644 --- a/briar-desktop/src/main/resources/strings/BriarDesktop.properties +++ b/briar-desktop/src/main/resources/strings/BriarDesktop.properties @@ -187,6 +187,10 @@ group.sharing.status.with=Shared with {0} ({1} online) group.message.hint=New Message group.message.reply.hint=New Reply group.message.reply.intro=Reply to: +group.meta.created.you=You created the group +group.meta.created.other={0} created the group +group.meta.joined.you=You joined the group +group.meta.joined.other={0} joined the group group.leave.title=Leave Group group.leave.dialog.title=Confirm Leaving Group group.leave.dialog.message=Are you sure that you want to leave this private group?