diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt
index 17e197550661a26cd39f1b8e487b2209496cd1f8..607730b4bbb52983f5b5afc7db6fb6ac7682a96a 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt
@@ -64,7 +64,7 @@ import org.briarproject.briar.desktop.contact.ContactItem
 import org.briarproject.briar.desktop.contact.loadContactItem
 import org.briarproject.briar.desktop.conversation.ConversationRequestItem.RequestType.FORUM
 import org.briarproject.briar.desktop.conversation.ConversationRequestItem.RequestType.INTRODUCTION
-import org.briarproject.briar.desktop.forums.sharing.ForumInvitationSentEvent
+import org.briarproject.briar.desktop.forum.sharing.ForumInvitationSentEvent
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.utils.KLoggerUtils.e
 import org.briarproject.briar.desktop.utils.KLoggerUtils.i
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/forum/ForumItem.kt
similarity index 92%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumItem.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumItem.kt
index 22c555b23f48b6a3d947ad48bc4fda10c1300ef5..40c5c5e8f8884c85095368077d271b039e30138b 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumItem.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumItem.kt
@@ -16,13 +16,13 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums
+package org.briarproject.briar.desktop.forum
 
 import org.briarproject.bramble.api.sync.GroupId
 import org.briarproject.briar.api.client.MessageTracker
 import org.briarproject.briar.api.client.PostHeader
 import org.briarproject.briar.api.forum.Forum
