diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumItem.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumItem.kt index 83a8b4e19795f6e1fd46a2f41ec28d66c00546e4..c68fdc1d7ee09995f9f26a8bc24a61871d9f5083 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumItem.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumItem.kt @@ -21,6 +21,8 @@ package org.briarproject.briar.desktop.forums import org.briarproject.bramble.api.sync.GroupId import org.briarproject.briar.api.client.MessageTracker import org.briarproject.briar.api.forum.Forum +import org.briarproject.briar.api.forum.ForumPostHeader +import kotlin.math.max interface GroupItem { val id: GroupId @@ -47,11 +49,10 @@ data class ForumItem( override val id: GroupId get() = forum.id override val name: String get() = forum.name - override fun equals(other: Any?): Boolean { - return other is ForumItem && other.id == id - } - - override fun hashCode(): Int { - return forum.hashCode() - } + fun updateOnPostReceived(header: ForumPostHeader) = + copy( + msgCount = msgCount + 1, + unread = if (header.isRead) unread else unread + 1, + timestamp = max(header.timestamp, this.timestamp) + ) } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumViewModel.kt index 3bfa842a781bb66951dbcbd3ee09318a22b9784d..bc8ff410fe512a70e0fa602d2cd1b4c9cb9dcab7 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumViewModel.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumViewModel.kt @@ -21,6 +21,7 @@ package org.briarproject.briar.desktop.forums import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf +import mu.KotlinLogging import org.briarproject.bramble.api.db.TransactionManager import org.briarproject.bramble.api.event.Event import org.briarproject.bramble.api.event.EventBus @@ -29,8 +30,11 @@ import org.briarproject.bramble.api.sync.GroupId import org.briarproject.bramble.api.sync.event.GroupAddedEvent import org.briarproject.bramble.api.sync.event.GroupRemovedEvent import org.briarproject.briar.api.forum.ForumManager +import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent import org.briarproject.briar.desktop.threading.BriarExecutors import org.briarproject.briar.desktop.utils.clearAndAddAll +import org.briarproject.briar.desktop.utils.removeFirst +import org.briarproject.briar.desktop.utils.replaceFirst import org.briarproject.briar.desktop.viewmodel.EventListenerDbViewModel import org.briarproject.briar.desktop.viewmodel.asState import javax.inject.Inject @@ -44,6 +48,10 @@ class ForumViewModel @Inject constructor( eventBus: EventBus, ) : EventListenerDbViewModel(briarExecutors, lifecycleManager, db, eventBus) { + companion object { + private val LOG = KotlinLogging.logger {} + } + private val _fullForumList = mutableStateListOf<ForumItem>() val forumList = derivedStateOf { val filter = _filterBy.value @@ -75,31 +83,44 @@ class ForumViewModel @Inject constructor( } override fun eventOccurred(e: Event) { - if (e is GroupAddedEvent) { - if (e.group.clientId == ForumManager.CLIENT_ID) loadGroups() - } else if (e is GroupRemovedEvent) { - if (e.group.clientId == ForumManager.CLIENT_ID) { - loadGroups() + when { + e is GroupAddedEvent && e.group.clientId == ForumManager.CLIENT_ID -> { + runOnDbThreadWithTransaction(true) { txn -> + val item = ForumItem( + forum = forumManager.getForum(txn, e.group.id), + groupCount = forumManager.getGroupCount(txn, e.group.id), + ) + txn.attach { + addItem(item) + } + } + } + + e is GroupRemovedEvent && e.group.clientId == ForumManager.CLIENT_ID -> { + removeItem(e.group.id) if (selectedGroupItem.value?.id == e.group.id) _selectedGroupItem.value = null } + + e is ForumPostReceivedEvent -> { + // todo: better use equivalent to ConversationMessageTrackedEvent to update on new *own* posts as well + updateItem(e.groupId) { it.updateOnPostReceived(e.header) } + } } } - fun createForum(name: String) { + fun createForum(name: String) = runOnDbThread { forumManager.addForum(name) } - private fun loadGroups() { - runOnDbThreadWithTransaction(true) { txn -> - val list = forumManager.getForums(txn).map { forums -> - ForumItem( - forum = forums, - groupCount = forumManager.getGroupCount(txn, forums.id), - ) - } - txn.attach { - _fullForumList.clearAndAddAll(list) - } + private fun loadGroups() = runOnDbThreadWithTransaction(true) { txn -> + val list = forumManager.getForums(txn).map { forums -> + ForumItem( + forum = forums, + groupCount = forumManager.getGroupCount(txn, forums.id), + ) + } + txn.attach { + _fullForumList.clearAndAddAll(list) } } @@ -113,4 +134,19 @@ class ForumViewModel @Inject constructor( fun setFilterBy(filter: String) { _filterBy.value = filter } + + private fun addItem(forumItem: ForumItem) = _fullForumList.add(forumItem) + + private fun updateItem(forumId: GroupId, update: (ForumItem) -> ForumItem) { + _fullForumList.replaceFirst( + { it.id == forumId }, + update + ) + } + + private fun removeItem(forumId: GroupId) { + _fullForumList.removeFirst { + it.id == forumId + } + } }