From 308a28c07306898ce9524245570dcc55669dc786 Mon Sep 17 00:00:00 2001 From: Kgothatso Ngako Date: Sun, 26 Jul 2026 00:57:53 +0200 Subject: [PATCH] List locally stored artifacts on the ChatRoomDetailScreen The Library section hardcoded "No artifacts exists". Load and render the chat room's stored artifacts instead. - MantraArtifactDao.getArtifactsByChatRoomId + MantraRepository.getArtifacts expose a chat room's artifacts (newest first). - ChatRoomDetailUIState.Loaded carries artifacts; ChatRoomDetailViewModel gains mantraRepository and loads them in initiateChatRoomDetail. - ChatRoomDetailScreen renders the empty-state text only when there are no artifacts, otherwise a Card/ListItem per artifact (name, url, chevron to a pending detail route). The screen takes mantraRepository, threaded through the factory, the nav host (databaseMantraRepository), and the preview. Co-Authored-By: Claude Opus 4.8 --- .../compose/database/dao/MantraArtifactDao.kt | 4 ++ .../repository/DatabaseMantraRepository.kt | 3 ++ .../compose/repository/MantraRepository.kt | 5 ++ .../ui/composable/ChatRoomDetailScreen.kt | 46 ++++++++++++++++++- .../ui/composable/navigation/MantraNavHost.kt | 1 + .../ui/view/model/ChatRoomDetailViewModel.kt | 13 ++++-- .../ui/view/state/ChatRoomDetailUIState.kt | 4 +- 7 files changed, 69 insertions(+), 7 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraArtifactDao.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraArtifactDao.kt index 07c5cf70..33f11ca3 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraArtifactDao.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraArtifactDao.kt @@ -1,6 +1,7 @@ package press.mantra.compose.database.dao import androidx.room3.Dao +import androidx.room3.Query import androidx.room3.Upsert import press.mantra.compose.database.model.MantraArtifact @@ -8,4 +9,7 @@ import press.mantra.compose.database.model.MantraArtifact interface MantraArtifactDao { @Upsert suspend fun upsert(mantraArtifact: MantraArtifact) + + @Query("SELECT * FROM MantraArtifact WHERE chatRoomId = :chatRoomId ORDER BY createdAt DESC") + suspend fun getArtifactsByChatRoomId(chatRoomId: String): List } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/repository/DatabaseMantraRepository.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/repository/DatabaseMantraRepository.kt index 75b7919c..fb92dd86 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/repository/DatabaseMantraRepository.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/repository/DatabaseMantraRepository.kt @@ -21,6 +21,9 @@ class DatabaseMantraRepository( private val logger = Logger.withTag(TAG) + override suspend fun getArtifacts(chatRoomId: String): List = + database.mantraArtifactDao().getArtifactsByChatRoomId(chatRoomId) + override suspend fun getDialects(chatRoomId: String): List = database.mantraDialectDao().getDialectsByChatRoomId(chatRoomId) diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/repository/MantraRepository.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/repository/MantraRepository.kt index 4f3ea079..7f74b788 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/repository/MantraRepository.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/repository/MantraRepository.kt @@ -1,10 +1,13 @@ package press.mantra.compose.repository import com.vitorpamplona.quartz.nip01Core.core.HexKey +import press.mantra.compose.database.model.MantraArtifact import press.mantra.compose.database.model.MantraDialect import press.mantra.compose.database.model.MarmotInnerEvent interface MantraRepository { + suspend fun getArtifacts(chatRoomId: String): List + suspend fun getDialects(chatRoomId: String): List suspend fun addDialect( @@ -38,6 +41,8 @@ interface MantraRepository { const val DEFAULT_LICENSE = "cc" val NO_OP_MANTRA_REPOSITORY = object: MantraRepository{ + override suspend fun getArtifacts(chatRoomId: String): List = emptyList() + override suspend fun getDialects(chatRoomId: String): List = emptyList() override suspend fun addDialect( diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomDetailScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomDetailScreen.kt index 151a86de..5c9b0468 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomDetailScreen.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomDetailScreen.kt @@ -46,6 +46,7 @@ import press.mantra.compose.database.model.Profile import press.mantra.compose.database.model.intermdiate.LocalChatRoom import press.mantra.compose.database.model.intermdiate.LocalParticipant import press.mantra.compose.repository.ChatRepository +import press.mantra.compose.repository.MantraRepository import press.mantra.compose.repository.NostrRepository import press.mantra.compose.ui.composable.navigation.routes.ImplementationPendingRoute import press.mantra.compose.ui.composable.navigation.routes.Route @@ -67,6 +68,7 @@ fun ChatRoomDetailScreen( initialChatRoomDetailUIState: ChatRoomDetailUIState = ChatRoomDetailUIState.Loading, nostrRepository: NostrRepository, chatRepository: ChatRepository, + mantraRepository: MantraRepository, onNavigateToRoute: (Route) -> Unit, onPopBackToRoute: (Route) -> Unit ) { @@ -77,6 +79,7 @@ fun ChatRoomDetailScreen( initialChatRoomDetailUIState = initialChatRoomDetailUIState, nostrRepository = nostrRepository, chatRepository = chatRepository, + mantraRepository = mantraRepository, activeUserPublicKey = activeUserPublicKey ) ) @@ -135,8 +138,46 @@ fun ChatRoomDetailScreen( ) } - item { - Text("No artifacts exists in this groups library.") + if (chatRoomDetailUIState.artifacts.isEmpty()) { + item { + Text("No artifacts exists in this groups library.") + } + } else { + items( + items = chatRoomDetailUIState.artifacts, + key = { artifact -> artifact.id } + ) { artifact -> + Card( + onClick = { + onNavigateToRoute.invoke( + ImplementationPendingRoute( + "Artifact detail" + ) + ) + } + ) { + ListItem( + leadingContent = { + Icon( + Icons.Default.LibraryBooks, + contentDescription = "Artifact" + ) + }, + trailingContent = { + Icon( + Icons.Default.ChevronRight, + contentDescription = "View artifact" + ) + }, + headlineContent = { + Text(text = artifact.name) + }, + supportingContent = { + Text(text = artifact.url) + } + ) + } + } } item { @@ -435,6 +476,7 @@ private fun ChatRoomMessagingScreenPreview() { ), nostrRepository = NostrRepository.NO_OP_NOSTR_REPOSITORY, chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY, + mantraRepository = MantraRepository.NO_OP_MANTRA_REPOSITORY, onNavigateToRoute = {}, onPopBackToRoute = {} ) diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/navigation/MantraNavHost.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/navigation/MantraNavHost.kt index 1eb1d3d0..91680106 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/navigation/MantraNavHost.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/navigation/MantraNavHost.kt @@ -597,6 +597,7 @@ fun MantraNavHost( relayHint = route.relayHint, nostrRepository = databaseNostrRepository, chatRepository = databaseChatRepository, + mantraRepository = databaseMantraRepository, onNavigateToRoute = { actionRoute -> navController.navigate( route = actionRoute diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/model/ChatRoomDetailViewModel.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/model/ChatRoomDetailViewModel.kt index 4c0c8416..89535ec0 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/model/ChatRoomDetailViewModel.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/model/ChatRoomDetailViewModel.kt @@ -11,6 +11,7 @@ import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.viewModelFactory import press.mantra.compose.database.model.intermdiate.LocalChatRoom import press.mantra.compose.repository.ChatRepository +import press.mantra.compose.repository.MantraRepository import press.mantra.compose.repository.NostrRepository import press.mantra.compose.ui.composable.navigation.routes.HomeRoute import press.mantra.compose.ui.composable.navigation.routes.Route @@ -27,7 +28,8 @@ class ChatRoomDetailViewModel( val relayHint: String?, initialChatRoomDetailUIState: ChatRoomDetailUIState, val nostrRepository: NostrRepository, - val chatRepository: ChatRepository + val chatRepository: ChatRepository, + val mantraRepository: MantraRepository, ): ViewModel() { var chatRoomDetailUIState: ChatRoomDetailUIState by mutableStateOf(initialChatRoomDetailUIState) @@ -51,7 +53,8 @@ class ChatRoomDetailViewModel( ChatRoomDetailUIState.Error("Missing chat room") } else { ChatRoomDetailUIState.Loaded( - localChatRoom = localChatRoom + localChatRoom = localChatRoom, + artifacts = mantraRepository.getArtifacts(chatRoomId), ) } } @@ -107,7 +110,8 @@ class ChatRoomDetailViewModel( relayHint: String?, initialChatRoomDetailUIState: ChatRoomDetailUIState = ChatRoomDetailUIState.Loading, nostrRepository: NostrRepository, - chatRepository: ChatRepository + chatRepository: ChatRepository, + mantraRepository: MantraRepository, ): ViewModelProvider.Factory = viewModelFactory { initializer { ChatRoomDetailViewModel( @@ -116,7 +120,8 @@ class ChatRoomDetailViewModel( relayHint = relayHint, initialChatRoomDetailUIState = initialChatRoomDetailUIState, nostrRepository = nostrRepository, - chatRepository = chatRepository + chatRepository = chatRepository, + mantraRepository = mantraRepository, ) } } diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/state/ChatRoomDetailUIState.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/state/ChatRoomDetailUIState.kt index aad05287..cb464925 100755 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/state/ChatRoomDetailUIState.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/state/ChatRoomDetailUIState.kt @@ -1,10 +1,12 @@ package press.mantra.compose.ui.view.state +import press.mantra.compose.database.model.MantraArtifact import press.mantra.compose.database.model.intermdiate.LocalChatRoom sealed interface ChatRoomDetailUIState { data class Loaded( - val localChatRoom: LocalChatRoom + val localChatRoom: LocalChatRoom, + val artifacts: List = emptyList(), ): ChatRoomDetailUIState data class Error(