Add description to chat room

This commit is contained in:
Kgothatso Ngako committed 2026-07-12 21:49:59 +02:00
1 parent 7e1be3c3f6
commit f53b407e58
14 files changed
+213 -21

No files matched your search

@@ -2,7 +2,7 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 1, "version": 1,
"identityHash": "f0a498de098c8c2c2007d4309022282e", "identityHash": "6a176cdf1ee35e271c2a38b5955a7440",
"entities": [ "entities": [
{ {
"tableName": "BroadcastNostrEventReceipt", "tableName": "BroadcastNostrEventReceipt",
@@ -645,7 +645,7 @@
}, },
{ {
"tableName": "ChatRoom", "tableName": "ChatRoom",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `userPublicKey` TEXT NOT NULL, `subject` TEXT, `mlsGroupState` TEXT, `initialGiftWrapPayloadId` TEXT, `createdAt` INTEGER NOT NULL, `updatedAt` INTEGER NOT NULL, `savedAt` INTEGER NOT NULL, `viewedAt` INTEGER, `deletedAt` INTEGER, PRIMARY KEY(`id`), FOREIGN KEY(`userPublicKey`) REFERENCES `Profile`(`publicKey`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`initialGiftWrapPayloadId`) REFERENCES `GiftWrapPayload`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `userPublicKey` TEXT NOT NULL, `subject` TEXT, `description` TEXT, `mlsGroupState` TEXT, `initialGiftWrapPayloadId` TEXT, `leftGroupAt` INTEGER, `createdAt` INTEGER NOT NULL, `updatedAt` INTEGER NOT NULL, `savedAt` INTEGER NOT NULL, `viewedAt` INTEGER, `deletedAt` INTEGER, PRIMARY KEY(`id`), FOREIGN KEY(`userPublicKey`) REFERENCES `Profile`(`publicKey`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`initialGiftWrapPayloadId`) REFERENCES `GiftWrapPayload`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@@ -664,6 +664,11 @@
"columnName": "subject", "columnName": "subject",
"affinity": "TEXT" "affinity": "TEXT"
}, },
{
"fieldPath": "description",
"columnName": "description",
"affinity": "TEXT"
},
{ {
"fieldPath": "mlsGroupState", "fieldPath": "mlsGroupState",
"columnName": "mlsGroupState", "columnName": "mlsGroupState",
@@ -674,6 +679,11 @@
"columnName": "initialGiftWrapPayloadId", "columnName": "initialGiftWrapPayloadId",
"affinity": "TEXT" "affinity": "TEXT"
}, },
{
"fieldPath": "leftGroupAt",
"columnName": "leftGroupAt",
"affinity": "INTEGER"
},
{ {
"fieldPath": "createdAt", "fieldPath": "createdAt",
"columnName": "createdAt", "columnName": "createdAt",
@@ -3452,7 +3462,7 @@
], ],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f0a498de098c8c2c2007d4309022282e')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6a176cdf1ee35e271c2a38b5955a7440')"
] ]
} }
} }
@@ -1,26 +1,32 @@
package at.torch.compose.database.dao package at.torch.compose.database.dao
import androidx.room3.Dao import androidx.room3.Dao
import androidx.room3.Delete
import androidx.room3.Query import androidx.room3.Query
import androidx.room3.Transaction import androidx.room3.Transaction
import androidx.room3.Upsert import androidx.room3.Upsert
import at.torch.compose.database.model.ChatRoom
import at.torch.compose.database.model.intermdiate.LocalChatRoom
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface ChatRoomDao { interface ChatRoomDao {
@Transaction @Transaction
@Query("SELECT * FROM ChatRoom WHERE id = :id") @Query("SELECT * FROM ChatRoom WHERE id = :id")
fun findChatRoomById(id: String): at.torch.compose.database.model.intermdiate.LocalChatRoom? fun findChatRoomById(id: String): LocalChatRoom?
@Transaction @Transaction
@Query("SELECT * FROM ChatRoom WHERE userPublicKey = :userPublicKey") @Query("SELECT * FROM ChatRoom WHERE userPublicKey = :userPublicKey")
fun getChatRoomListByUserPublicKey(userPublicKey: String): List<at.torch.compose.database.model.intermdiate.LocalChatRoom> fun getChatRoomListByUserPublicKey(userPublicKey: String): List<LocalChatRoom>
@Transaction @Transaction
@Query("SELECT * FROM ChatRoom WHERE userPublicKey = :userPublicKey") @Query("SELECT * FROM ChatRoom WHERE userPublicKey = :userPublicKey")
fun observeChatRoomListByUserPublicKey(userPublicKey: String): Flow<List<at.torch.compose.database.model.intermdiate.LocalChatRoom>> fun observeChatRoomListByUserPublicKey(userPublicKey: String): Flow<List<LocalChatRoom>>
@Upsert @Upsert
suspend fun upsert(chatRoom: at.torch.compose.database.model.ChatRoom) suspend fun upsert(chatRoom: ChatRoom)
@Delete
suspend fun delete(chatRoom: ChatRoom)
} }
@@ -56,6 +56,8 @@ abstract class MarmotOutboundDao(
@Transaction @Transaction
open suspend fun createMlsDirectMessageChatRoom( open suspend fun createMlsDirectMessageChatRoom(
name: String? = null,
description: String? = null,
userPublicKey: HexKey, userPublicKey: HexKey,
peerPublicKey: HexKey, peerPublicKey: HexKey,
peerKeyPackage: MarmotKeyPackage, peerKeyPackage: MarmotKeyPackage,
@@ -78,7 +80,8 @@ abstract class MarmotOutboundDao(
id = nostrGroupId, id = nostrGroupId,
userPublicKey = userPublicKey, userPublicKey = userPublicKey,
mlsGroupState = mlsGroup.saveState().encodeTls().toHex(), mlsGroupState = mlsGroup.saveState().encodeTls().toHex(),
subject = null, subject = name,
description = description
) )
database.chatRoomDao().upsert( database.chatRoomDao().upsert(
chatRoom chatRoom
@@ -275,7 +278,6 @@ abstract class MarmotOutboundDao(
) )
} }
) )
// TODO: Save chatMessage
} }
} }
@@ -510,6 +510,7 @@ abstract class NostrDao(
id = decryptedGiftWrapPayload.chatRoomId, id = decryptedGiftWrapPayload.chatRoomId,
userPublicKey = userPublicKey, userPublicKey = userPublicKey,
subject = decryptedGiftWrapPayload.parseSubject(), subject = decryptedGiftWrapPayload.parseSubject(),
description = null,
createdAt = decryptedGiftWrapPayload.createdAt, createdAt = decryptedGiftWrapPayload.createdAt,
initialGiftWrapPayloadId = decryptedGiftWrapPayload.id, initialGiftWrapPayloadId = decryptedGiftWrapPayload.id,
mlsGroupState = null mlsGroupState = null
@@ -736,6 +737,7 @@ abstract class NostrDao(
id = nostrGroupId, id = nostrGroupId,
userPublicKey = userPublicKey, userPublicKey = userPublicKey,
subject = group.currentMarmotData()?.name?.ifBlank { null }, subject = group.currentMarmotData()?.name?.ifBlank { null },
description = group.currentMarmotData()?.description?.ifBlank { null },
initialGiftWrapPayloadId = decryptedGiftWrapPayload.id, initialGiftWrapPayloadId = decryptedGiftWrapPayload.id,
createdAt = decryptedGiftWrapPayload.createdAt, createdAt = decryptedGiftWrapPayload.createdAt,
mlsGroupState = group.saveState().encodeTls().toHex(), mlsGroupState = group.saveState().encodeTls().toHex(),
@@ -28,7 +28,14 @@ abstract class NostrNip17Dao(
val logger = Logger.withTag(TAG) val logger = Logger.withTag(TAG)
@Transaction @Transaction
open suspend fun getOrCreateChatRoom(chatRoomId: String, activeUserPublicKey: HexKey, relayHint: String?, defaultSubject: String? = null, mlsGroupState: String? = null): LocalChatRoom? { open suspend fun getOrCreateChatRoom(
chatRoomId: HexKey,
activeUserPublicKey: HexKey,
relayHint: String?,
defaultSubject: String? = null,
description: String? = null,
mlsGroupState: String? = null
): LocalChatRoom? {
logger.d("getOrCreateChatRoom: $chatRoomId") logger.d("getOrCreateChatRoom: $chatRoomId")
@@ -51,7 +58,8 @@ abstract class NostrNip17Dao(
id = chatRoomId, id = chatRoomId,
userPublicKey = activeUserPublicKey, userPublicKey = activeUserPublicKey,
subject = defaultSubject, subject = defaultSubject,
mlsGroupState = mlsGroupState mlsGroupState = mlsGroupState,
description = description
) )
database.chatRoomDao().upsert(chatRoom) database.chatRoomDao().upsert(chatRoom)
@@ -58,6 +58,8 @@ data class ChatRoom(
*/ */
val subject: String?, val subject: String?,
val description: String?,
val mlsGroupState: String?, val mlsGroupState: String?,
/** /**
@@ -75,6 +77,8 @@ data class ChatRoom(
// Might want to focus on the other last messages... // Might want to focus on the other last messages...
val initialGiftWrapPayloadId: HexKey? = null, val initialGiftWrapPayloadId: HexKey? = null,
val leftGroupAt: Instant? = null,
override val createdAt: Instant = Clock.System.now(), override val createdAt: Instant = Clock.System.now(),
override val updatedAt: Instant = createdAt, override val updatedAt: Instant = createdAt,
override val savedAt: Instant = createdAt, override val savedAt: Instant = createdAt,
@@ -3,6 +3,7 @@ package at.torch.compose.database.repository
import at.torch.compose.database.GENESIS_AT import at.torch.compose.database.GENESIS_AT
import at.torch.compose.database.TorchDatabase import at.torch.compose.database.TorchDatabase
import at.torch.compose.database.model.ChatMessage import at.torch.compose.database.model.ChatMessage
import at.torch.compose.database.model.ChatRoom
import at.torch.compose.database.model.GiftWrapPayload import at.torch.compose.database.model.GiftWrapPayload
import at.torch.compose.database.model.MarmotInnerEvent import at.torch.compose.database.model.MarmotInnerEvent
import at.torch.compose.database.model.MarmotKeyPackage import at.torch.compose.database.model.MarmotKeyPackage
@@ -14,7 +15,6 @@ import co.touchlab.kermit.Logger
import com.vitorpamplona.quartz.marmot.mip02Welcome.WelcomeEvent import com.vitorpamplona.quartz.marmot.mip02Welcome.WelcomeEvent
import com.vitorpamplona.quartz.marmot.mls.group.MlsGroup import com.vitorpamplona.quartz.marmot.mls.group.MlsGroup
import com.vitorpamplona.quartz.marmot.mls.group.MlsGroupState import com.vitorpamplona.quartz.marmot.mls.group.MlsGroupState
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Kind import com.vitorpamplona.quartz.nip01Core.core.Kind
import com.vitorpamplona.quartz.nip01Core.crypto.EventHasher import com.vitorpamplona.quartz.nip01Core.crypto.EventHasher
@@ -69,6 +69,7 @@ class DatabaseChatRepository(
activeUserPublicKey: HexKey, activeUserPublicKey: HexKey,
relayHint: String?, relayHint: String?,
defaultSubject: String?, defaultSubject: String?,
description: String?,
mlsGroupState: String? mlsGroupState: String?
): LocalChatRoom? = try { ): LocalChatRoom? = try {
return database.nostrNip17Dao().getOrCreateChatRoom( return database.nostrNip17Dao().getOrCreateChatRoom(
@@ -76,6 +77,7 @@ class DatabaseChatRepository(
activeUserPublicKey = activeUserPublicKey, activeUserPublicKey = activeUserPublicKey,
relayHint = relayHint, relayHint = relayHint,
defaultSubject = defaultSubject, defaultSubject = defaultSubject,
description = description,
mlsGroupState = mlsGroupState mlsGroupState = mlsGroupState
) )
} catch (e: Throwable) { } catch (e: Throwable) {
@@ -120,11 +122,15 @@ class DatabaseChatRepository(
} }
override suspend fun createMlsDirectMessage( override suspend fun createMlsDirectMessage(
name: String?,
description: String?,
userPublicKey: HexKey, userPublicKey: HexKey,
peerPublicKey: HexKey, peerPublicKey: HexKey,
peerKeyPackage: MarmotKeyPackage peerKeyPackage: MarmotKeyPackage
): String { ): String {
return database.marmotOutboundDao().createMlsDirectMessageChatRoom( return database.marmotOutboundDao().createMlsDirectMessageChatRoom(
name = name,
description = description,
userPublicKey = userPublicKey, userPublicKey = userPublicKey,
peerPublicKey = peerPublicKey, peerPublicKey = peerPublicKey,
peerKeyPackage = peerKeyPackage peerKeyPackage = peerKeyPackage
@@ -155,6 +161,7 @@ class DatabaseChatRepository(
) )
) )
} }
if (mlsGroup != null) { if (mlsGroup != null) {
// Create ChatRumor... // Create ChatRumor...
val createdAt = Clock.System.now().epochSeconds val createdAt = Clock.System.now().epochSeconds
@@ -345,6 +352,112 @@ class DatabaseChatRepository(
} }
} }
override suspend fun leaveChatRoom(localChatRoom: LocalChatRoom) {
val text = "Left group."
val mlsGroup = localChatRoom.chatRoom.mlsGroupState?.let { mlsGroupState ->
MlsGroup.restore(
MlsGroupState.decodeTls(
mlsGroupState.hexToByteArray()
)
)
}
if (mlsGroup != null) {
// Create ChatRumor...
val createdAt = Clock.System.now().epochSeconds
val marmotInnerEventKind = ChatEvent.KIND
val marmotInnerEventId = EventHasher.hashId(
pubKey = localChatRoom.chatRoom.userPublicKey,
createdAt = createdAt,
tags = emptyArray(),
content = text,
kind = marmotInnerEventKind
)
database.marmotInnerEventDao().upsert(
MarmotInnerEvent(
id = marmotInnerEventId,
publicKey = localChatRoom.chatRoom.userPublicKey,
createdAt = Instant.fromEpochSeconds(createdAt),
tags = emptyArray(),
content = text,
chatRoomId = localChatRoom.chatRoom.id,
kind = marmotInnerEventKind
)
)
database.chatMessageDao().upsert(
ChatMessage(
content = text,
chatRoomId = localChatRoom.chatRoom.id,
senderPublicKey = localChatRoom.chatRoom.userPublicKey,
isUserMessage = true,
giftWrapPayloadId = null,
marmotGroupEventId = null,
marmotInnerEventId = marmotInnerEventId,
)
)
} else {
val innerEventKind = ChatMessageEvent.KIND
// Send GiftWrapMessage
val receiverTags = localChatRoom.localParticipants.filter { participant ->
participant.participant.participantPublicKey != localChatRoom.chatRoom.userPublicKey // TODO: Allow this where it's notes to self...
}.map { localParticipant ->
PTag.assemble(
localParticipant.participant.participantPublicKey,
localParticipant.participant.relayHint?.let { NormalizedRelayUrl(it) }
)
}
val createdAt = Clock.System.now().epochSeconds
val giftWrapPayloadId = EventHasher.hashId(
pubKey = localChatRoom.chatRoom.userPublicKey,
createdAt = createdAt,
tags = receiverTags.toTypedArray(),
content = text,
kind = innerEventKind
)
database.giftWrapPayloadDao().upsert(
GiftWrapPayload(
id = giftWrapPayloadId,
kind = innerEventKind,
tags = receiverTags.toTypedArray(),
createdAt = Instant.fromEpochSeconds(createdAt),
content = text,
chatRoomId = localChatRoom.chatRoom.id,
publicKey = localChatRoom.chatRoom.userPublicKey
)
)
database.chatMessageDao().upsert(
ChatMessage(
content = text,
chatRoomId = localChatRoom.chatRoom.id,
senderPublicKey = localChatRoom.chatRoom.userPublicKey,
isUserMessage = true,
giftWrapPayloadId = giftWrapPayloadId,
marmotGroupEventId = null,
marmotInnerEventId = null
)
)
}
}
override suspend fun softDeleteChatRoom(chatRoom: ChatRoom) {
database.chatRoomDao().upsert(
chatRoom.copy(
deletedAt = Clock.System.now()
)
)
}
override suspend fun deleteChatRoom(chatRoom: ChatRoom) {
database.chatRoomDao().delete(chatRoom)
}
companion object { companion object {
const val TAG = "DatabaseChatRepository" const val TAG = "DatabaseChatRepository"
} }
@@ -7,13 +7,11 @@ import at.torch.compose.database.model.Participant
import at.torch.compose.database.model.Profile import at.torch.compose.database.model.Profile
import at.torch.compose.database.model.intermdiate.LocalChatMessage import at.torch.compose.database.model.intermdiate.LocalChatMessage
import at.torch.compose.database.model.intermdiate.LocalChatRoom import at.torch.compose.database.model.intermdiate.LocalChatRoom
import at.torch.compose.database.model.intermdiate.LocalProfile
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Kind import com.vitorpamplona.quartz.nip01Core.core.Kind
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync
import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
import fr.acinq.secp256k1.Hex
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
@@ -35,6 +33,7 @@ interface ChatRepository {
activeUserPublicKey: HexKey, activeUserPublicKey: HexKey,
relayHint: String?, relayHint: String?,
defaultSubject: String?, defaultSubject: String?,
description: String?,
mlsGroupState: String? mlsGroupState: String?
): LocalChatRoom? ): LocalChatRoom?
@@ -45,6 +44,8 @@ interface ChatRepository {
suspend fun getProfileWithPublicKey(publicKey: HexKey): Profile? suspend fun getProfileWithPublicKey(publicKey: HexKey): Profile?
suspend fun createMlsDirectMessage( suspend fun createMlsDirectMessage(
name: String? = null,
description: String? = null,
userPublicKey: HexKey, userPublicKey: HexKey,
peerPublicKey: HexKey, peerPublicKey: HexKey,
peerKeyPackage: MarmotKeyPackage peerKeyPackage: MarmotKeyPackage
@@ -68,6 +69,12 @@ interface ChatRepository {
suspend fun sealGiftWrapPayload(giftWrapPayload: GiftWrapPayload, nostrSignerSync: NostrSignerSync) suspend fun sealGiftWrapPayload(giftWrapPayload: GiftWrapPayload, nostrSignerSync: NostrSignerSync)
suspend fun leaveChatRoom(localChatRoom: LocalChatRoom)
suspend fun softDeleteChatRoom(chatRoom: ChatRoom)
suspend fun deleteChatRoom(chatRoom: ChatRoom)
companion object { companion object {
val NO_OP_CHAT_REPOSITORY = object: ChatRepository { val NO_OP_CHAT_REPOSITORY = object: ChatRepository {
override suspend fun observeChatRoomListByPublicKey(publicKey: String): Flow<List<LocalChatRoom>> { override suspend fun observeChatRoomListByPublicKey(publicKey: String): Flow<List<LocalChatRoom>> {
@@ -100,6 +107,7 @@ interface ChatRepository {
activeUserPublicKey: HexKey, activeUserPublicKey: HexKey,
relayHint: String?, relayHint: String?,
defaultSubject: String?, defaultSubject: String?,
description: String?,
mlsGroupState: String? mlsGroupState: String?
): LocalChatRoom? { ): LocalChatRoom? {
return null return null
@@ -118,6 +126,8 @@ interface ChatRepository {
} }
override suspend fun createMlsDirectMessage( override suspend fun createMlsDirectMessage(
name: String?,
description: String?,
userPublicKey: HexKey, userPublicKey: HexKey,
peerPublicKey: HexKey, peerPublicKey: HexKey,
peerKeyPackage: MarmotKeyPackage peerKeyPackage: MarmotKeyPackage
@@ -155,6 +165,18 @@ interface ChatRepository {
) { ) {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override suspend fun leaveChatRoom(localChatRoom: LocalChatRoom) {
TODO("Not yet implemented")
}
override suspend fun softDeleteChatRoom(chatRoom: ChatRoom) {
TODO("Not yet implemented")
}
override suspend fun deleteChatRoom(chatRoom: ChatRoom) {
TODO("Not yet implemented")
}
} }
} }
} }
@@ -219,6 +219,7 @@ private fun ChatRoomDetailScreenPreview() {
id = "hex", id = "hex",
userPublicKey = "hex", userPublicKey = "hex",
subject = "Room Title", subject = "Room Title",
description = "See something... say something.",
initialGiftWrapPayloadId = "sdfaer", initialGiftWrapPayloadId = "sdfaer",
mlsGroupState = null mlsGroupState = null
), ),
@@ -206,12 +206,12 @@ fun ChatRoomDetailScreen(
colors = ButtonDefaults.textButtonColors( colors = ButtonDefaults.textButtonColors(
contentColor = MaterialTheme.colorScheme.secondary contentColor = MaterialTheme.colorScheme.secondary
), ),
enabled = true, // Disable after we leave group... enabled = chatRoomDetailUIState.localChatRoom.chatRoom.leftGroupAt == null, // Disable after we leave group...
onClick = { onClick = {
onNavigateToRoute.invoke( // Leave group logic
ImplementationPendingRoute( chatRoomDetailViewModel.leaveGroup(
"Leave Group" localChatRoom = chatRoomDetailUIState.localChatRoom,
) onNavigateToRoute = onNavigateToRoute
) )
} }
) { ) {
@@ -233,7 +233,7 @@ fun ChatRoomDetailScreen(
colors = ButtonDefaults.textButtonColors( colors = ButtonDefaults.textButtonColors(
contentColor = MaterialTheme.colorScheme.error contentColor = MaterialTheme.colorScheme.error
), ),
enabled = true, // TODO: Only enabled after we leave group... enabled = chatRoomDetailUIState.localChatRoom.chatRoom.leftGroupAt != null,
onClick = { onClick = {
onNavigateToRoute.invoke( onNavigateToRoute.invoke(
ImplementationPendingRoute( ImplementationPendingRoute(
@@ -316,7 +316,8 @@ private fun ChatRoomMessagingScreenPreview() {
chatRoom = ChatRoom( chatRoom = ChatRoom(
id = "", id = "",
userPublicKey = "", userPublicKey = "",
subject = "Message title", subject = "Message Title",
description = "Description",
initialGiftWrapPayloadId = "sdfaer", initialGiftWrapPayloadId = "sdfaer",
mlsGroupState = null mlsGroupState = null
), ),
@@ -340,6 +340,7 @@ private fun ChatRoomMessagingScreenPreview() {
id = "", id = "",
userPublicKey = "", userPublicKey = "",
subject = "Message title", subject = "Message title",
description = "See something. Say somethin",
initialGiftWrapPayloadId = "sdfaer", initialGiftWrapPayloadId = "sdfaer",
mlsGroupState = null mlsGroupState = null
), ),
@@ -227,6 +227,7 @@ private fun ChatRoomDetailScreenPreview() {
id = "", id = "",
userPublicKey = "", userPublicKey = "",
subject = "Message title", subject = "Message title",
description = "See something... say something.",
initialGiftWrapPayloadId = "sdfaer", initialGiftWrapPayloadId = "sdfaer",
mlsGroupState = null mlsGroupState = null
), ),
@@ -84,6 +84,7 @@ class ChatRoomCreationViewModel(
activeUserPublicKey = keyPair.pubKey.toHexKey(), activeUserPublicKey = keyPair.pubKey.toHexKey(),
relayHint = null, relayHint = null,
defaultSubject = name.toString(), defaultSubject = name.toString(),
description = description.toString(),
mlsGroupState = group.saveState().encodeTls().toHex() mlsGroupState = group.saveState().encodeTls().toHex()
) )
@@ -9,8 +9,12 @@ import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory import androidx.lifecycle.viewmodel.viewModelFactory
import at.torch.compose.database.model.ChatRoom
import at.torch.compose.database.model.intermdiate.LocalChatRoom
import at.torch.compose.repository.ChatRepository import at.torch.compose.repository.ChatRepository
import at.torch.compose.repository.NostrRepository import at.torch.compose.repository.NostrRepository
import at.torch.compose.ui.composable.navigation.routes.ImplementationPendingRoute
import at.torch.compose.ui.composable.navigation.routes.Route
import at.torch.compose.ui.view.state.ChatRoomDetailUIState import at.torch.compose.ui.view.state.ChatRoomDetailUIState
import co.touchlab.kermit.Logger import co.touchlab.kermit.Logger
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
@@ -53,6 +57,22 @@ class ChatRoomDetailViewModel(
} }
} }
fun leaveGroup(
localChatRoom: LocalChatRoom,
onNavigateToRoute: (Route) -> Unit
) {
viewModelScope.launch(Dispatchers.IO) {
chatRepository.leaveChatRoom(localChatRoom)
viewModelScope.launch(Dispatchers.Main) {
onNavigateToRoute.invoke(
ImplementationPendingRoute(
"Leave Group"
)
)
}
}
}
companion object { companion object {
private const val TAG = "ChatRoomDetailViewModel" private const val TAG = "ChatRoomDetailViewModel"