-import org.briarproject.briar.desktop.group.GroupItem
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupItem
 import kotlin.math.max
 
 data class ForumItem(
@@ -30,7 +30,7 @@ data class ForumItem(
     override val msgCount: Int,
     override val unread: Int,
     override val timestamp: Long,
-) : GroupItem {
+) : ThreadedGroupItem {
 
     constructor(forum: Forum, groupCount: MessageTracker.GroupCount) : this(
         forum = forum,
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumListViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumListViewModel.kt
similarity index 91%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumListViewModel.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumListViewModel.kt
index 84d6b9b491c820cfc9afb3a2b85c7f080f13baff..6dbdad4dbb691a352719d234f089ae831ac26a4d 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumListViewModel.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumListViewModel.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums
+package org.briarproject.briar.desktop.forum
 
 import androidx.compose.runtime.mutableStateListOf
 import mu.KotlinLogging
@@ -30,8 +30,8 @@ import org.briarproject.bramble.api.sync.GroupId
 import org.briarproject.briar.api.client.PostHeader
 import org.briarproject.briar.api.forum.ForumManager
 import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent
-import org.briarproject.briar.desktop.forums.conversation.ForumConversationViewModel
-import org.briarproject.briar.desktop.group.GroupListViewModel
+import org.briarproject.briar.desktop.forum.conversation.ForumConversationViewModel
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupListViewModel
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.utils.removeFirst
 import org.briarproject.briar.desktop.utils.replaceFirst
@@ -45,7 +45,7 @@ class ForumListViewModel
     lifecycleManager: LifecycleManager,
     db: TransactionManager,
     eventBus: EventBus,
-) : GroupListViewModel<ForumItem>(threadViewModel, briarExecutors, lifecycleManager, db, eventBus) {
+) : ThreadedGroupListViewModel<ForumItem>(threadViewModel, briarExecutors, lifecycleManager, db, eventBus) {
 
     companion object {
         private val LOG = KotlinLogging.logger {}
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumPostReadEvent.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumPostReadEvent.kt
similarity index 91%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumPostReadEvent.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumPostReadEvent.kt
index 7d2656143f6b135301358e1c032ff3e7dc1e7192..f0da6e2e9c035a2ebc4ed4b302935bbcc82663ee 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumPostReadEvent.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumPostReadEvent.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
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums
+package org.briarproject.briar.desktop.forum
 
 import org.briarproject.bramble.api.event.Event
 import org.briarproject.bramble.api.sync.GroupId
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumScreen.kt
similarity index 84%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumScreen.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumScreen.kt
index ffb232f1c051a435182aff6ef22a7d60c718b1de..803705e23d97b1f39bf4e916d76210732dcbd048 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumScreen.kt
@@ -16,17 +16,17 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums
+package org.briarproject.briar.desktop.forum
 
 import androidx.compose.runtime.Composable
-import org.briarproject.briar.desktop.forums.conversation.ForumDropdownMenu
-import org.briarproject.briar.desktop.group.GroupScreen
+import org.briarproject.briar.desktop.forum.conversation.ForumDropdownMenu
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupScreen
 import org.briarproject.briar.desktop.viewmodel.viewModel
 
 @Composable
 fun ForumScreen(
     viewModel: ForumListViewModel = viewModel(),
-) = GroupScreen(
+) = ThreadedGroupScreen(
     strings = ForumStrings,
     viewModel = viewModel,
     dropdownMenu = { forumSharingViewModel, expanded, onClose, onLeaveForumClick ->
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumStrings.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumStrings.kt
similarity index 94%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumStrings.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumStrings.kt
index f18ba114f9cc9095dce078bf93f55c75a8710e03..4812d32eefd9bcf1b2d9985c1043fa82b12fafe3 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumStrings.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/ForumStrings.kt
@@ -16,16 +16,16 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums
+package org.briarproject.briar.desktop.forum
 
 import org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH
 import org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_TEXT_LENGTH
-import org.briarproject.briar.desktop.group.GroupStrings
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupStrings
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nF
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nP
 
-object ForumStrings : GroupStrings(
+object ForumStrings : ThreadedGroupStrings(
     listTitle = i18n("forum.search.title"),
     listDescription = i18n("access.forums.list"),
     addGroupTitle = i18n("forum.add.title"),
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/conversation/ForumConversationViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumConversationViewModel.kt
similarity index 94%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/conversation/ForumConversationViewModel.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumConversationViewModel.kt
index 2ceb8eef0ef548ab8e708c605f340dafab9c6d08..75570a87a2001d1d84b6ba4c81e407314efdc44c 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/conversation/ForumConversationViewModel.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumConversationViewModel.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums.conversation
+package org.briarproject.briar.desktop.forum.conversation
 
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.DelicateCoroutinesApi
@@ -38,9 +38,9 @@ import org.briarproject.bramble.api.system.Clock
 import org.briarproject.briar.api.client.MessageTracker
 import org.briarproject.briar.api.forum.ForumManager
 import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent
-import org.briarproject.briar.desktop.forums.ForumItem
-import org.briarproject.briar.desktop.forums.sharing.ForumSharingViewModel
-import org.briarproject.briar.desktop.group.conversation.ThreadedConversationViewModel
+import org.briarproject.briar.desktop.forum.ForumItem
+import org.briarproject.briar.desktop.forum.sharing.ForumSharingViewModel
+import org.briarproject.briar.desktop.threadedgroup.conversation.ThreadedConversationViewModel
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.threading.UiExecutor
 import java.lang.Long.max
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/conversation/ForumDropdownMenu.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumDropdownMenu.kt
similarity index 89%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/conversation/ForumDropdownMenu.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumDropdownMenu.kt
index ae00c4015b60d930a071df6c13b813e221fb4aa9..d4195d362f8862bdcb18a5f889f3af538d2e4b32 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/conversation/ForumDropdownMenu.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumDropdownMenu.kt
@@ -16,16 +16,16 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums.conversation
+package org.briarproject.briar.desktop.forum.conversation
 
 import androidx.compose.material.DropdownMenu
 import androidx.compose.material.DropdownMenuItem
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
-import org.briarproject.briar.desktop.forums.sharing.ForumSharingActionDrawerContent
-import org.briarproject.briar.desktop.forums.sharing.ForumSharingStatusDrawerContent
-import org.briarproject.briar.desktop.forums.sharing.ForumSharingViewModel
+import org.briarproject.briar.desktop.forum.sharing.ForumSharingActionDrawerContent
+import org.briarproject.briar.desktop.forum.sharing.ForumSharingStatusDrawerContent
+import org.briarproject.briar.desktop.forum.sharing.ForumSharingViewModel
 import org.briarproject.briar.desktop.ui.getInfoDrawerHandler
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/conversation/ForumPostItem.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumPostItem.kt
similarity index 89%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/conversation/ForumPostItem.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumPostItem.kt
index f9a5b8f2ce94afcafc2dfe703c0399e5ae87e725..009d842ed9489e51d2816243225e094f615f10e8 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/conversation/ForumPostItem.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/conversation/ForumPostItem.kt
@@ -16,10 +16,10 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums.conversation
+package org.briarproject.briar.desktop.forum.conversation
 
 import org.briarproject.briar.api.forum.ForumPostHeader
-import org.briarproject.briar.desktop.group.conversation.ThreadItem
+import org.briarproject.briar.desktop.threadedgroup.conversation.ThreadItem
 import javax.annotation.concurrent.NotThreadSafe
 
 @NotThreadSafe
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/sharing/ForumInvitationSentEvent.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumInvitationSentEvent.kt
similarity index 94%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/sharing/ForumInvitationSentEvent.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumInvitationSentEvent.kt
index 016dfd976ffec2ba09c6001b81de71b59cdc9a17..1d090fb951704d0cc33ef71041b8616e40c09b15 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/sharing/ForumInvitationSentEvent.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumInvitationSentEvent.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums.sharing
+package org.briarproject.briar.desktop.forum.sharing
 
 import org.briarproject.bramble.api.contact.ContactId
 import org.briarproject.bramble.api.event.Event
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/sharing/ForumSharingActionDrawerContent.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingActionDrawerContent.kt
similarity index 98%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/sharing/ForumSharingActionDrawerContent.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingActionDrawerContent.kt
index f4924ed795243558dd7d7ee2fd77791ae0dae3a2..d85a38c1a94a7444e6fc7bf1c45c9cf38919f101 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/sharing/ForumSharingActionDrawerContent.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingActionDrawerContent.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
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums.sharing
+package org.briarproject.briar.desktop.forum.sharing
 
 import androidx.compose.foundation.layout.Arrangement.spacedBy
 import androidx.compose.foundation.layout.Box
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/sharing/ForumSharingStatusDrawerContent.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingStatusDrawerContent.kt
similarity index 97%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/sharing/ForumSharingStatusDrawerContent.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingStatusDrawerContent.kt
index c3c47e99b141964444e4440a0d44e65e139e899d..b289ffa91689e58137a873ea0c466a31e6f06111 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/sharing/ForumSharingStatusDrawerContent.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingStatusDrawerContent.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
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums.sharing
+package org.briarproject.briar.desktop.forum.sharing
 
 import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy
 import androidx.compose.foundation.layout.Box
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/sharing/ForumSharingViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingViewModel.kt
similarity index 99%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/sharing/ForumSharingViewModel.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingViewModel.kt
index 03dc7a57be0a89d6deb86f9cd7b4607519979ab3..cf041bf7816889f07d81e2651fdb646c5f30b206 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/sharing/ForumSharingViewModel.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forum/sharing/ForumSharingViewModel.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums.sharing
+package org.briarproject.briar.desktop.forum.sharing
 
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.mutableStateOf
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupItem.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupItem.kt
index 2f50b43eb7abdd0bc8cc231f8b7d79dcf63fbe2a..fce9fc24abaf6268df5058c547c579fa7307ecc9 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupItem.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupItem.kt
@@ -22,7 +22,7 @@ import org.briarproject.bramble.api.sync.GroupId
 import org.briarproject.briar.api.client.MessageTracker
 import org.briarproject.briar.api.client.PostHeader
 import org.briarproject.briar.api.privategroup.PrivateGroup
-import org.briarproject.briar.desktop.group.GroupItem
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupItem
 import kotlin.math.max
 
 data class PrivateGroupItem(
@@ -30,7 +30,7 @@ data class PrivateGroupItem(
     override val msgCount: Int,
     override val unread: Int,
     override val timestamp: Long,
-) : GroupItem {
+) : ThreadedGroupItem {
 
     constructor(privateGroup: PrivateGroup, groupCount: MessageTracker.GroupCount) :
         this(
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupListViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupListViewModel.kt
index 410294a95ab4bd99146ed3d32be4bb4732f70ac4..5997082470cf0c26ed1f95e442f71bbbffacbaf4 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupListViewModel.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupListViewModel.kt
@@ -40,8 +40,8 @@ import org.briarproject.briar.api.privategroup.GroupMessageFactory
 import org.briarproject.briar.api.privategroup.PrivateGroupFactory
 import org.briarproject.briar.api.privategroup.PrivateGroupManager
 import org.briarproject.briar.api.privategroup.event.GroupMessageAddedEvent
-import org.briarproject.briar.desktop.group.GroupListViewModel
 import org.briarproject.briar.desktop.privategroup.conversation.PrivateGroupConversationViewModel
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupListViewModel
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.utils.removeFirst
 import org.briarproject.briar.desktop.utils.replaceFirst
@@ -60,7 +60,7 @@ class PrivateGroupListViewModel
     lifecycleManager: LifecycleManager,
     db: TransactionManager,
     eventBus: EventBus,
-) : GroupListViewModel<PrivateGroupItem>(threadViewModel, briarExecutors, lifecycleManager, db, eventBus) {
+) : ThreadedGroupListViewModel<PrivateGroupItem>(threadViewModel, briarExecutors, lifecycleManager, db, eventBus) {
 
     override val clientId: ClientId = PrivateGroupManager.CLIENT_ID
 
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 568a7b7736cbb9574fc3e99bf9e745aca82f7104..286b65482b6923522ead7c550a5578b761e18189 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
@@ -19,13 +19,13 @@
 package org.briarproject.briar.desktop.privategroup
 
 import androidx.compose.runtime.Composable
-import org.briarproject.briar.desktop.group.GroupScreen
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupScreen
 import org.briarproject.briar.desktop.viewmodel.viewModel
 
 @Composable
 fun PrivateGroupScreen(
     viewModel: PrivateGroupListViewModel = viewModel(),
-) = GroupScreen(
+) = ThreadedGroupScreen(
     strings = PrivateGroupStrings,
     viewModel = viewModel,
     dropdownMenu = { forumSharingViewModel, expanded, onClose, onLeaveForumClick ->
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupStrings.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupStrings.kt
index 8ecc2adc077469b8ebaa4cbbabb82d887720f601..0988825d78d859d179c732dc0ed8c077343a236a 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupStrings.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupStrings.kt
@@ -20,12 +20,12 @@ package org.briarproject.briar.desktop.privategroup
 
 import org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_NAME_LENGTH
 import org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_TEXT_LENGTH
-import org.briarproject.briar.desktop.group.GroupStrings
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupStrings
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nF
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nP
 
-object PrivateGroupStrings : GroupStrings(
+object PrivateGroupStrings : ThreadedGroupStrings(
     listTitle = i18n("group.search.title"),
     listDescription = i18n("access.group.list"),
     addGroupTitle = i18n("group.add.title"),
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 396f05c875e5074ad5475625c252f199049c71e3..593bac83d417b810fc612f682adaadc8e5b3479b 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
@@ -39,8 +39,8 @@ import org.briarproject.briar.api.client.MessageTracker
 import org.briarproject.briar.api.privategroup.GroupMessageFactory
 import org.briarproject.briar.api.privategroup.JoinMessageHeader
 import org.briarproject.briar.api.privategroup.PrivateGroupManager
-import org.briarproject.briar.desktop.forums.sharing.ForumSharingViewModel
-import org.briarproject.briar.desktop.group.conversation.ThreadedConversationViewModel
+import org.briarproject.briar.desktop.forum.sharing.ForumSharingViewModel
+import org.briarproject.briar.desktop.threadedgroup.conversation.ThreadedConversationViewModel
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.threading.UiExecutor
 import java.lang.Long.max
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 efc450c4605e8465159ffe27d24a868cbea6c619..546ff08f3441e4074a3433c877665e4a0aabb93b 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
@@ -19,7 +19,7 @@
 package org.briarproject.briar.desktop.privategroup.conversation
 
 import org.briarproject.briar.api.privategroup.GroupMessageHeader
-import org.briarproject.briar.desktop.group.conversation.ThreadItem
+import org.briarproject.briar.desktop.threadedgroup.conversation.ThreadItem
 import javax.annotation.concurrent.NotThreadSafe
 
 @NotThreadSafe
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/AddGroupDialog.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/AddThreadedGroupDialog.kt
similarity index 93%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/AddGroupDialog.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/AddThreadedGroupDialog.kt
index 7e8ec71b2d5b857df446e07c3c9e103e66f6dab4..f8cd80afc2382cecb9f2c29eb7f6309d338f1361 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/AddGroupDialog.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/AddThreadedGroupDialog.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group
+package org.briarproject.briar.desktop.threadedgroup
 
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Row
@@ -50,7 +50,7 @@ import androidx.compose.ui.window.Dialog
 import androidx.compose.ui.window.WindowPosition
 import androidx.compose.ui.window.rememberDialogState
 import org.briarproject.bramble.util.StringUtils.utf8IsTooLong
-import org.briarproject.briar.desktop.forums.ForumStrings
+import org.briarproject.briar.desktop.forum.ForumStrings
 import org.briarproject.briar.desktop.privategroup.PrivateGroupStrings
 import org.briarproject.briar.desktop.utils.AccessibilityUtils.description
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
@@ -61,7 +61,7 @@ fun main() = preview(
     "visible" to true,
     "forums" to true
 ) {
-    AddGroupDialog(
+    AddThreadedGroupDialog(
         strings = if (getBooleanParameter("forums")) ForumStrings else PrivateGroupStrings,
         visible = getBooleanParameter("visible"),
         onCreate = {},
@@ -70,8 +70,8 @@ fun main() = preview(
 }
 
 @Composable
-fun AddGroupDialog(
-    strings: GroupStrings,
+fun AddThreadedGroupDialog(
+    strings: ThreadedGroupStrings,
     visible: Boolean,
     onCreate: (String) -> Unit,
     onCancelButtonClicked: () -> Unit,
@@ -110,7 +110,7 @@ fun AddGroupDialog(
                         }
                     },
                     content = {
-                        AddGroupContent(name.value, onNameChanged, strings.addGroupHint, onCreate)
+                        AddThreadedGroupContent(name.value, onNameChanged, strings.addGroupHint, onCreate)
                     },
                     bottomBar = {
                         OkCancelBottomBar(
@@ -133,7 +133,12 @@ private fun isValidGroupName(name: String, maxLength: Int) =
     name.isNotBlank() && !utf8IsTooLong(name, maxLength)
 
 @Composable
-fun AddGroupContent(name: String, onNameChanged: (String) -> Unit, description: String, onCreate: (String) -> Unit) {
+private fun AddThreadedGroupContent(
+    name: String,
+    onNameChanged: (String) -> Unit,
+    description: String,
+    onCreate: (String) -> Unit,
+) {
     val focusRequester = remember { FocusRequester() }
     OutlinedTextField(
         value = name,
@@ -156,7 +161,7 @@ fun AddGroupContent(name: String, onNameChanged: (String) -> Unit, description:
 }
 
 @Composable
-fun OkCancelBottomBar(
+private fun OkCancelBottomBar(
     okButtonLabel: String,
     okButtonEnabled: Boolean = true,
     onOkButtonClicked: () -> Unit,
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupCircle.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupCircle.kt
similarity index 93%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupCircle.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupCircle.kt
index 599dd6770f07a8a5b5cba35ca0d271b835896642..3c0f3ad0c4400994450a8ade3b575940a5f27cb7 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupCircle.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupCircle.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group
+package org.briarproject.briar.desktop.threadedgroup
 
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
@@ -39,7 +39,7 @@ import org.briarproject.briar.desktop.theme.outline
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.locale
 
 @Composable
-fun GroupCircle(item: GroupItem, modifier: Modifier = Modifier) {
+fun ThreadedGroupCircle(item: ThreadedGroupItem, modifier: Modifier = Modifier) {
     Box(
         contentAlignment = Center,
         modifier = modifier
@@ -63,7 +63,7 @@ fun GroupCircle(item: GroupItem, modifier: Modifier = Modifier) {
     }
 }
 
-fun GroupId.getBackgroundColor(): Color {
+private fun GroupId.getBackgroundColor(): Color {
     return Color(
         red = bytes.getByte(0) * 3 / 4 + 96,
         green = bytes.getByte(1) * 3 / 4 + 96,
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupItem.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupItem.kt
similarity index 91%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupItem.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupItem.kt
index 588cc76afef22212010a6a4a64bb4ec414fcad00..2ec955692abcd4732dcbc7e152555705c35da601 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupItem.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupItem.kt
@@ -16,11 +16,11 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group
+package org.briarproject.briar.desktop.threadedgroup
 
 import org.briarproject.bramble.api.sync.GroupId
 
-interface GroupItem {
+interface ThreadedGroupItem {
     val id: GroupId
     val name: String
     val msgCount: Int
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupItemView.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupItemView.kt
similarity index 81%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupItemView.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupItemView.kt
index fff90eb904ab27bc73aebb68f380cad08e2ad205..d4fdc7cba4bf54ed94a417c2bb600a54e6ce7523 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupItemView.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupItemView.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group
+package org.briarproject.briar.desktop.threadedgroup
 
 import androidx.compose.foundation.layout.Arrangement.SpaceBetween
 import androidx.compose.foundation.layout.Arrangement.spacedBy
@@ -43,7 +43,7 @@ import androidx.compose.ui.semantics.text
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
 import org.briarproject.bramble.api.sync.GroupId
-import org.briarproject.briar.desktop.forums.ForumStrings
+import org.briarproject.briar.desktop.forum.ForumStrings
 import org.briarproject.briar.desktop.ui.NumberBadge
 import org.briarproject.briar.desktop.utils.PreviewUtils.preview
 import org.briarproject.briar.desktop.utils.TimeUtils.getFormattedTimestamp
@@ -58,20 +58,20 @@ fun main() = preview(
     "unread" to 23,
     "timestamp" to Instant.now().toEpochMilli(),
 ) {
-    val item = object : GroupItem {
+    val item = object : ThreadedGroupItem {
         override val id: GroupId = GroupId(getRandomIdPersistent())
         override val name: String = getStringParameter("name")
         override val msgCount: Int = getIntParameter("msgCount")
         override val unread: Int = getIntParameter("unread")
         override val timestamp: Long = getLongParameter("timestamp")
     }
-    GroupItemView(ForumStrings, item)
+    ThreadedGroupItemView(ForumStrings, item)
 }
 
 @Composable
-fun GroupItemView(
-    strings: GroupStrings,
-    groupItem: GroupItem,
+fun ThreadedGroupItemView(
+    strings: ThreadedGroupStrings,
+    threadedGroupItem: ThreadedGroupItem,
     modifier: Modifier = Modifier,
 ) = Row(
     horizontalArrangement = spacedBy(12.dp),
@@ -80,20 +80,20 @@ fun GroupItemView(
         // allows content to be bottom-aligned
         .height(IntrinsicSize.Min)
         .semantics {
-            text = getDescription(strings, groupItem)
+            text = getDescription(strings, threadedGroupItem)
         },
 ) {
     Box(Modifier.align(Top).padding(vertical = 8.dp)) {
-        GroupCircle(groupItem)
+        ThreadedGroupCircle(threadedGroupItem)
         NumberBadge(
-            num = groupItem.unread,
+            num = threadedGroupItem.unread,
             modifier = Modifier.align(TopEnd).offset(6.dp, (-6).dp)
         )
     }
-    GroupItemViewInfo(strings, groupItem)
+    ThreadedGroupItemViewInfo(strings, threadedGroupItem)
 }
 
-private fun getDescription(strings: GroupStrings, item: GroupItem) = buildBlankAnnotatedString {
+private fun getDescription(strings: ThreadedGroupStrings, item: ThreadedGroupItem) = buildBlankAnnotatedString {
     append(item.name)
     if (item.unread > 0) appendCommaSeparated(strings.unreadCount(item.unread))
     appendCommaSeparated(strings.messageCount(item.msgCount))
@@ -101,12 +101,12 @@ private fun getDescription(strings: GroupStrings, item: GroupItem) = buildBlankA
 }
 
 @Composable
-private fun GroupItemViewInfo(strings: GroupStrings, groupItem: GroupItem) = Column(
+private fun ThreadedGroupItemViewInfo(strings: ThreadedGroupStrings, threadedGroupItem: ThreadedGroupItem) = Column(
     horizontalAlignment = Start,
 ) {
     Spacer(Modifier.weight(1f, fill = true))
     Text(
-        text = groupItem.name,
+        text = threadedGroupItem.name,
         style = MaterialTheme.typography.body1,
         maxLines = 3,
         overflow = TextOverflow.Ellipsis,
@@ -117,12 +117,12 @@ private fun GroupItemViewInfo(strings: GroupStrings, groupItem: GroupItem) = Col
         modifier = Modifier.fillMaxWidth()
     ) {
         Text(
-            text = strings.messageCount(groupItem.msgCount),
+            text = strings.messageCount(threadedGroupItem.msgCount),
             style = MaterialTheme.typography.caption
         )
-        if (groupItem.msgCount > 0) {
+        if (threadedGroupItem.msgCount > 0) {
             Text(
-                text = getFormattedTimestamp(groupItem.timestamp),
+                text = getFormattedTimestamp(threadedGroupItem.timestamp),
                 style = MaterialTheme.typography.caption
             )
         }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupList.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupList.kt
similarity index 90%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupList.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupList.kt
index bd766693819caae16eb7d6bba671e69d1b530a56..2da3f31ce4e2ae3859004daf635dbfb59269dc2d 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupList.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupList.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group
+package org.briarproject.briar.desktop.threadedgroup
 
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Column
@@ -41,7 +41,7 @@ import androidx.compose.ui.semantics.contentDescription
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.dp
 import org.briarproject.bramble.api.sync.GroupId
-import org.briarproject.briar.desktop.forums.ForumStrings
+import org.briarproject.briar.desktop.forum.ForumStrings
 import org.briarproject.briar.desktop.theme.surfaceVariant
 import org.briarproject.briar.desktop.ui.Constants.COLUMN_WIDTH
 import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE
@@ -55,7 +55,7 @@ import java.time.Instant
 fun main() = preview {
     val list = remember {
         listOf(
-            object : GroupItem {
+            object : ThreadedGroupItem {
                 override val id: GroupId = GroupId(getRandomId())
                 override val name: String =
                     "This is a test forum! This is a test forum! This is a test forum! This is a test forum!"
@@ -63,14 +63,14 @@ fun main() = preview {
                 override val unread: Int = 23
                 override val timestamp: Long = (Instant.now().minusSeconds(300)).toEpochMilli()
             },
-            object : GroupItem {
+            object : ThreadedGroupItem {
                 override val id: GroupId = GroupId(getRandomId())
                 override val name: String = "Newly added forum"
                 override val msgCount: Int = 0
                 override val unread: Int = 0
                 override val timestamp: Long = (Instant.now()).toEpochMilli()
             },
-            object : GroupItem {
+            object : ThreadedGroupItem {
                 override val id: GroupId = GroupId(getRandomId())
                 override val name: String = "Old forum"
                 override val msgCount: Int = 123
@@ -80,7 +80,7 @@ fun main() = preview {
         )
     }
 
-    val (selected, setSelected) = remember { mutableStateOf<GroupItem?>(null) }
+    val (selected, setSelected) = remember { mutableStateOf<ThreadedGroupItem?>(null) }
     val (filterBy, setFilterBy) = remember { mutableStateOf("") }
 
     val filteredList = remember(filterBy) {
@@ -89,7 +89,7 @@ fun main() = preview {
         }.sortedByDescending { it.timestamp }
     }
 
-    GroupList(
+    ThreadedGroupList(
         strings = ForumStrings,
         list = filteredList,
         isSelected = { selected?.id == it },
@@ -101,13 +101,13 @@ fun main() = preview {
 }
 
 @Composable
-fun GroupList(
-    strings: GroupStrings,
-    list: List<GroupItem>,
+fun ThreadedGroupList(
+    strings: ThreadedGroupStrings,
+    list: List<ThreadedGroupItem>,
     isSelected: (GroupId) -> Boolean,
     filterBy: String,
     onFilterSet: (String) -> Unit,
-    onGroupItemSelected: (GroupItem) -> Unit,
+    onGroupItemSelected: (ThreadedGroupItem) -> Unit,
     onAddButtonClicked: () -> Unit,
 ) = Column(
     modifier = Modifier.fillMaxHeight().width(COLUMN_WIDTH).background(MaterialTheme.colors.surfaceVariant),
@@ -143,9 +143,9 @@ fun GroupList(
                     // let divider start at horizontal position of text
                     dividerOffsetFromStart = (16 + 36 + 12).dp,
                 ) {
-                    GroupItemView(
+                    ThreadedGroupItemView(
                         strings = strings,
-                        groupItem = item,
+                        threadedGroupItem = item,
                         modifier = Modifier
                             .heightIn(min = HEADER_SIZE)
                             .fillMaxWidth()
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupListViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupListViewModel.kt
similarity index 90%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupListViewModel.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupListViewModel.kt
index 906a7c8ad7b592dd8807cb29b3bb7dc807090ec9..e404bee0fe59b1aa4174a6adf2e9ba28b7088ee8 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupListViewModel.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupListViewModel.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group
+package org.briarproject.briar.desktop.threadedgroup
 
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.mutableStateOf
@@ -32,13 +32,13 @@ 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.client.PostHeader
-import org.briarproject.briar.desktop.group.conversation.ThreadedConversationViewModel
+import org.briarproject.briar.desktop.threadedgroup.conversation.ThreadedConversationViewModel
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.utils.clearAndAddAll
 import org.briarproject.briar.desktop.viewmodel.EventListenerDbViewModel
 import org.briarproject.briar.desktop.viewmodel.asState
 
-abstract class GroupListViewModel<T : GroupItem>(
+abstract class ThreadedGroupListViewModel<T : ThreadedGroupItem>(
     val threadViewModel: ThreadedConversationViewModel,
     briarExecutors: BriarExecutors,
     lifecycleManager: LifecycleManager,
@@ -127,10 +127,10 @@ abstract class GroupListViewModel<T : GroupItem>(
 
     protected abstract fun addOwnMessage(header: PostHeader)
 
-    fun selectGroup(groupItem: GroupItem) {
-        if (_selectedGroupId.value == groupItem.id) return
-        _selectedGroupId.value = groupItem.id
-        threadViewModel.setGroupItem(groupItem, this::addOwnMessage)
+    fun selectGroup(threadedGroupItem: ThreadedGroupItem) {
+        if (_selectedGroupId.value == threadedGroupItem.id) return
+        _selectedGroupId.value = threadedGroupItem.id
+        threadViewModel.setGroupItem(threadedGroupItem, this::addOwnMessage)
     }
 
     fun isSelected(groupId: GroupId) = _selectedGroupId.value == groupId
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupScreen.kt
similarity index 77%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupScreen.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupScreen.kt
index 53c37dc6dd4b9d72df8499fbded6ff48e3aeddad..2c5676181e042ed8594f44ffef1c673ebceb0b93 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupScreen.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group
+package org.briarproject.briar.desktop.threadedgroup
 
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
@@ -32,20 +32,20 @@ import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import org.briarproject.briar.desktop.conversation.Explainer
-import org.briarproject.briar.desktop.group.conversation.GroupConversationScreen
-import org.briarproject.briar.desktop.group.conversation.GroupDropdownMenu
+import org.briarproject.briar.desktop.threadedgroup.conversation.ThreadedGroupConversationScreen
+import org.briarproject.briar.desktop.threadedgroup.conversation.ThreadedGroupDropdownMenu
 import org.briarproject.briar.desktop.ui.ColoredIconButton
 import org.briarproject.briar.desktop.ui.VerticalDivider
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 
 @Composable
-fun <T : GroupItem> GroupScreen(
-    strings: GroupStrings,
-    viewModel: GroupListViewModel<T>,
-    dropdownMenu: GroupDropdownMenu,
+fun <T : ThreadedGroupItem> ThreadedGroupScreen(
+    strings: ThreadedGroupStrings,
+    viewModel: ThreadedGroupListViewModel<T>,
+    dropdownMenu: ThreadedGroupDropdownMenu,
 ) {
     var addDialogVisible by remember { mutableStateOf(false) }
-    AddGroupDialog(
+    AddThreadedGroupDialog(
         strings = strings,
         visible = addDialogVisible,
         onCreate = { name ->
@@ -56,10 +56,10 @@ fun <T : GroupItem> GroupScreen(
     )
 
     if (viewModel.noGroupsYet.value) {
-        NoGroupsYet(strings) { addDialogVisible = true }
+        NoThreadedGroupsYet(strings) { addDialogVisible = true }
     } else {
         Row(modifier = Modifier.fillMaxWidth()) {
-            GroupList(
+            ThreadedGroupList(
                 strings = strings,
                 list = viewModel.list.value,
                 isSelected = viewModel::isSelected,
@@ -71,9 +71,9 @@ fun <T : GroupItem> GroupScreen(
             VerticalDivider()
             Column(modifier = Modifier.weight(1f).fillMaxHeight()) {
                 if (viewModel.selectedGroupId.value == null) {
-                    NoGroupSelected(strings)
+                    NoThreadedGroupSelected(strings)
                 } else {
-                    GroupConversationScreen(strings, viewModel.threadViewModel, dropdownMenu)
+                    ThreadedGroupConversationScreen(strings, viewModel.threadViewModel, dropdownMenu)
                 }
             }
         }
@@ -81,7 +81,7 @@ fun <T : GroupItem> GroupScreen(
 }
 
 @Composable
-fun NoGroupsYet(strings: GroupStrings, onAdd: () -> Unit) = Explainer(
+private fun NoThreadedGroupsYet(strings: ThreadedGroupStrings, onAdd: () -> Unit) = Explainer(
     headline = i18n("welcome.title"),
     text = strings.noGroupsYet,
 ) {
@@ -94,7 +94,7 @@ fun NoGroupsYet(strings: GroupStrings, onAdd: () -> Unit) = Explainer(
 }
 
 @Composable
-fun NoGroupSelected(strings: GroupStrings) = Explainer(
+private fun NoThreadedGroupSelected(strings: ThreadedGroupStrings) = Explainer(
     headline = strings.noGroupSelectedTitle,
     text = strings.noGroupSelectedText,
 )
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupStrings.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupStrings.kt
similarity index 94%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupStrings.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupStrings.kt
index 1f10a448251a7f946006e4610d8e394d609ee4eb..f1cec8e35dcd953d78ed91dd09e726e8333517c8 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupStrings.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/ThreadedGroupStrings.kt
@@ -16,9 +16,9 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group
+package org.briarproject.briar.desktop.threadedgroup
 
-abstract class GroupStrings(
+abstract class ThreadedGroupStrings(
     val listTitle: String,
     val listDescription: String,
     val addGroupTitle: String,
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadItem.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadItem.kt
similarity index 97%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadItem.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadItem.kt
index 7ad139c531ced2618b368f0d201d405a4ba9a1dd..84561397683ac0dd2123339e1a761f71dc0ddd45 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadItem.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadItem.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group.conversation
+package org.briarproject.briar.desktop.threadedgroup.conversation
 
 import org.briarproject.bramble.api.identity.Author
 import org.briarproject.bramble.api.sync.MessageId
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadItemView.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadItemView.kt
similarity index 98%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadItemView.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadItemView.kt
index ac4e489a5ce9d8afdeda07da038a545026c4f7d3..64cc1ec225e0b2ee8ca12e0b909308266c98cd94 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadItemView.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadItemView.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group.conversation
+package org.briarproject.briar.desktop.threadedgroup.conversation
 
 import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.foundation.ExperimentalFoundationApi
@@ -53,7 +53,7 @@ import androidx.compose.ui.text.style.TextOverflow
 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.forums.conversation.ForumPostItem
+import org.briarproject.briar.desktop.forum.conversation.ForumPostItem
 import org.briarproject.briar.desktop.theme.Blue500
 import org.briarproject.briar.desktop.theme.divider
 import org.briarproject.briar.desktop.ui.Constants.COLUMN_WIDTH
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadedConversationViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedConversationViewModel.kt
similarity index 85%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadedConversationViewModel.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedConversationViewModel.kt
index f96815a40c8f1f17b820f9fb0abef46e4ac18e34..b14b6456b4f761b9a586e09bd2442017b008c91a 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadedConversationViewModel.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedConversationViewModel.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group.conversation
+package org.briarproject.briar.desktop.threadedgroup.conversation
 
 import androidx.compose.runtime.mutableStateOf
 import kotlinx.coroutines.Job
@@ -29,9 +29,9 @@ import org.briarproject.bramble.api.sync.GroupId
 import org.briarproject.bramble.api.sync.MessageId
 import org.briarproject.briar.api.client.PostHeader
 import org.briarproject.briar.client.MessageTreeImpl
-import org.briarproject.briar.desktop.forums.ForumPostReadEvent
-import org.briarproject.briar.desktop.forums.sharing.ForumSharingViewModel
-import org.briarproject.briar.desktop.group.GroupItem
+import org.briarproject.briar.desktop.forum.ForumPostReadEvent
+import org.briarproject.briar.desktop.forum.sharing.ForumSharingViewModel
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupItem
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.threading.UiExecutor
 import org.briarproject.briar.desktop.viewmodel.EventListenerDbViewModel
@@ -45,24 +45,24 @@ abstract class ThreadedConversationViewModel(
     private val eventBus: EventBus,
 ) : EventListenerDbViewModel(briarExecutors, lifecycleManager, db, eventBus) {
 
-    private val _groupItem = mutableStateOf<GroupItem?>(null)
-    val groupItem = _groupItem.asState()
+    private val _threadedGroupItem = mutableStateOf<ThreadedGroupItem?>(null)
+    val groupItem = _threadedGroupItem.asState()
 
     protected lateinit var onThreadItemLocallyAdded: (header: PostHeader) -> Unit
 
-    private val _state = mutableStateOf<ThreadedConversationScreenState>(Loading)
+    private val _state = mutableStateOf<ThreadedGroupConversationScreenState>(Loading)
     val state = _state.asState()
 
     private val _selectedThreadItem = mutableStateOf<ThreadItem?>(null)
     val selectedThreadItem = _selectedThreadItem.asState()
 
     @UiExecutor
-    fun setGroupItem(groupItem: GroupItem, onThreadItemLocallyAdded: (header: PostHeader) -> Unit) {
+    fun setGroupItem(threadedGroupItem: ThreadedGroupItem, onThreadItemLocallyAdded: (header: PostHeader) -> Unit) {
         this.onThreadItemLocallyAdded = onThreadItemLocallyAdded
-        _groupItem.value = groupItem
+        _threadedGroupItem.value = threadedGroupItem
         _selectedThreadItem.value = null
-        forumSharingViewModel.setGroupId(groupItem.id)
-        loadThreadItems(groupItem.id)
+        forumSharingViewModel.setGroupId(threadedGroupItem.id)
+        loadThreadItems(threadedGroupItem.id)
     }
 
     override fun onInit() {
@@ -119,7 +119,7 @@ abstract class ThreadedConversationViewModel(
             item.id
         } ?: emptyList()
 
-        val groupId = _groupItem.value?.id
+        val groupId = _threadedGroupItem.value?.id
         if (readIds.isNotEmpty() && groupId != null) {
             runOnDbThread {
                 readIds.forEach { id ->
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadedConversationScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationContent.kt
similarity index 93%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadedConversationScreen.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationContent.kt
index d1fc5090fadfc820cde9320fe9946fcdca95764f..5b2998eeaa085119297db0f20376e46ad5679ac2 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadedConversationScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationContent.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group.conversation
+package org.briarproject.briar.desktop.threadedgroup.conversation
 
 import androidx.compose.foundation.VerticalScrollbar
 import androidx.compose.foundation.layout.Box
@@ -36,14 +36,14 @@ import androidx.compose.ui.unit.dp
 import kotlinx.coroutines.delay
 import org.briarproject.bramble.api.sync.MessageId
 import org.briarproject.briar.desktop.conversation.reallyVisibleItemsInfo
-import org.briarproject.briar.desktop.group.GroupStrings
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupStrings
 import org.briarproject.briar.desktop.ui.Loader
 import org.briarproject.briar.desktop.ui.isWindowFocused
 
 @Composable
-fun ThreadedConversationScreen(
-    strings: GroupStrings,
-    state: ThreadedConversationScreenState,
+fun ThreadedGroupConversationContent(
+    strings: ThreadedGroupStrings,
+    state: ThreadedGroupConversationScreenState,
     selectedThreadItem: ThreadItem?,
     onThreadItemSelected: (ThreadItem) -> Unit,
     onThreadItemsVisible: (List<MessageId>) -> Unit,
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadedConversationInput.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationInput.kt
similarity index 96%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadedConversationInput.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationInput.kt
index 91b1b2d2cd4f575eaf1e86fc006c324f5932e5de..89b77665cb5f6c0d40571853fca21bf753ca2a0c 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadedConversationInput.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationInput.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group.conversation
+package org.briarproject.briar.desktop.threadedgroup.conversation
 
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
@@ -45,17 +45,17 @@ import androidx.compose.ui.input.pointer.PointerIconDefaults
 import androidx.compose.ui.input.pointer.pointerHoverIcon
 import androidx.compose.ui.unit.dp
 import org.briarproject.bramble.util.StringUtils.utf8IsTooLong
-import org.briarproject.briar.desktop.group.GroupStrings
 import org.briarproject.briar.desktop.theme.divider
 import org.briarproject.briar.desktop.theme.sendButton
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupStrings
 import org.briarproject.briar.desktop.ui.HorizontalDivider
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.StringUtils.takeUtf8
 
 @Composable
 @OptIn(ExperimentalComposeUiApi::class)
-fun ThreadedConversationInput(
-    strings: GroupStrings,
+fun ThreadedGroupConversationInput(
+    strings: ThreadedGroupStrings,
     selectedThreadItem: ThreadItem?,
     onReplyClosed: () -> Unit,
     onSend: (String) -> Unit,
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/GroupConversationScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationScreen.kt
similarity index 85%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/GroupConversationScreen.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationScreen.kt
index 6e19d0db8248ab3ef762f67ca3de559df130b2c1..6f5422be11a6939e0339b1d395b745d6da05d56a 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/GroupConversationScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationScreen.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group.conversation
+package org.briarproject.briar.desktop.threadedgroup.conversation
 
 import androidx.compose.foundation.layout.Arrangement.SpaceBetween
 import androidx.compose.foundation.layout.Arrangement.spacedBy
@@ -51,26 +51,26 @@ import androidx.compose.ui.text.style.TextOverflow.Companion.Ellipsis
 import androidx.compose.ui.unit.dp
 import org.briarproject.briar.desktop.contact.ContactDropDown.State.CLOSED
 import org.briarproject.briar.desktop.contact.ContactDropDown.State.MAIN
-import org.briarproject.briar.desktop.forums.sharing.ForumSharingViewModel
-import org.briarproject.briar.desktop.group.GroupCircle
-import org.briarproject.briar.desktop.group.GroupItem
-import org.briarproject.briar.desktop.group.GroupStrings
+import org.briarproject.briar.desktop.forum.sharing.ForumSharingViewModel
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupCircle
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupItem
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupStrings
 import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE
 import org.briarproject.briar.desktop.ui.HorizontalDivider
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 
 @Composable
-fun GroupConversationScreen(
-    strings: GroupStrings,
+fun ThreadedGroupConversationScreen(
+    strings: ThreadedGroupStrings,
     viewModel: ThreadedConversationViewModel,
-    dropdownMenu: GroupDropdownMenu,
+    dropdownMenu: ThreadedGroupDropdownMenu,
 ) {
     Scaffold(
         topBar = {
             viewModel.groupItem.value?.let { groupItem ->
-                GroupConversationHeader(
+                ThreadedGroupConversationHeader(
                     strings = strings,
-                    groupItem = groupItem,
+                    threadedGroupItem = groupItem,
                     forumSharingViewModel = viewModel.forumSharingViewModel,
                     onGroupDelete = viewModel::deleteGroup,
                     dropdownMenu = dropdownMenu,
@@ -78,7 +78,7 @@ fun GroupConversationScreen(
             }
         },
         content = { padding ->
-            ThreadedConversationScreen(
+            ThreadedGroupConversationContent(
                 strings = strings,
                 state = viewModel.state.value,
                 selectedThreadItem = viewModel.selectedThreadItem.value,
@@ -89,7 +89,7 @@ fun GroupConversationScreen(
         },
         bottomBar = {
             val onCloseReply = { viewModel.selectThreadItem(null) }
-            ThreadedConversationInput(strings, viewModel.selectedThreadItem.value, onCloseReply) { text ->
+            ThreadedGroupConversationInput(strings, viewModel.selectedThreadItem.value, onCloseReply) { text ->
                 viewModel.createThreadItem(text)
             }
         }
@@ -97,12 +97,12 @@ fun GroupConversationScreen(
 }
 
 @Composable
-private fun GroupConversationHeader(
-    strings: GroupStrings,
-    groupItem: GroupItem,
+private fun ThreadedGroupConversationHeader(
+    strings: ThreadedGroupStrings,
+    threadedGroupItem: ThreadedGroupItem,
     forumSharingViewModel: ForumSharingViewModel,
     onGroupDelete: () -> Unit,
-    dropdownMenu: GroupDropdownMenu,
+    dropdownMenu: ThreadedGroupDropdownMenu,
 ) {
     val deleteGroupDialogVisible = remember { mutableStateOf(false) }
     val menuState = remember { mutableStateOf(CLOSED) }
@@ -120,11 +120,11 @@ private fun GroupConversationHeader(
                 horizontalArrangement = spacedBy(12.dp),
                 verticalAlignment = CenterVertically
             ) {
-                GroupCircle(groupItem)
+                ThreadedGroupCircle(threadedGroupItem)
                 Column {
                     Text(
                         modifier = Modifier,
-                        text = groupItem.name,
+                        text = threadedGroupItem.name,
                         maxLines = 2,
                         overflow = Ellipsis,
                         style = MaterialTheme.typography.h2,
@@ -151,7 +151,7 @@ private fun GroupConversationHeader(
         HorizontalDivider(modifier = Modifier.align(BottomCenter))
     }
     if (deleteGroupDialogVisible.value) {
-        DeleteGroupDialog(
+        DeleteThreadedGroupDialog(
             strings = strings,
             close = { deleteGroupDialogVisible.value = false },
             onDelete = onGroupDelete,
@@ -161,8 +161,8 @@ private fun GroupConversationHeader(
 
 @Composable
 @OptIn(ExperimentalMaterialApi::class)
-private fun DeleteGroupDialog(
-    strings: GroupStrings,
+private fun DeleteThreadedGroupDialog(
+    strings: ThreadedGroupStrings,
     close: () -> Unit,
     onDelete: () -> Unit = {},
 ) {
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadedConversationScreenState.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationScreenState.kt
similarity index 90%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadedConversationScreenState.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationScreenState.kt
index 1f2f870a7b0693af5f5eb1885206f0d552685c19..26da505ae64c6b748cb972de1e034f4b8d2dde2c 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadedConversationScreenState.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupConversationScreenState.kt
@@ -16,18 +16,18 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group.conversation
+package org.briarproject.briar.desktop.threadedgroup.conversation
 
 import org.briarproject.bramble.api.sync.MessageId
 import org.briarproject.briar.client.MessageTreeImpl
 import org.briarproject.briar.desktop.threading.UiExecutor
 
-sealed class ThreadedConversationScreenState
-object Loading : ThreadedConversationScreenState()
+sealed class ThreadedGroupConversationScreenState
+object Loading : ThreadedGroupConversationScreenState()
 class Loaded(
     val messageTree: MessageTreeImpl<ThreadItem>,
     val scrollTo: MessageId? = null,
-) : ThreadedConversationScreenState() {
+) : ThreadedGroupConversationScreenState() {
     val posts: List<ThreadItem> = messageTree.depthFirstOrder()
 
     @UiExecutor
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/GroupDropdownMenu.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupDropdownMenu.kt
similarity index 82%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/GroupDropdownMenu.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupDropdownMenu.kt
index 9f184527732e3b01c42b0250d50e96371ac89ecb..0e567fc9f54fecdb1eff73c1a93cf7ffbfcb3eed 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/GroupDropdownMenu.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/ThreadedGroupDropdownMenu.kt
@@ -16,12 +16,12 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group.conversation
+package org.briarproject.briar.desktop.threadedgroup.conversation
 
 import androidx.compose.runtime.Composable
-import org.briarproject.briar.desktop.forums.sharing.ForumSharingViewModel
+import org.briarproject.briar.desktop.forum.sharing.ForumSharingViewModel
 
-typealias GroupDropdownMenu = @Composable (
+typealias ThreadedGroupDropdownMenu = @Composable (
     forumSharingViewModel: ForumSharingViewModel,
     expanded: Boolean,
     onClose: () -> Unit,
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/UnreadFabs.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/UnreadFabs.kt
similarity index 95%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/UnreadFabs.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/UnreadFabs.kt
index b3e1dc37100c10a3ab420e8f87033adb78f6d810..0f006388eb1d1962f0689e601415eeca5012dbc6 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/UnreadFabs.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/threadedgroup/conversation/UnreadFabs.kt
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.group.conversation
+package org.briarproject.briar.desktop.threadedgroup.conversation
 
 import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.foundation.layout.Box
@@ -38,13 +38,13 @@ import androidx.compose.ui.unit.dp
 import kotlinx.coroutines.launch
 import org.briarproject.briar.desktop.conversation.firstReallyVisibleItemIndex
 import org.briarproject.briar.desktop.conversation.lastReallyVisibleItemIndex
-import org.briarproject.briar.desktop.group.GroupStrings
 import org.briarproject.briar.desktop.theme.ChevronDown
 import org.briarproject.briar.desktop.theme.ChevronUp
+import org.briarproject.briar.desktop.threadedgroup.ThreadedGroupStrings
 import org.briarproject.briar.desktop.ui.NumberBadge
 
 @Composable
-fun BoxScope.UnreadFabs(strings: GroupStrings, scrollState: LazyListState, postsState: Loaded) {
+fun BoxScope.UnreadFabs(strings: ThreadedGroupStrings, scrollState: LazyListState, postsState: Loaded) {
     val coroutineScope = rememberCoroutineScope()
 
     // remember first really visible item index based on scroll offset
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MainScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MainScreen.kt
index bd2ca81b882aa52bc4d6bc7d5a268a139b25f8e7..b1b37c56c4631f7de11b4caab5546c5193a2f7db 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MainScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MainScreen.kt
@@ -28,7 +28,7 @@ import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.runtime.staticCompositionLocalOf
 import org.briarproject.briar.desktop.conversation.PrivateMessageScreen
-import org.briarproject.briar.desktop.forums.ForumScreen
+import org.briarproject.briar.desktop.forum.ForumScreen
 import org.briarproject.briar.desktop.mailbox.MailboxScreen
 import org.briarproject.briar.desktop.navigation.BriarSidebar
 import org.briarproject.briar.desktop.navigation.SidebarViewModel
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounterImpl.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounterImpl.kt
index fb386620413810738348a26c00b4663616d7561d..876ec358b2db63676de624f4044cf960daf203a5 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounterImpl.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MessageCounterImpl.kt
@@ -33,7 +33,7 @@ import org.briarproject.briar.api.conversation.event.ConversationMessageReceived
 import org.briarproject.briar.api.forum.ForumManager
 import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent
 import org.briarproject.briar.desktop.conversation.ConversationMessagesReadEvent
-import org.briarproject.briar.desktop.forums.ForumPostReadEvent
+import org.briarproject.briar.desktop.forum.ForumPostReadEvent
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.threading.UiExecutor
 import org.briarproject.briar.desktop.ui.MessageCounterDataType.Forum
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/ViewModelModule.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/ViewModelModule.kt
index f3f1c99d0781652372b6b41b6ce7c217ecf7de3b..244409ecf8fe86d49cca889a12887ae8b32c6876 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/ViewModelModule.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/ViewModelModule.kt
@@ -25,8 +25,8 @@ import dagger.multibindings.IntoMap
 import org.briarproject.briar.desktop.contact.ContactListViewModel
 import org.briarproject.briar.desktop.contact.add.remote.AddContactViewModel
 import org.briarproject.briar.desktop.conversation.ConversationViewModel
-import org.briarproject.briar.desktop.forums.ForumListViewModel
-import org.briarproject.briar.desktop.forums.sharing.ForumSharingViewModel
+import org.briarproject.briar.desktop.forum.ForumListViewModel
+import org.briarproject.briar.desktop.forum.sharing.ForumSharingViewModel
 import org.briarproject.briar.desktop.introduction.IntroductionViewModel
 import org.briarproject.briar.desktop.login.StartupViewModel
 import org.briarproject.briar.desktop.mailbox.MailboxViewModel