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/forums/ForumScreen.kt
index db4b9ebe2af099d6d9e068eaa8bc59e7366b8144..ffb232f1c051a435182aff6ef22a7d60c718b1de 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumScreen.kt
@@ -19,6 +19,7 @@
 package org.briarproject.briar.desktop.forums
 
 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.viewmodel.viewModel
 
@@ -28,5 +29,7 @@ fun ForumScreen(
 ) = GroupScreen(
     strings = ForumStrings,
     viewModel = viewModel,
-    conversationScreen = { GroupConversationScreen(viewModel.threadViewModel) }
+    dropdownMenu = { forumSharingViewModel, expanded, onClose, onLeaveForumClick ->
+        ForumDropdownMenu(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/forums/ForumStrings.kt
index aa8f947f0e7a6473d8672e25b691782316774672..401007e7de157bd241b64996be529648852dd0c6 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumStrings.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumStrings.kt
@@ -44,4 +44,10 @@ object ForumStrings : GroupStrings(
         i18nF("access.forums.last_post_timestamp", timestamp)
     },
     groupNameMaxLength = MAX_FORUM_NAME_LENGTH,
+    sharedWith = { total, online ->
+        i18nF("forum.sharing.status.with", total, online)
+    },
+    deleteDialogTitle = i18n("forum.delete.dialog.title"),
+    deleteDialogMessage = i18n("forum.delete.dialog.message"),
+    deleteDialogButton = i18n("forum.delete.dialog.button"),
 )
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/PostsState.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/PostsState.kt
index 67a4355bc158cd7e159178e033a1af820b41d871..d3fca2ceb66b1bff694b72a1951a09ad32a45ad2 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/PostsState.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/PostsState.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
@@ -20,6 +20,7 @@ package org.briarproject.briar.desktop.forums
 
 import org.briarproject.bramble.api.sync.MessageId
 import org.briarproject.briar.client.MessageTreeImpl
+import org.briarproject.briar.desktop.group.conversation.ThreadItem
 import org.briarproject.briar.desktop.threading.UiExecutor
 
 sealed class PostsState
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadedConversationScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadedConversationScreen.kt
index 6e80372562a7b3725697d34b1d816c19b28faac7..bb2e1db993adb516935d3edc665c5395c5000c0d 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadedConversationScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadedConversationScreen.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
@@ -36,6 +36,9 @@ 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.conversation.ThreadItem
+import org.briarproject.briar.desktop.group.conversation.ThreadItemView
+import org.briarproject.briar.desktop.group.conversation.getMaxNestingLevel
 import org.briarproject.briar.desktop.ui.Loader
 import org.briarproject.briar.desktop.ui.isWindowFocused
 
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadedConversationViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadedConversationViewModel.kt
index ba6c0cea348af62d2c990a3c32640665a76eb784..85168f8a8eabfcef4f5638faf001a29e371f35aa 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadedConversationViewModel.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadedConversationViewModel.kt
@@ -40,8 +40,10 @@ import org.briarproject.briar.api.forum.ForumManager
 import org.briarproject.briar.api.forum.ForumPostHeader
 import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent
 import org.briarproject.briar.client.MessageTreeImpl
+import org.briarproject.briar.desktop.forums.conversation.ForumPostItem
 import org.briarproject.briar.desktop.forums.sharing.ForumSharingViewModel
 import org.briarproject.briar.desktop.group.GroupItem
+import org.briarproject.briar.desktop.group.conversation.ThreadItem
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.threading.UiExecutor
 import org.briarproject.briar.desktop.viewmodel.EventListenerDbViewModel
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/forums/conversation/ForumDropdownMenu.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ae00c4015b60d930a071df6c13b813e221fb4aa9
--- /dev/null
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/conversation/ForumDropdownMenu.kt
@@ -0,0 +1,86 @@
+/*
+ * Briar Desktop
+ * Copyright (C) 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
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package org.briarproject.briar.desktop.forums.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.ui.getInfoDrawerHandler
+import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
+
+@Composable
+fun ForumDropdownMenu(
+    forumSharingViewModel: ForumSharingViewModel,
+    expanded: Boolean,
+    onClose: () -> Unit,
+    onLeaveForumClick: () -> Unit,
+) = DropdownMenu(
+    expanded = expanded,
+    onDismissRequest = onClose,
+) {
+    val infoDrawerHandler = getInfoDrawerHandler()
+    DropdownMenuItem(
+        onClick = {
+            onClose()
+            infoDrawerHandler.open {
+                ForumSharingActionDrawerContent(
+                    close = infoDrawerHandler::close,
+                    viewModel = forumSharingViewModel,
+                )
+            }
+        }
+    ) {
+        Text(
+            i18n("forum.sharing.action.title"),
+            style = MaterialTheme.typography.body2,
+        )
+    }
+    DropdownMenuItem(
+        onClick = {
+            onClose()
+            infoDrawerHandler.open {
+                ForumSharingStatusDrawerContent(
+                    close = infoDrawerHandler::close,
+                    viewModel = forumSharingViewModel,
+                )
+            }
+        }
+    ) {
+        Text(
+            i18n("forum.sharing.status.title"),
+            style = MaterialTheme.typography.body2,
+        )
+    }
+    DropdownMenuItem(
+        onClick = {
+            onClose()
+            onLeaveForumClick()
+        }
+    ) {
+        Text(
+            i18n("forum.leave.title"),
+            style = MaterialTheme.typography.body2,
+        )
+    }
+}
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/forums/conversation/ForumPostItem.kt
new file mode 100644
index 0000000000000000000000000000000000000000..5adc49791d7b96e50e95da2d3d14937184db3130
--- /dev/null
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/conversation/ForumPostItem.kt
@@ -0,0 +1,34 @@
+/*
+ * Briar Desktop
+ * Copyright (C) 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
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package org.briarproject.briar.desktop.forums.conversation
+
+import org.briarproject.briar.api.forum.ForumPostHeader
+import org.briarproject.briar.desktop.group.conversation.ThreadItem
+import javax.annotation.concurrent.NotThreadSafe
+
+@NotThreadSafe
+class ForumPostItem(h: ForumPostHeader, text: String?) : ThreadItem(
+    messageId = h.id,
+    parentId = h.parentId,
+    text = text ?: "",
+    timestamp = h.timestamp,
+    author = h.author,
+    authorInfo = h.authorInfo,
+    isRead = h.isRead
+)
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupInputComposable.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupInputComposable.kt
index 9d096aadfd5d9bc2ee363c8ade9533263c4d5341..cce4664f49d2d427545759a02f78fc21f889753f 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupInputComposable.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupInputComposable.kt
@@ -45,8 +45,8 @@ import androidx.compose.ui.input.pointer.PointerIconDefaults
 import androidx.compose.ui.input.pointer.pointerHoverIcon
 import androidx.compose.ui.unit.dp
 import org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_TEXT_LENGTH
-import org.briarproject.briar.desktop.forums.ThreadItem
-import org.briarproject.briar.desktop.forums.ThreadItemContentComposable
+import org.briarproject.briar.desktop.group.conversation.ThreadItem
+import org.briarproject.briar.desktop.group.conversation.ThreadItemContentComposable
 import org.briarproject.briar.desktop.theme.divider
 import org.briarproject.briar.desktop.theme.sendButton
 import org.briarproject.briar.desktop.ui.HorizontalDivider
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/group/GroupScreen.kt
index 3c1e7bfd6b21c79598848b250e4efc7cbb53cab2..53c37dc6dd4b9d72df8499fbded6ff48e3aeddad 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupScreen.kt
@@ -32,6 +32,8 @@ 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.ui.ColoredIconButton
 import org.briarproject.briar.desktop.ui.VerticalDivider
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
@@ -40,7 +42,7 @@ import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 fun <T : GroupItem> GroupScreen(
     strings: GroupStrings,
     viewModel: GroupListViewModel<T>,
-    conversationScreen: @Composable () -> Unit,
+    dropdownMenu: GroupDropdownMenu,
 ) {
     var addDialogVisible by remember { mutableStateOf(false) }
     AddGroupDialog(
@@ -71,7 +73,7 @@ fun <T : GroupItem> GroupScreen(
                 if (viewModel.selectedGroupId.value == null) {
                     NoGroupSelected(strings)
                 } else {
-                    conversationScreen()
+                    GroupConversationScreen(strings, viewModel.threadViewModel, dropdownMenu)
                 }
             }
         }
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/group/GroupStrings.kt
index 505d325ffd4021925f1c7afceda2614f9c8bc116..1c7a45f8bc8c62fd8f93f582d6c7950032b54807 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupStrings.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/GroupStrings.kt
@@ -31,4 +31,9 @@ abstract class GroupStrings(
     val unreadCount: (Int) -> String,
     val lastMessage: (String) -> String,
     val groupNameMaxLength: Int,
+    val sharedWith: (total: Int, online: Int) -> String,
+    // todo: will need to be different for private groups depending on creator or not
+    val deleteDialogTitle: String,
+    val deleteDialogMessage: String,
+    val deleteDialogButton: String,
 )
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/GroupConversationScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/GroupConversationScreen.kt
similarity index 70%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/GroupConversationScreen.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/GroupConversationScreen.kt
index 5392282bc61eff32dc83960d2e4d169f7d962139..e1e1c1fc5f9764cd714696b8fcd1a3556d10439f 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/GroupConversationScreen.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/GroupConversationScreen.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.group.conversation
 
 import androidx.compose.foundation.layout.Arrangement.SpaceBetween
 import androidx.compose.foundation.layout.Arrangement.spacedBy
@@ -33,8 +33,6 @@ import androidx.compose.material.AlertDialog
 import androidx.compose.material.ButtonType.DESTRUCTIVE
 import androidx.compose.material.ButtonType.NEUTRAL
 import androidx.compose.material.DialogButton
-import androidx.compose.material.DropdownMenu
-import androidx.compose.material.DropdownMenuItem
 import androidx.compose.material.ExperimentalMaterialApi
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
@@ -53,29 +51,32 @@ 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.ForumSharingActionDrawerContent
-import org.briarproject.briar.desktop.forums.sharing.ForumSharingStatusDrawerContent
+import org.briarproject.briar.desktop.forums.ThreadedConversationScreen
+import org.briarproject.briar.desktop.forums.ThreadedConversationViewModel
 import org.briarproject.briar.desktop.forums.sharing.ForumSharingViewModel
 import org.briarproject.briar.desktop.group.GroupCircle
 import org.briarproject.briar.desktop.group.GroupInputComposable
 import org.briarproject.briar.desktop.group.GroupItem
+import org.briarproject.briar.desktop.group.GroupStrings
 import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE
 import org.briarproject.briar.desktop.ui.HorizontalDivider
-import org.briarproject.briar.desktop.ui.getInfoDrawerHandler
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
-import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nF
 
 @Composable
 fun GroupConversationScreen(
+    strings: GroupStrings,
     viewModel: ThreadedConversationViewModel,
+    dropdownMenu: GroupDropdownMenu,
 ) {
     Scaffold(
         topBar = {
             viewModel.groupItem.value?.let { groupItem ->
                 GroupConversationHeader(
+                    strings = strings,
                     groupItem = groupItem,
                     forumSharingViewModel = viewModel.forumSharingViewModel,
                     onGroupDelete = viewModel::deleteGroup,
+                    dropdownMenu = dropdownMenu,
                 )
             }
         },
@@ -99,14 +100,15 @@ fun GroupConversationScreen(
 
 @Composable
 private fun GroupConversationHeader(
+    strings: GroupStrings,
     groupItem: GroupItem,
     forumSharingViewModel: ForumSharingViewModel,
     onGroupDelete: () -> Unit,
+    dropdownMenu: GroupDropdownMenu,
 ) {
     val deleteGroupDialogVisible = remember { mutableStateOf(false) }
     val menuState = remember { mutableStateOf(CLOSED) }
     val close = { menuState.value = CLOSED }
-    val infoDrawerHandler = getInfoDrawerHandler()
     Box(modifier = Modifier.fillMaxWidth().height(HEADER_SIZE + 1.dp)) {
         Row(
             horizontalArrangement = SpaceBetween,
@@ -131,7 +133,7 @@ private fun GroupConversationHeader(
                     )
                     val sharingInfo = forumSharingViewModel.sharingInfo.value
                     Text(
-                        text = i18nF("forum.sharing.status.with", sharingInfo.total, sharingInfo.online)
+                        text = strings.sharedWith(sharingInfo.total, sharingInfo.online)
                     )
                 }
             }
@@ -141,60 +143,18 @@ private fun GroupConversationHeader(
                 onClick = { menuState.value = MAIN },
                 modifier = Modifier.align(CenterVertically).padding(end = 16.dp),
             ) {
-                DropdownMenu(
-                    expanded = menuState.value == MAIN,
-                    onDismissRequest = close,
-                ) {
-                    DropdownMenuItem(
-                        onClick = {
-                            close()
-                            infoDrawerHandler.open {
-                                ForumSharingActionDrawerContent(
-                                    close = infoDrawerHandler::close,
-                                    viewModel = forumSharingViewModel,
-                                )
-                            }
-                        }
-                    ) {
-                        Text(
-                            i18n("forum.sharing.action.title"),
-                            style = MaterialTheme.typography.body2,
-                        )
-                    }
-                    DropdownMenuItem(
-                        onClick = {
-                            close()
-                            infoDrawerHandler.open {
-                                ForumSharingStatusDrawerContent(
-                                    close = infoDrawerHandler::close,
-                                    viewModel = forumSharingViewModel,
-                                )
-                            }
-                        }
-                    ) {
-                        Text(
-                            i18n("forum.sharing.status.title"),
-                            style = MaterialTheme.typography.body2,
-                        )
-                    }
-                    DropdownMenuItem(
-                        onClick = {
-                            close()
-                            deleteGroupDialogVisible.value = true
-                        }
-                    ) {
-                        Text(
-                            i18n("forum.leave.title"),
-                            style = MaterialTheme.typography.body2,
-                        )
-                    }
-                }
+                dropdownMenu(
+                    forumSharingViewModel,
+                    menuState.value == MAIN,
+                    close
+                ) { deleteGroupDialogVisible.value = true }
             }
         }
         HorizontalDivider(modifier = Modifier.align(BottomCenter))
     }
     if (deleteGroupDialogVisible.value) {
-        DeleteForumDialog(
+        DeleteGroupDialog(
+            strings = strings,
             close = { deleteGroupDialogVisible.value = false },
             onDelete = onGroupDelete,
         )
@@ -203,7 +163,8 @@ private fun GroupConversationHeader(
 
 @Composable
 @OptIn(ExperimentalMaterialApi::class)
-fun DeleteForumDialog(
+private fun DeleteGroupDialog(
+    strings: GroupStrings,
     close: () -> Unit,
     onDelete: () -> Unit = {},
 ) {
@@ -211,13 +172,13 @@ fun DeleteForumDialog(
         onDismissRequest = close,
         title = {
             Text(
-                text = i18n("forum.delete.dialog.title"),
+                text = strings.deleteDialogTitle,
                 modifier = Modifier.width(Max),
                 style = MaterialTheme.typography.h6,
             )
         },
         text = {
-            Text(i18n("forum.delete.dialog.message"))
+            Text(strings.deleteDialogMessage)
         },
         dismissButton = {
             DialogButton(
@@ -232,7 +193,7 @@ fun DeleteForumDialog(
                     close()
                     onDelete()
                 },
-                text = i18n("forum.delete.dialog.button"),
+                text = strings.deleteDialogButton,
                 type = DESTRUCTIVE,
             )
         },
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/group/conversation/GroupDropdownMenu.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9f184527732e3b01c42b0250d50e96371ac89ecb
--- /dev/null
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/GroupDropdownMenu.kt
@@ -0,0 +1,29 @@
+/*
+ * Briar Desktop
+ * Copyright (C) 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
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package org.briarproject.briar.desktop.group.conversation
+
+import androidx.compose.runtime.Composable
+import org.briarproject.briar.desktop.forums.sharing.ForumSharingViewModel
+
+typealias GroupDropdownMenu = @Composable (
+    forumSharingViewModel: ForumSharingViewModel,
+    expanded: Boolean,
+    onClose: () -> Unit,
+    onLeaveGroupClick: () -> Unit,
+) -> Unit
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadItem.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadItem.kt
similarity index 84%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadItem.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadItem.kt
index a751f18fbd566521e3bf639ab027539adf4b32bb..7ad139c531ced2618b368f0d201d405a4ba9a1dd 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadItem.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadItem.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,27 +16,15 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package org.briarproject.briar.desktop.forums
+package org.briarproject.briar.desktop.group.conversation
 
 import org.briarproject.bramble.api.identity.Author
 import org.briarproject.bramble.api.sync.MessageId
 import org.briarproject.briar.api.client.MessageTree
-import org.briarproject.briar.api.forum.ForumPostHeader
 import org.briarproject.briar.api.identity.AuthorInfo
 import org.briarproject.briar.desktop.utils.UiUtils.getContactDisplayName
 import javax.annotation.concurrent.NotThreadSafe
 
-@NotThreadSafe
-class ForumPostItem(h: ForumPostHeader, text: String?) : ThreadItem(
-    messageId = h.id,
-    parentId = h.parentId,
-    text = text ?: "",
-    timestamp = h.timestamp,
-    author = h.author,
-    authorInfo = h.authorInfo,
-    isRead = h.isRead
-)
-
 // TODO the mutable state here might need to be made immutable later
 //  and copy on data classes used to trigger recompositions when items update
 @NotThreadSafe
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadItemView.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadItemView.kt
similarity index 98%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadItemView.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadItemView.kt
index 45f057136858d6f693879b2a24c3bd7313016c17..ac4e489a5ce9d8afdeda07da038a545026c4f7d3 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ThreadItemView.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/group/conversation/ThreadItemView.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.group.conversation
 
 import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.foundation.ExperimentalFoundationApi
@@ -53,6 +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.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/privategroup/PrivateGroupScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/PrivateGroupScreen.kt
index eb8091a1186eec312d90ab37b9770cfcbe4c36c9..378ae583c4d0cab52b6efcc3da818c5d047696e5 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,8 +19,8 @@
 package org.briarproject.briar.desktop.privategroup
 
 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.ui.UiPlaceholder
 import org.briarproject.briar.desktop.viewmodel.viewModel
 
 @Composable
@@ -29,5 +29,7 @@ fun PrivateGroupScreen(
 ) = GroupScreen(
     strings = PrivateGroupStrings,
     viewModel = viewModel,
-    conversationScreen = { UiPlaceholder() }
+    dropdownMenu = { forumSharingViewModel, expanded, onClose, onLeaveForumClick ->
+        ForumDropdownMenu(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 d0ca2055c8eb3f88b1025105337a2ed6257f38b7..6d8415f83943b187e45afaab13e332892ae321fc 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
@@ -45,4 +45,10 @@ object PrivateGroupStrings : GroupStrings(
         i18nF("access.forums.last_post_timestamp", timestamp)
     },
     groupNameMaxLength = MAX_GROUP_NAME_LENGTH,
+    sharedWith = { total, online ->
+        i18nF("forum.sharing.status.with", total, online)
+    },
+    deleteDialogTitle = i18n("forum.delete.dialog.title"),
+    deleteDialogMessage = i18n("forum.delete.dialog.message"),
+    deleteDialogButton = i18n("forum.delete.dialog.button"),
 )