From 6c63027912eb233557b772435205598f537cff5b Mon Sep 17 00:00:00 2001 From: Kgothatso Ngako Date: Sat, 5 Sep 2026 20:21:52 +0200 Subject: [PATCH] feat: submit nip30303 events to the group instead of authoring them into it With the receiving side able to open an envelope, start sending one. Every nip30303 event now leaves as a SubmissionEvent payload and none leaves on its own: addDialect, addArtifact, addArtifactVersion, addChapter and each of its chunks, addTranslationArtifactVersion and each of its translation chapters, and saveTranslation. Because all four add screens reach the wire through MantraDao, none of them needed touching. Two helpers carry it: rumorOf(template, publicKey) the unsigned event a template describes. Its id is computed exactly as the matching Mantra* entity computes its own, so the row on disk and the payload on the wire are one event rather than two copies of one. submitToGroup(...) wraps a payload, queues the submission as an unprocessed rumor, and writes the chat line. Two things this drags in, neither optional: The queued MarmotInnerEvent is now the envelope, so its id is the envelope's and no longer the nip30303 event's. saveTranslation replaces a chunk whenever its text changes -- the id is derived from the content, so an edit is a new row -- and un-queued the superseded one by deleteById(stale.id). That silently stops matching anything once the row is a submission, leaving the stale translation to be sent anyway. It now also deletes by what the submission carries, via deleteByPayloadEventId. The add* methods return the entity rather than the queued rumor. This is a correctness fix, not tidying: AddArtifactViewModel navigates to ArtifactDetailRoute on that id, and AddTranslationArtifactVersionViewModel feeds addDialect's id straight back in as a dialectId. Both used to be handed a MarmotInnerEvent whose id happened to equal the entity's, and both would now have been handed a submission id -- one navigating to an artifact that does not exist, the other tagging a translation with a dialect that does not. Returning MantraArtifact/MantraDialect/etc. makes .id mean the entity everywhere and matches saveTranslationChunk, which already returned its entity. The sendMarmotInnerEvent overload taking a LocalChatRoom loses its last caller; submitToGroup names the submitter explicitly, which is the thing that matters now that it is not necessarily the author. Outbound still only ever submits payloads authored by the submitter -- nothing in the app originates a foreign event yet. submitToGroup is where that would attach. Co-Authored-By: Claude Opus 5 --- .../mantra/compose/database/dao/MantraDao.kt | 265 +++++++++--------- .../database/dao/MarmotInnerEventDao.kt | 9 + .../repository/DatabaseMantraRepository.kt | 10 +- .../compose/repository/MantraRepository.kt | 21 +- .../ui/view/model/AddArtifactViewModel.kt | 6 +- .../ui/view/model/AddDialectViewModel.kt | 6 +- 6 files changed, 157 insertions(+), 160 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraDao.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraDao.kt index ba331ccb..ac55e82e 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraDao.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraDao.kt @@ -3,7 +3,10 @@ package press.mantra.compose.database.dao import androidx.room3.Dao import androidx.room3.Transaction import co.touchlab.kermit.Logger +import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.crypto.EventHasher +import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import press.mantra.compose.database.MantraDatabase import press.mantra.compose.database.model.ChatMessage import press.mantra.compose.database.model.MantraArtifact @@ -21,6 +24,7 @@ import press.mantra.compose.nostr.nip30303.ArtifactVersionEvent import press.mantra.compose.nostr.nip30303.ChapterEvent import press.mantra.compose.nostr.nip30303.ChunkEvent import press.mantra.compose.nostr.nip30303.DialectEvent +import press.mantra.compose.nostr.nip30303.SubmissionEvent import press.mantra.compose.nostr.nip30303.TranslationArtifactVersionEvent import press.mantra.compose.nostr.nip30303.TranslationChapterEvent import press.mantra.compose.nostr.nip30303.TranslationChunkEvent @@ -28,6 +32,7 @@ import press.mantra.compose.nostr.nip30303.tags.ArtifactIdTag import press.mantra.compose.repository.MantraRepository.Companion.DEFAULT_LICENSE import press.mantra.compose.repository.MantraRepository.Companion.DEFAULT_VISIBILITY import press.mantra.compose.text.Markdown +import kotlin.time.Instant @Dao abstract class MantraDao( @@ -35,6 +40,82 @@ abstract class MantraDao( ) { val logger = Logger.withTag("NostrDao") + /** + * The unsigned nip30303 event [template] describes, authored by [publicKey]. + * + * Its id is computed the same way the matching Mantra* entity computes + * its own, so the row on disk and the payload on the wire are the same + * event rather than two copies of one. + */ + private fun rumorOf( + template: EventTemplate, + publicKey: HexKey, + ): Event = Event( + id = EventHasher.hashId( + pubKey = publicKey, + createdAt = template.createdAt, + kind = template.kind, + tags = template.tags, + content = template.content, + ), + pubKey = publicKey, + createdAt = template.createdAt, + kind = template.kind, + tags = template.tags, + content = template.content, + // A rumor. What signs for this reaching the group is the kind:445 the + // outbound pipeline wraps it in, not the payload itself. + sig = "", + ) + + /** + * Queue [payload] for the group inside a [SubmissionEvent] that + * [submitterPublicKey] authors. + * + * nip30303 events are never sent on their own. Wrapping them means the + * payload keeps whoever wrote it as its author while the group still knows + * which member put it there -- see [SubmissionEvent] for why the two are + * worth telling apart. + * + * The submission is stored as an unprocessed rumor (null marmotGroupEventId), + * which is what the outbound pipeline picks up and encrypts into a kind:445 + * group event for the chat room. + */ + private suspend fun submitToGroup( + chatRoomId: String, + submitterPublicKey: HexKey, + payload: Event, + text: String, + ): MarmotInnerEvent { + val submissionTemplate = SubmissionEvent.build(payload = payload) + + val submissionInnerEvent = MarmotInnerEvent( + id = EventHasher.hashId( + pubKey = submitterPublicKey, + createdAt = submissionTemplate.createdAt, + kind = submissionTemplate.kind, + tags = submissionTemplate.tags, + content = submissionTemplate.content, + ), + publicKey = submitterPublicKey, + kind = SubmissionEvent.KIND, + createdAt = Instant.fromEpochSeconds(submissionTemplate.createdAt), + tags = submissionTemplate.tags, + content = submissionTemplate.content, + payloadEventId = payload.id, + chatRoomId = chatRoomId, + ) + + sendMarmotInnerEvent( + chatRoomId = chatRoomId, + userPublicKey = submitterPublicKey, + text = text, + marmotInnerEvent = submissionInnerEvent, + ) + + return submissionInnerEvent + } + @Transaction open suspend fun addDialect( localChatRoom: LocalChatRoom, @@ -42,7 +123,7 @@ abstract class MantraDao( country: String, language: String, userPublicKey: HexKey, - ): MarmotInnerEvent? { + ): MantraDialect? { logger.d("addDialect: $name") val dialectEventTemplate = DialectEvent.build( @@ -57,26 +138,17 @@ abstract class MantraDao( userPublicKey = userPublicKey, ) ?: return null - val dialectInnerEvent = MarmotInnerEvent( - id = mantraDialect.id, - publicKey = mantraDialect.publicKey, - kind = DialectEvent.KIND, - createdAt = mantraDialect.createdAt, - tags = dialectEventTemplate.tags, - content = dialectEventTemplate.content, - chatRoomId = mantraDialect.chatRoomId, - ) - return try { database.mantraDialectDao().upsert(mantraDialect) - database.marmotInnerEventDao().upsert(dialectInnerEvent) - sendMarmotInnerEvent( - localChatRoom = localChatRoom, + submitToGroup( + chatRoomId = mantraDialect.chatRoomId, + submitterPublicKey = userPublicKey, + payload = rumorOf(dialectEventTemplate, userPublicKey), text = "Added $name as a dialect", - marmotInnerEvent = dialectInnerEvent ) - dialectInnerEvent + + mantraDialect } catch (error: Throwable) { logger.e("Failed to add dialect \"$name\" to chat room ${localChatRoom.chatRoom.id}", error) null @@ -94,7 +166,7 @@ abstract class MantraDao( userPublicKey: HexKey, visibility: String = DEFAULT_VISIBILITY, license: String = DEFAULT_LICENSE, - ): MarmotInnerEvent? { + ): MantraArtifact? { // TODO: Verify the active user is an admin of the chat room before allowing this. val artifactEventTemplate = ArtifactEvent.build( name = name, @@ -110,32 +182,19 @@ abstract class MantraDao( userPublicKey = userPublicKey, ) ?: return null - // Persist the artifact together with an unprocessed marmot inner event - // (a rumor). Inner events with a null marmotGroupEventId are later - // picked up by the outbound pipeline and encrypted into a kind:445 - // group event for the chat room. + // Persist the artifact locally and submit it to the group. // // This covers the "private" visibility case. Permissioned artifacts // (published as a PublicMessage) and public artifacts (published as a // plain nostr event) are not implemented yet. - val artifactInnerEvent = MarmotInnerEvent( - id = mantraArtifact.id, - publicKey = mantraArtifact.publicKey, - kind = ArtifactEvent.KIND, - createdAt = mantraArtifact.createdAt, - tags = artifactEventTemplate.tags, - content = artifactEventTemplate.content, - chatRoomId = mantraArtifact.chatRoomId, - ) - return try { database.mantraArtifactDao().upsert(mantraArtifact) - database.marmotInnerEventDao().upsert(artifactInnerEvent) - sendMarmotInnerEvent( - localChatRoom = localChatRoom, + submitToGroup( + chatRoomId = mantraArtifact.chatRoomId, + submitterPublicKey = userPublicKey, + payload = rumorOf(artifactEventTemplate, userPublicKey), text = "Added $name to artifacts", - marmotInnerEvent = artifactInnerEvent ) // Every artifact starts with an initial version. @@ -146,7 +205,7 @@ abstract class MantraDao( userPublicKey = userPublicKey, ) - artifactInnerEvent + mantraArtifact } catch (error: Throwable) { logger.e("Failed to add artifact \"$name\" to chat room ${localChatRoom.chatRoom.id}", error) null @@ -159,7 +218,7 @@ abstract class MantraDao( artifactId: HexKey, versionLabel: String, userPublicKey: HexKey, - ): MarmotInnerEvent? { + ): MantraArtifactVersion? { return addArtifactVersionInternal( localChatRoom = localChatRoom, artifactId = artifactId, @@ -173,7 +232,7 @@ abstract class MantraDao( artifactId: HexKey, versionLabel: String, userPublicKey: HexKey, - ): MarmotInnerEvent? { + ): MantraArtifactVersion? { // The version label is carried in the event content (see // MantraArtifactVersion.fromArtifactVersionEvent). val artifactVersionEventTemplate = ArtifactVersionEvent.build( @@ -188,25 +247,16 @@ abstract class MantraDao( userPublicKey = userPublicKey, ) ?: return null - val versionInnerEvent = MarmotInnerEvent( - id = mantraArtifactVersion.id, - publicKey = mantraArtifactVersion.publicKey, - kind = ArtifactVersionEvent.KIND, - createdAt = mantraArtifactVersion.createdAt, - tags = artifactVersionEventTemplate.tags, - content = artifactVersionEventTemplate.content, - chatRoomId = mantraArtifactVersion.chatRoomId, - ) - database.mantraArtifactVersionDao().upsert(mantraArtifactVersion) - database.marmotInnerEventDao().upsert(versionInnerEvent) - sendMarmotInnerEvent( - localChatRoom = localChatRoom, + submitToGroup( + chatRoomId = mantraArtifactVersion.chatRoomId, + submitterPublicKey = userPublicKey, + payload = rumorOf(artifactVersionEventTemplate, userPublicKey), text = "Add the ${artifactVersionEventTemplate.content} version", - marmotInnerEvent = versionInnerEvent ) - return versionInnerEvent + + return mantraArtifactVersion } @Transaction @@ -216,7 +266,7 @@ abstract class MantraDao( originalText: String, chatRoomId: String, userPublicKey: HexKey, - ): MarmotInnerEvent? { + ): MantraChapter? { // Chapters attach to an artifact version; use the latest one. val version = database.mantraArtifactVersionDao() @@ -244,24 +294,12 @@ abstract class MantraDao( return try { database.mantraChapterDao().upsert(chapter) - val chapterInnerEvent = MarmotInnerEvent( - id = chapter.id, - publicKey = chapter.publicKey, - kind = ChapterEvent.KIND, - createdAt = chapter.createdAt, - tags = chapterEventTemplate.tags, - content = chapterEventTemplate.content, - chatRoomId = chapter.chatRoomId, - ) - database.marmotInnerEventDao().upsert( - chapterInnerEvent - ) - sendMarmotInnerEvent( + submitToGroup( chatRoomId = chatRoomId, - userPublicKey = userPublicKey, + submitterPublicKey = userPublicKey, + payload = rumorOf(chapterEventTemplate, userPublicKey), text = "Added chapter to artifact", // TODO: Get artifact to use in text... - marmotInnerEvent = chapterInnerEvent ) // Split the markdown into paragraph chunks. @@ -279,30 +317,17 @@ abstract class MantraDao( userPublicKey = userPublicKey, )?.let { chunk -> database.mantraChunkDao().upsert(chunk) - val chunkInnerEvent = MarmotInnerEvent( - id = chunk.id, - publicKey = chunk.publicKey, - kind = ChunkEvent.KIND, - createdAt = chunk.createdAt, - tags = chunkEventTemplate.tags, - content = chunkEventTemplate.content, - chatRoomId = chunk.chatRoomId, - ) - database.marmotInnerEventDao().upsert( - chunkInnerEvent - ) - - sendMarmotInnerEvent( + submitToGroup( chatRoomId = chatRoomId, - userPublicKey = userPublicKey, + submitterPublicKey = userPublicKey, + payload = rumorOf(chunkEventTemplate, userPublicKey), text = "${chapter.name} added chunk $chunkIndex", // TODO: Use a portion of the actual chunked text... - marmotInnerEvent = chunkInnerEvent ) } } - chapterInnerEvent + chapter } catch (error: Throwable) { logger.e("Failed to add chapter \"$name\" to artifact $artifactId", error) null @@ -315,7 +340,7 @@ abstract class MantraDao( dialectId: String, chatRoomId: String, userPublicKey: HexKey, - ): MarmotInnerEvent? { + ): MantraTranslationArtifactVersion? { val artifact = database.mantraArtifactDao().getArtifactById(artifactId) ?: return null val version = database.mantraArtifactVersionDao() .getArtifactVersionsByArtifactId(artifactId) @@ -339,21 +364,12 @@ abstract class MantraDao( return try { database.mantraTranslationArtifactVersionDao().upsert(translationVersion) - val translationArtifactVersionInnerEvent = MarmotInnerEvent( - id = translationVersion.id, - publicKey = translationVersion.publicKey, - kind = TranslationArtifactVersionEvent.KIND, - createdAt = translationVersion.createdAt, - tags = translationVersionTemplate.tags, - content = translationVersionTemplate.content, - chatRoomId = translationVersion.chatRoomId, - ) - sendMarmotInnerEvent( + submitToGroup( chatRoomId = chatRoomId, - userPublicKey = userPublicKey, + submitterPublicKey = userPublicKey, + payload = rumorOf(translationVersionTemplate, userPublicKey), text = "Added ${dialect.name} translation", - marmotInnerEvent = translationArtifactVersionInnerEvent ) // Mirror the source structure: a translation chapter per chapter and @@ -372,21 +388,12 @@ abstract class MantraDao( ) ?: return@forEach database.mantraTranslationChapterDao().upsert(translationChapter) - val translationChapterInnerEvent = MarmotInnerEvent( - id = translationChapter.id, - publicKey = translationChapter.publicKey, - kind = TranslationChapterEvent.KIND, - createdAt = translationChapter.createdAt, - tags = translationChapterTemplate.tags, - content = translationChapterTemplate.content, - chatRoomId = translationChapter.chatRoomId, - ) - sendMarmotInnerEvent( + submitToGroup( chatRoomId = chatRoomId, - userPublicKey = userPublicKey, + submitterPublicKey = userPublicKey, + payload = rumorOf(translationChapterTemplate, userPublicKey), text = "Prepared ${dialect.name} translation of the chapter ${chapter.name}", - marmotInnerEvent = translationChapterInnerEvent ) // TODO: Figure out if we seriously need the scaffolding @@ -427,7 +434,7 @@ abstract class MantraDao( // } } - translationArtifactVersionInnerEvent + translationVersion } catch (error: Throwable) { logger.e("Failed to add translation for artifact $artifactId", error) null @@ -460,30 +467,25 @@ abstract class MantraDao( return try { // Replace any existing translation chunk for this source chunk. Its id // is derived from the (now changed) content, so it becomes a new row — - // drop the old one (and its rumor) to keep one per source chunk. + // drop the old one (and the submission carrying it) to keep one per + // source chunk. The submission is found by what it carries, since its + // own id is the envelope's rather than the chunk's. database.mantraTranslationChunkDao() .getTranslationChunksByTranslationChapterId(translationChapterId) .filter { it.chunkId == chunkId && it.id != translationChunk.id } .forEach { stale -> database.mantraTranslationChunkDao().deleteById(stale.id) database.marmotInnerEventDao().deleteById(stale.id) + database.marmotInnerEventDao().deleteByPayloadEventId(stale.id) } database.mantraTranslationChunkDao().upsert(translationChunk) - val translationChunkInnerEvent = MarmotInnerEvent( - id = translationChunk.id, - publicKey = translationChunk.publicKey, - kind = TranslationChunkEvent.KIND, - createdAt = translationChunk.createdAt, - tags = translationChunkTemplate.tags, - content = translationChunkTemplate.content, - chatRoomId = translationChunk.chatRoomId, - ) - sendMarmotInnerEvent( + + submitToGroup( chatRoomId = chatRoomId, - userPublicKey = userPublicKey, + submitterPublicKey = userPublicKey, + payload = rumorOf(translationChunkTemplate, userPublicKey), text = "Translated chunk ${translationChunk.index}", // TODO: Use a portion of the translation and name the language - marmotInnerEvent = translationChunkInnerEvent ) translationChunk @@ -493,19 +495,6 @@ abstract class MantraDao( } } - private suspend fun sendMarmotInnerEvent( - localChatRoom: LocalChatRoom, - text: String, - marmotInnerEvent: MarmotInnerEvent - ) { - sendMarmotInnerEvent( - chatRoomId = localChatRoom.chatRoom.id, - userPublicKey = localChatRoom.chatRoom.userPublicKey, - text = text, - marmotInnerEvent = marmotInnerEvent - ) - } - private suspend fun sendMarmotInnerEvent( chatRoomId: String, userPublicKey: HexKey, diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MarmotInnerEventDao.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MarmotInnerEventDao.kt index 159e1dfb..016e060b 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MarmotInnerEventDao.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MarmotInnerEventDao.kt @@ -17,4 +17,13 @@ interface MarmotInnerEventDao { @Query("DELETE FROM MarmotInnerEvent WHERE id = :id") suspend fun deleteById(id: String) + + /** + * Drop the submissions carrying [payloadEventId]. + * + * A submission's id is the envelope's, not the payload's, so a superseded + * nip30303 event cannot be un-queued by its own id. + */ + @Query("DELETE FROM MarmotInnerEvent WHERE payloadEventId = :payloadEventId") + suspend fun deleteByPayloadEventId(payloadEventId: String) } \ 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 5a5bcc6c..eb573bcf 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 @@ -44,7 +44,7 @@ class DatabaseMantraRepository( dialectId: String, chatRoomId: String, userPublicKey: HexKey, - ): MarmotInnerEvent? { + ): MantraTranslationArtifactVersion? { return database.mantraDao().addTranslationArtifactVersion( artifactId = artifactId, dialectId = dialectId, @@ -99,7 +99,7 @@ class DatabaseMantraRepository( originalText: String, chatRoomId: String, userPublicKey: HexKey, - ): MarmotInnerEvent? { + ): MantraChapter? { return database.mantraDao().addChapter( artifactId = artifactId, name = name, @@ -121,7 +121,7 @@ class DatabaseMantraRepository( country: String, language: String, userPublicKey: HexKey, - ): MarmotInnerEvent? { + ): MantraDialect? { return database.mantraDao().addDialect( localChatRoom = localChatRoom, name = name, @@ -140,7 +140,7 @@ class DatabaseMantraRepository( userPublicKey: HexKey, visibility: String, license: String, - ): MarmotInnerEvent? { + ): MantraArtifact? { return database.mantraDao().addArtifact( localChatRoom = localChatRoom, name = name, @@ -158,7 +158,7 @@ class DatabaseMantraRepository( artifactId: HexKey, versionLabel: String, userPublicKey: HexKey, - ): MarmotInnerEvent? { + ): MantraArtifactVersion? { return database.mantraDao().addArtifactVersion( localChatRoom = localChatRoom, artifactId = artifactId, 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 3ec50ddb..9d0b5d88 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/repository/MantraRepository.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/repository/MantraRepository.kt @@ -9,7 +9,6 @@ import press.mantra.compose.database.model.MantraDialect import press.mantra.compose.database.model.MantraTranslationArtifactVersion import press.mantra.compose.database.model.MantraTranslationChapter import press.mantra.compose.database.model.MantraTranslationChunk -import press.mantra.compose.database.model.MarmotInnerEvent import press.mantra.compose.database.model.intermdiate.LocalChatRoom interface MantraRepository { @@ -65,7 +64,7 @@ interface MantraRepository { dialectId: String, chatRoomId: String, userPublicKey: HexKey, - ): MarmotInnerEvent? + ): MantraTranslationArtifactVersion? /** * Add a chapter (markdown [originalText]) to the artifact's latest version. @@ -79,7 +78,7 @@ interface MantraRepository { originalText: String, chatRoomId: String, userPublicKey: HexKey, - ): MarmotInnerEvent? + ): MantraChapter? suspend fun getDialects(chatRoomId: String): List @@ -91,7 +90,7 @@ interface MantraRepository { country: String, language: String, userPublicKey: HexKey, - ): MarmotInnerEvent? + ): MantraDialect? suspend fun addArtifact( localChatRoom: LocalChatRoom, @@ -102,14 +101,14 @@ interface MantraRepository { userPublicKey: HexKey, visibility: String = DEFAULT_VISIBILITY, license: String = DEFAULT_LICENSE, - ): MarmotInnerEvent? + ): MantraArtifact? suspend fun addArtifactVersion( localChatRoom: LocalChatRoom, artifactId: HexKey, versionLabel: String, userPublicKey: HexKey, - ): MarmotInnerEvent? + ): MantraArtifactVersion? companion object { const val DEFAULT_VISIBILITY = "private" @@ -155,7 +154,7 @@ interface MantraRepository { dialectId: String, chatRoomId: String, userPublicKey: HexKey, - ): MarmotInnerEvent? = null + ): MantraTranslationArtifactVersion? = null override suspend fun addChapter( artifactId: String, @@ -163,7 +162,7 @@ interface MantraRepository { originalText: String, chatRoomId: String, userPublicKey: HexKey, - ): MarmotInnerEvent? = null + ): MantraChapter? = null override suspend fun getDialects(chatRoomId: String): List = emptyList() @@ -175,7 +174,7 @@ interface MantraRepository { country: String, language: String, userPublicKey: HexKey, - ): MarmotInnerEvent? = null + ): MantraDialect? = null override suspend fun addArtifact( localChatRoom: LocalChatRoom, @@ -186,14 +185,14 @@ interface MantraRepository { userPublicKey: HexKey, visibility: String, license: String, - ): MarmotInnerEvent? = null + ): MantraArtifact? = null override suspend fun addArtifactVersion( localChatRoom: LocalChatRoom, artifactId: HexKey, versionLabel: String, userPublicKey: HexKey, - ): MarmotInnerEvent? = null + ): MantraArtifactVersion? = null } } } diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/model/AddArtifactViewModel.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/model/AddArtifactViewModel.kt index cc90e468..98a02974 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/model/AddArtifactViewModel.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/model/AddArtifactViewModel.kt @@ -85,7 +85,7 @@ class AddArtifactViewModel( isActionPending.value = true viewModelScope.launch(Dispatchers.IO) { - val artifactInnerEvent = runCatching { + val artifact = runCatching { mantraRepository.addArtifact( localChatRoom = localChatRoom, name = name, @@ -100,13 +100,13 @@ class AddArtifactViewModel( logger.e("Failed to add artifact", error) }.getOrNull() - if (artifactInnerEvent != null) { + if (artifact != null) { nameField.clearText() urlField.clearText() versionLabelField.clearText() viewModelScope.launch(Dispatchers.Main) { - onSuccess.invoke(artifactInnerEvent.id) + onSuccess.invoke(artifact.id) } } else { viewModelScope.launch(Dispatchers.Main) { diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/model/AddDialectViewModel.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/model/AddDialectViewModel.kt index b4a3abfb..f0f655e7 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/model/AddDialectViewModel.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/view/model/AddDialectViewModel.kt @@ -76,7 +76,7 @@ class AddDialectViewModel( isActionPending.value = true viewModelScope.launch(Dispatchers.IO) { - val dialectInnerEvent = runCatching { + val dialect = runCatching { mantraRepository.addDialect( localChatRoom = localChatRoom, name = name, @@ -88,13 +88,13 @@ class AddDialectViewModel( logger.e("Failed to add dialect", error) }.getOrNull() - if (dialectInnerEvent != null) { + if (dialect != null) { nameField.clearText() countryField.clearText() languageField.clearText() viewModelScope.launch(Dispatchers.Main) { - onSuccess.invoke(dialectInnerEvent.id) + onSuccess.invoke(dialect.id) } } else { viewModelScope.launch(Dispatchers.Main) {