diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumScreen.kt index ec14f6f62386a6c789a34cbde6f671c5798407ed..3eaa778c3335258f1139d50b2d5d3173c909b210 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumScreen.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumScreen.kt @@ -30,8 +30,8 @@ fun ForumScreen( ) = ThreadedGroupScreen( strings = ForumStrings, viewModel = viewModel, - dropdownMenu = { sharingViewModel, expanded, onClose, onLeaveForumClick -> + dropdownMenu = { sharingViewModel, expanded, onClose, onMarkReadClick, onLeaveForumClick -> val forumSharingViewModel = sharingViewModel as ForumSharingViewModel - ForumDropdownMenu(forumSharingViewModel, expanded, onClose, onLeaveForumClick) + ForumDropdownMenu(forumSharingViewModel, expanded, onClose, onMarkReadClick, onLeaveForumClick) } ) diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumConversationViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumConversationViewModel.kt index 4d7e26cf4f19041d600cc55989bb34fa41d8a8ee..429db62a02136c110bd1a1973fe2da0b8c6a2c06 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumConversationViewModel.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumConversationViewModel.kt @@ -112,8 +112,8 @@ class ForumConversationViewModel @Inject constructor( } @DatabaseExecutor - override fun markThreadItemRead(groupId: GroupId, id: MessageId) = - forumManager.setReadFlag(groupId, id, true) + override fun markThreadItemRead(txn: Transaction, groupId: GroupId, id: MessageId) = + forumManager.setReadFlag(txn, groupId, id, true) @UiExecutor override fun deleteGroup() { diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumDropdownMenu.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumDropdownMenu.kt index 871d3b4b031d9dff17909d9e0a65aebc0d41a305..19b06b6ddf2351e998901b9aa02d19716202cb87 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumDropdownMenu.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumDropdownMenu.kt @@ -35,6 +35,7 @@ fun ForumDropdownMenu( forumSharingViewModel: ForumSharingViewModel, expanded: Boolean, onClose: () -> Unit, + onMarkReadClick: () -> Unit, onLeaveForumClick: () -> Unit, ) = DropdownMenu( expanded = expanded, @@ -74,6 +75,17 @@ fun ForumDropdownMenu( style = MaterialTheme.typography.body2, ) } + DropdownMenuItem( + onClick = { + onClose() + onMarkReadClick() + } + ) { + Text( + i18n("group.mark.read"), + style = MaterialTheme.typography.body2, + ) + } DropdownMenuItem( onClick = { onClose() diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingViewModel.kt index d47f5e7b7c22062edd9c02cc7e295f69ee6ff0a5..773c13f4a58e66c2528653aafff1156c353df907 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingViewModel.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingViewModel.kt @@ -129,7 +129,7 @@ class ForumSharingViewModel @Inject constructor( } } - fun loadSharingStatus(txn: Transaction, groupId: GroupId) { + private fun loadSharingStatus(txn: Transaction, groupId: GroupId) { val map = contactManager.getContacts(txn).associate { contact -> contact.id to forumSharingManager.getSharingStatus(txn, groupId, contact) } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupScreen.kt index 48d13acb0b5fbe271b8d473529985a263dc4c2e8..9a94982bce8cb00559c25737837258e33bbd9f76 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupScreen.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupScreen.kt @@ -43,12 +43,13 @@ fun PrivateGroupScreen( ThreadedGroupScreen( strings = PrivateGroupStrings, viewModel = viewModel, - dropdownMenu = { sharingViewModel, expanded, onClose, onLeaveOrDissolvePrivateGroupClick -> + dropdownMenu = { sharingViewModel, expanded, onClose, onMarkReadClick, onLeaveOrDissolvePrivateGroupClick -> val privateGroupSharingViewModel = sharingViewModel as PrivateGroupSharingViewModel PrivateGroupDropdownMenu( privateGroupSharingViewModel = privateGroupSharingViewModel, expanded = expanded, onClose = onClose, + onMarkReadClick = onMarkReadClick, onLeaveOrDissolvePrivateGroupClick = onLeaveOrDissolvePrivateGroupClick ) }, 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 81695874c4c5eee2a49db8d285f6cba876edbd8b..ab44963e734c59fee00cadad2ef448793d6fcfc0 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 @@ -135,8 +135,8 @@ class PrivateGroupConversationViewModel @Inject constructor( } @DatabaseExecutor - override fun markThreadItemRead(groupId: GroupId, id: MessageId) = - privateGroupManager.setReadFlag(groupId, id, true) + override fun markThreadItemRead(txn: Transaction, groupId: GroupId, id: MessageId) = + privateGroupManager.setReadFlag(txn, groupId, id, true) @UiExecutor override fun deleteGroup() { diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupDropdownMenu.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupDropdownMenu.kt index a23d807ab2a6388b56000fb5241d929006d73217..efb37e4216ea7691d484a9b307c3a71a1f54eedd 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupDropdownMenu.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupDropdownMenu.kt @@ -35,6 +35,7 @@ fun PrivateGroupDropdownMenu( privateGroupSharingViewModel: PrivateGroupSharingViewModel, expanded: Boolean, onClose: () -> Unit, + onMarkReadClick: () -> Unit, onLeaveOrDissolvePrivateGroupClick: () -> Unit, ) = DropdownMenu( expanded = expanded, @@ -76,6 +77,17 @@ fun PrivateGroupDropdownMenu( ) } } + DropdownMenuItem( + onClick = { + onClose() + onMarkReadClick() + } + ) { + Text( + i18n("group.mark.read"), + style = MaterialTheme.typography.body2, + ) + } DropdownMenuItem( onClick = { onClose() diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedConversationViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedConversationViewModel.kt index 4d8fe22105a8287730e0911d41565630172313d9..8190c5fd61dab16c7ab66128e6fec03dfa54eee2 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedConversationViewModel.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedConversationViewModel.kt @@ -112,13 +112,13 @@ abstract class ThreadedConversationViewModel( } @DatabaseExecutor - abstract fun markThreadItemRead(groupId: GroupId, id: MessageId) + abstract fun markThreadItemRead(txn: Transaction, groupId: GroupId, id: MessageId) @UiExecutor - fun markThreadItemsRead(ids: List<MessageId>) { + fun markThreadItemsRead(ids: List<MessageId>? = null) { // TODO messageTree.get(id) would be nice, but not in briar-core val readIds = (state.value as? Loaded)?.posts?.filter { item -> - !item.isRead && ids.contains(item.id) + ids?.contains(item.id) ?: true && !item.isRead }?.map { item -> item.isRead = true item.id @@ -126,17 +126,17 @@ abstract class ThreadedConversationViewModel( val groupId = _threadedGroupItem.value?.id if (readIds.isNotEmpty() && groupId != null) { - runOnDbThread { + runOnDbThreadWithTransaction(false) { txn -> readIds.forEach { id -> - markThreadItemRead(groupId, id) + markThreadItemRead(txn, groupId, id) + } + txn.attach(ThreadedGroupMessageReadEvent(clientId, groupId, readIds.size)) + txn.attach { + // TODO replace immutable ThreadItems instead to avoid recomposing whole list + val messageTree = (state.value as? Loaded)?.messageTree ?: return@attach + _state.value = Loaded(messageTree) } } - // we don't attach this to the transaction that actually changes the DB, - // but that should be fine for this purpose of just decrementing a counter - eventBus.broadcast(ThreadedGroupMessageReadEvent(clientId, groupId, readIds.size)) - // TODO replace immutable ThreadItems instead to avoid recomposing whole list - val messageTree = (state.value as? Loaded)?.messageTree ?: return - _state.value = Loaded(messageTree) } } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationScreen.kt index 2aebe4f82db729ac6188fcd89e35f87bf7a21612..86b607c30a572eb4bc3b94446bb423f0e27bb158 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationScreen.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationScreen.kt @@ -76,6 +76,7 @@ fun ThreadedGroupConversationScreen( threadedGroupItem = groupItem, sharingViewModel = viewModel.sharingViewModel, onGroupDelete = viewModel::deleteGroup, + onMarkRead = viewModel::markThreadItemsRead, dropdownMenu = dropdownMenu, ) } @@ -108,6 +109,7 @@ private fun ThreadedGroupConversationHeader( strings: ThreadedGroupStrings, threadedGroupItem: ThreadedGroupItem, sharingViewModel: ThreadedGroupSharingViewModel, + onMarkRead: () -> Unit, onGroupDelete: () -> Unit, dropdownMenu: ThreadedGroupDropdownMenu, ) { @@ -151,7 +153,8 @@ private fun ThreadedGroupConversationHeader( dropdownMenu( sharingViewModel, menuState.value == MAIN, - close + close, + onMarkRead, ) { deleteGroupDialogVisible.value = true } } } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupDropdownMenu.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupDropdownMenu.kt index dc6909d9505934e72a080f532719be1e6502ebd2..b9cd05701592c685fa392d5839110a1aff498c1b 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupDropdownMenu.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupDropdownMenu.kt @@ -25,5 +25,6 @@ typealias ThreadedGroupDropdownMenu = @Composable ( sharingViewModel: ThreadedGroupSharingViewModel, expanded: Boolean, onClose: () -> Unit, + onMarkReadClick: () -> Unit, onLeaveGroupClick: () -> Unit, ) -> Unit diff --git a/briar-desktop/src/main/resources/strings/BriarDesktop.properties b/briar-desktop/src/main/resources/strings/BriarDesktop.properties index 327cf981bbdef395e682b82504017b7868d42e0b..afa4b54bbd27f4fdb3732dd95d7dee33fec63d7c 100644 --- a/briar-desktop/src/main/resources/strings/BriarDesktop.properties +++ b/briar-desktop/src/main/resources/strings/BriarDesktop.properties @@ -209,6 +209,7 @@ group.member.created_you=You created the group group.member.created_contact={0} created the group group.invite.action.title=Invite Contacts group.invite.action.no_contacts=No contacts yet. You can only invite contacts to your private group. +group.mark.read=Mark as read # Introduction introduction.introduce=Make Introduction