From 6e139384781f0fa8e2e9ce465fde44bb766b854e Mon Sep 17 00:00:00 2001 From: Kgothatso Ngako Date: Tue, 28 Jul 2026 09:29:15 +0200 Subject: [PATCH] Add and broadcast translation chunks version --- .../mantra/compose/database/dao/MantraDao.kt | 60 +++++++++++++++++++ .../repository/DatabaseMantraRepository.kt | 44 +------------- 2 files changed, 63 insertions(+), 41 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 223a4caf..62a44691 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 @@ -309,6 +309,7 @@ abstract class MantraDao( } } + @Transaction open suspend fun addTranslationArtifactVersion( artifactId: String, dialectId: String, @@ -433,6 +434,65 @@ abstract class MantraDao( } } + @Transaction + open suspend fun saveTranslation( + translationChapterId: String, + chunkId: String, + text: String, + chatRoomId: String, + userPublicKey: HexKey, + ): MantraTranslationChunk? { + // The translation chunk mirrors the source chunk's position. + val sourceChunk = database.mantraChunkDao().getChunkById(chunkId) ?: return null + + val translationChunkTemplate = TranslationChunkEvent.build( + translationChapterId = translationChapterId, + chunkId = chunkId, + index = sourceChunk.index, + text = text, + ) + val translationChunk = MantraTranslationChunk.fromTranslationChunkEventTemplate( + translationChunkEventTemplate = translationChunkTemplate, + chatRoomId = chatRoomId, + userPublicKey = userPublicKey, + ) ?: return null + + 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. + 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.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( + chatRoomId = chatRoomId, + userPublicKey = userPublicKey, + text = "Translated chunk ${translationChunk.index}", // TODO: Use a portion of the translation and name the language + marmotInnerEvent = translationChunkInnerEvent + ) + + translationChunk + } catch (error: Throwable) { + logger.e("Failed to save translation for chunk $chunkId", error) + null + } + } + private suspend fun sendMarmotInnerEvent( localChatRoom: LocalChatRoom, text: String, 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 d2a10cd8..5a5bcc6c 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 @@ -69,51 +69,13 @@ class DatabaseMantraRepository( chatRoomId: String, userPublicKey: HexKey, ): MantraTranslationChunk? { - // The translation chunk mirrors the source chunk's position. - val sourceChunk = database.mantraChunkDao().getChunkById(chunkId) ?: return null - - val translationChunkTemplate = TranslationChunkEvent.build( + return database.mantraDao().saveTranslation( translationChapterId = translationChapterId, chunkId = chunkId, - index = sourceChunk.index, text = text, - ) - val translationChunk = MantraTranslationChunk.fromTranslationChunkEventTemplate( - translationChunkEventTemplate = translationChunkTemplate, chatRoomId = chatRoomId, - userPublicKey = userPublicKey, - ) ?: return null - - 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. - 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.mantraTranslationChunkDao().upsert(translationChunk) - database.marmotInnerEventDao().upsert( - MarmotInnerEvent( - id = translationChunk.id, - publicKey = translationChunk.publicKey, - kind = TranslationChunkEvent.KIND, - createdAt = translationChunk.createdAt, - tags = translationChunkTemplate.tags, - content = translationChunkTemplate.content, - chatRoomId = translationChunk.chatRoomId, - ) - ) - - translationChunk - } catch (error: Throwable) { - logger.e("Failed to save translation for chunk $chunkId", error) - null - } + userPublicKey = userPublicKey + ) } override suspend fun getTranslationsForArtifact(artifactId: String): List =