From d2b64b5d9163932661135821fba7ecd7cc8bf856 Mon Sep 17 00:00:00 2001 From: Kgothatso Ngako Date: Fri, 17 Jul 2026 21:28:39 +0200 Subject: [PATCH] Maintain contributors with role attributor instead of exact role having it's own class --- .../mantra/compose/database/MantraDatabase.kt | 29 +++--- ...ranslationArtifactVersionContributorDao.kt | 11 +++ ...ntraTranslationArtifactVersionEditorDao.kt | 13 --- .../MantraTranslationChapterContributorDao.kt | 12 +++ .../MantraTranslationChapterProofReaderDao.kt | 11 --- .../MantraTranslationChapterTranslatorDao.kt | 13 --- .../dao/MantraTranslationContributorDao.kt | 11 +++ .../dao/MantraTranslationTranslatorDao.kt | 13 --- ...aTranslationArtifactVersionContributor.kt} | 19 ++-- ...=> MantraTranslationChapterContributor.kt} | 14 +-- .../MantraTranslationChapterProofReader.kt | 64 ------------- .../model/MantraTranslationContributor.kt | 95 +++++++++++++++++++ .../model/MantraTranslationTranslator.kt | 64 ------------- ...ionArtifactVersionContributorListEvent.kt} | 4 +- ...TranslationChapterContributorListEvent.kt} | 6 +- .../nostr/nip30303/TranslationChapterEvent.kt | 2 +- .../TranslationChapterTranslatorListEvent.kt | 37 -------- .../nostr/nip30303/TranslationChunkEvent.kt | 2 +- ....kt => TranslationContributorListEvent.kt} | 6 +- .../nostr/nip30303/tags/ContributorTag.kt | 52 ++++++++++ 20 files changed, 222 insertions(+), 256 deletions(-) create mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationArtifactVersionContributorDao.kt delete mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationArtifactVersionEditorDao.kt create mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationChapterContributorDao.kt delete mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationChapterProofReaderDao.kt delete mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationChapterTranslatorDao.kt create mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationContributorDao.kt delete mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationTranslatorDao.kt rename composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/{MantraTranslationArtifactVersionEditor.kt => MantraTranslationArtifactVersionContributor.kt} (76%) rename composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/{MantraTranslationChapterTranslator.kt => MantraTranslationChapterContributor.kt} (79%) delete mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapterProofReader.kt create mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationContributor.kt delete mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationTranslator.kt rename composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/{TranslationArtifactVersionEditorListEvent.kt => TranslationArtifactVersionContributorListEvent.kt} (88%) rename composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/{TranslationChapterProofReaderListEvent.kt => TranslationChapterContributorListEvent.kt} (87%) delete mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterTranslatorListEvent.kt rename composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/{TranslationTranslatorListEvent.kt => TranslationContributorListEvent.kt} (88%) create mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ContributorTag.kt diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/MantraDatabase.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/MantraDatabase.kt index 0991b2a5..351b8520 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/MantraDatabase.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/MantraDatabase.kt @@ -24,13 +24,12 @@ import press.mantra.compose.database.dao.MantraChapterDao import press.mantra.compose.database.dao.MantraChunkDao import press.mantra.compose.database.dao.MantraDialectDao import press.mantra.compose.database.dao.MantraTranslationArtifactVersionDao -import press.mantra.compose.database.dao.MantraTranslationArtifactVersionEditorDao +import press.mantra.compose.database.dao.MantraTranslationArtifactVersionContributorDao import press.mantra.compose.database.dao.MantraTranslationChapterDao -import press.mantra.compose.database.dao.MantraTranslationChapterProofReaderDao -import press.mantra.compose.database.dao.MantraTranslationChapterTranslatorDao +import press.mantra.compose.database.dao.MantraTranslationChapterContributorDao import press.mantra.compose.database.dao.MantraTranslationChunkDao import press.mantra.compose.database.dao.MantraTranslationDao -import press.mantra.compose.database.dao.MantraTranslationTranslatorDao +import press.mantra.compose.database.dao.MantraTranslationContributorDao import press.mantra.compose.database.dao.MarmotCommitResultDao import press.mantra.compose.database.dao.MarmotOutboundDao import press.mantra.compose.database.dao.MarmotGroupEventDao @@ -76,12 +75,11 @@ import press.mantra.compose.database.model.MantraChunk import press.mantra.compose.database.model.MantraDialect import press.mantra.compose.database.model.MantraTranslation import press.mantra.compose.database.model.MantraTranslationArtifactVersion -import press.mantra.compose.database.model.MantraTranslationArtifactVersionEditor +import press.mantra.compose.database.model.MantraTranslationArtifactVersionContributor import press.mantra.compose.database.model.MantraTranslationChapter -import press.mantra.compose.database.model.MantraTranslationChapterProofReader -import press.mantra.compose.database.model.MantraTranslationChapterTranslator +import press.mantra.compose.database.model.MantraTranslationChapterContributor import press.mantra.compose.database.model.MantraTranslationChunk -import press.mantra.compose.database.model.MantraTranslationTranslator +import press.mantra.compose.database.model.MantraTranslationContributor import press.mantra.compose.database.model.MarmotCommitResult import press.mantra.compose.database.model.MarmotGroupEvent import press.mantra.compose.database.model.MarmotInnerEvent @@ -130,12 +128,11 @@ val GENESIS_AT = Instant.fromEpochMilliseconds(1231006505000L) MantraDialect::class, MantraTranslation::class, MantraTranslationArtifactVersion::class, - MantraTranslationArtifactVersionEditor::class, + MantraTranslationArtifactVersionContributor::class, MantraTranslationChapter::class, - MantraTranslationChapterProofReader::class, - MantraTranslationChapterTranslator::class, + MantraTranslationChapterContributor::class, MantraTranslationChunk::class, - MantraTranslationTranslator::class, + MantraTranslationContributor::class, MarmotCommitResult::class, MarmotGroupEvent::class, MarmotInnerEvent::class, @@ -199,19 +196,17 @@ abstract class MantraDatabase: RoomDatabase() { abstract fun mantraTranslationArtifactVersionDao(): MantraTranslationArtifactVersionDao - abstract fun mantraTranslationArtifactVersionEditorDao(): MantraTranslationArtifactVersionEditorDao + abstract fun mantraTranslationArtifactVersionContributorDao(): MantraTranslationArtifactVersionContributorDao abstract fun mantraTranslationChapterDao(): MantraTranslationChapterDao - abstract fun mantraTranslationChapterProofReaderDao(): MantraTranslationChapterProofReaderDao - - abstract fun mantraTranslationChapterTranslatorDao(): MantraTranslationChapterTranslatorDao + abstract fun mantraTranslationChapterContributorDao(): MantraTranslationChapterContributorDao abstract fun mantraTranslationChunkDao(): MantraTranslationChunkDao abstract fun mantraTranslationDao(): MantraTranslationDao - abstract fun mantraTranslationTranslatorDao(): MantraTranslationTranslatorDao + abstract fun mantraTranslationContributorDao(): MantraTranslationContributorDao abstract fun marmotCommitResultDao(): MarmotCommitResultDao diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationArtifactVersionContributorDao.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationArtifactVersionContributorDao.kt new file mode 100644 index 00000000..be33e76c --- /dev/null +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationArtifactVersionContributorDao.kt @@ -0,0 +1,11 @@ +package press.mantra.compose.database.dao + +import androidx.room3.Dao +import androidx.room3.Upsert +import press.mantra.compose.database.model.MantraTranslationArtifactVersionContributor + +@Dao +interface MantraTranslationArtifactVersionContributorDao { + @Upsert + suspend fun upsert(mantraTranslationArtifactVersionContributor: MantraTranslationArtifactVersionContributor) +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationArtifactVersionEditorDao.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationArtifactVersionEditorDao.kt deleted file mode 100644 index e7b66edc..00000000 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationArtifactVersionEditorDao.kt +++ /dev/null @@ -1,13 +0,0 @@ -package press.mantra.compose.database.dao - -import androidx.room3.Dao -import androidx.room3.Insert -import androidx.room3.OnConflictStrategy.Companion.IGNORE -import androidx.room3.Upsert -import press.mantra.compose.database.model.MantraTranslationArtifactVersionEditor - -@Dao -interface MantraTranslationArtifactVersionEditorDao { - @Upsert - suspend fun upsert(mantraTranslationArtifactVersion: MantraTranslationArtifactVersionEditor) -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationChapterContributorDao.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationChapterContributorDao.kt new file mode 100644 index 00000000..da2b3b93 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationChapterContributorDao.kt @@ -0,0 +1,12 @@ +package press.mantra.compose.database.dao + +import androidx.room3.Dao +import androidx.room3.Upsert +import press.mantra.compose.database.model.MantraTranslationChapter +import press.mantra.compose.database.model.MantraTranslationChapterContributor + +@Dao +interface MantraTranslationChapterContributorDao { + @Upsert + suspend fun upsert(mantraTranslationChapterContributor: MantraTranslationChapterContributor) +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationChapterProofReaderDao.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationChapterProofReaderDao.kt deleted file mode 100644 index 21b22c70..00000000 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationChapterProofReaderDao.kt +++ /dev/null @@ -1,11 +0,0 @@ -package press.mantra.compose.database.dao - -import androidx.room3.Dao -import androidx.room3.Upsert -import press.mantra.compose.database.model.MantraTranslationChapterProofReader - -@Dao -interface MantraTranslationChapterProofReaderDao { - @Upsert - suspend fun upsert(mantraTranslationChapterProofReader: MantraTranslationChapterProofReader) -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationChapterTranslatorDao.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationChapterTranslatorDao.kt deleted file mode 100644 index 9ba4ada0..00000000 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationChapterTranslatorDao.kt +++ /dev/null @@ -1,13 +0,0 @@ -package press.mantra.compose.database.dao - -import androidx.room3.Dao -import androidx.room3.Insert -import androidx.room3.OnConflictStrategy.Companion.IGNORE -import androidx.room3.Upsert -import press.mantra.compose.database.model.MantraTranslationChapter - -@Dao -interface MantraTranslationChapterTranslatorDao { - @Upsert - suspend fun upsert(mantraTranslationChapter: MantraTranslationChapter) -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationContributorDao.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationContributorDao.kt new file mode 100644 index 00000000..36f7383e --- /dev/null +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationContributorDao.kt @@ -0,0 +1,11 @@ +package press.mantra.compose.database.dao + +import androidx.room3.Dao +import androidx.room3.Upsert +import press.mantra.compose.database.model.MantraTranslationContributor + +@Dao +interface MantraTranslationContributorDao { + @Upsert + suspend fun upsert(mantraTranslationContributor: MantraTranslationContributor) +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationTranslatorDao.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationTranslatorDao.kt deleted file mode 100644 index 3b7b6f6f..00000000 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/dao/MantraTranslationTranslatorDao.kt +++ /dev/null @@ -1,13 +0,0 @@ -package press.mantra.compose.database.dao - -import androidx.room3.Dao -import androidx.room3.Insert -import androidx.room3.OnConflictStrategy.Companion.IGNORE -import androidx.room3.Upsert -import press.mantra.compose.database.model.MantraTranslationTranslator - -@Dao -interface MantraTranslationTranslatorDao { - @Upsert - suspend fun upsert(mantraTranslationTranslator: MantraTranslationTranslator) -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationArtifactVersionEditor.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationArtifactVersionContributor.kt similarity index 76% rename from composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationArtifactVersionEditor.kt rename to composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationArtifactVersionContributor.kt index 639f8299..543f6554 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationArtifactVersionEditor.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationArtifactVersionContributor.kt @@ -4,12 +4,11 @@ import androidx.room3.Entity import androidx.room3.PrimaryKey import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nipF4Podcasts.metadata.tags.AuthorTag import com.vitorpamplona.quartz.utils.TimeUtils import press.mantra.compose.database.model.traits.OptionalNostrEventEntity import press.mantra.compose.database.model.traits.TimestampedEntity -import press.mantra.compose.nostr.nip30303.TranslationArtifactVersionEditorListEvent -import press.mantra.compose.nostr.nip30303.TranslationChapterProofReaderListEvent +import press.mantra.compose.nostr.nip30303.TranslationArtifactVersionContributorListEvent +import press.mantra.compose.nostr.nip30303.tags.ContributorTag import press.mantra.compose.nostr.nip30303.tags.TranslationArtifactVersionIdTag import kotlin.time.Clock import kotlin.time.Instant @@ -18,7 +17,7 @@ import kotlin.time.Instant * 30307 */ @Entity -data class MantraTranslationArtifactVersionEditor( +data class MantraTranslationArtifactVersionContributor( @PrimaryKey val id: HexKey, val publicKey: HexKey, @@ -42,19 +41,23 @@ data class MantraTranslationArtifactVersionEditor( ): OptionalNostrEventEntity, TimestampedEntity { companion object { - fun toTranslationChapterProofReaderListEvent(mantraTranslationChapterProofReaders: List): TranslationArtifactVersionEditorListEvent { + fun toTranslationChapterProofReaderListEvent(mantraTranslationChapterProofReaders: List): TranslationArtifactVersionContributorListEvent { // TODO: create TranslationChapterProofReaderListEvent from mantraTranslationChapterProofReaders - return TranslationArtifactVersionEditorListEvent( + return TranslationArtifactVersionContributorListEvent( id = "", pubKey = "", createdAt = TimeUtils.now(), - tags = TagArrayBuilder() + tags = TagArrayBuilder() + .addUnique( TranslationArtifactVersionIdTag.assemble("") // TODO: use actual value.. ) // TODO: Add tag for editorPublicKey .addUnique( - AuthorTag.assemble("") // TODO: Get piblicKeyList... + ContributorTag.assemble( + "", + ContributorTag.ROLE_EDITOR + ) ) .build(), content = "", diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapterTranslator.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapterContributor.kt similarity index 79% rename from composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapterTranslator.kt rename to composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapterContributor.kt index 996fefba..59426302 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapterTranslator.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapterContributor.kt @@ -8,7 +8,8 @@ import com.vitorpamplona.quartz.nipF4Podcasts.metadata.tags.AuthorTag import com.vitorpamplona.quartz.utils.TimeUtils import press.mantra.compose.database.model.traits.OptionalNostrEventEntity import press.mantra.compose.database.model.traits.TimestampedEntity -import press.mantra.compose.nostr.nip30303.TranslationChapterTranslatorListEvent +import press.mantra.compose.nostr.nip30303.TranslationChapterContributorListEvent +import press.mantra.compose.nostr.nip30303.tags.ContributorTag import press.mantra.compose.nostr.nip30303.tags.TranslationChapterIdTag import kotlin.time.Clock import kotlin.time.Instant @@ -17,13 +18,14 @@ import kotlin.time.Instant * 30310 */ @Entity -data class MantraTranslationChapterTranslator( +data class MantraTranslationChapterContributor( @PrimaryKey val id: HexKey, val publicKey: HexKey, val translationChapterId: HexKey, val translatorPublicKey: HexKey, + val role: String, /** * Signature will be an empty string if this is a rumor */ @@ -41,18 +43,18 @@ data class MantraTranslationChapterTranslator( ): OptionalNostrEventEntity, TimestampedEntity { companion object { - fun toTranslationChapterTranslatorListEvent(mantraTranslationChapterTranslators: List): TranslationChapterTranslatorListEvent { + fun toTranslationChapterTranslatorListEvent(mantraTranslationChapterTranslators: List): TranslationChapterContributorListEvent { // TODO: create TranslationChapterProofReaderListEvent from mantraTranslationChapterProofReaders - return TranslationChapterTranslatorListEvent( + return TranslationChapterContributorListEvent( id = "", pubKey = "", createdAt = TimeUtils.now(), - tags = TagArrayBuilder() + tags = TagArrayBuilder() .addUnique( TranslationChapterIdTag.assemble("") ) .addUnique( - AuthorTag.assemble("") // TODO: PublicKeyListTag + ContributorTag.assemble("", ContributorTag.ROLE_TRANSLATOR) ) .build(), content = "", diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapterProofReader.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapterProofReader.kt deleted file mode 100644 index 5264f3cd..00000000 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapterProofReader.kt +++ /dev/null @@ -1,64 +0,0 @@ -package press.mantra.compose.database.model - -import androidx.room3.Entity -import androidx.room3.PrimaryKey -import com.vitorpamplona.quartz.nip01Core.core.HexKey -import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nipF4Podcasts.metadata.tags.AuthorTag -import com.vitorpamplona.quartz.utils.TimeUtils -import press.mantra.compose.database.model.traits.OptionalNostrEventEntity -import press.mantra.compose.database.model.traits.TimestampedEntity -import press.mantra.compose.nostr.nip30303.TranslationChapterProofReaderListEvent -import press.mantra.compose.nostr.nip30303.tags.TranslationChapterIdTag -import kotlin.time.Clock -import kotlin.time.Instant - -/** - * 30309 - */ -@Entity -data class MantraTranslationChapterProofReader( - @PrimaryKey - val id: HexKey, - val publicKey: HexKey, - val translationChapterId: HexKey, - val proofReaderPublicKey: HexKey, - - /** - * Signature will be an empty string if this is a rumor - */ - val signature: String, - - val relayHint: String? = null, - val marmotGroupEventId: HexKey? = null, - - /** - * Related nostrEventId if this is not a rumor... - */ - override val nostrEventId: HexKey? = null, - override val createdAt: Instant = Clock.System.now(), - override val updatedAt: Instant = createdAt -): OptionalNostrEventEntity, TimestampedEntity { - - companion object { - fun toTranslationChapterProofReaderListEvent(mantraTranslationChapterProofReaders: List): TranslationChapterProofReaderListEvent { - // TODO: create TranslationChapterProofReaderListEvent from mantraTranslationChapterProofReaders - return TranslationChapterProofReaderListEvent( - id = "", - pubKey = "", - createdAt = TimeUtils.now(), - tags = TagArrayBuilder() - .addUnique( - TranslationChapterIdTag.assemble("") - ) - .addUnique( - AuthorTag.assemble("") // TODO: PublicKeyListTag - ) - .build(), - content = "", - sig = "" - ) - } - } -} - diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationContributor.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationContributor.kt new file mode 100644 index 00000000..d0d77733 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationContributor.kt @@ -0,0 +1,95 @@ +package press.mantra.compose.database.model + +import androidx.room3.Entity +import androidx.room3.PrimaryKey +import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.crypto.EventHasher +import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate +import com.vitorpamplona.quartz.nip01Core.tags.dTag.DTag +import com.vitorpamplona.quartz.nip31Alts.alt +import press.mantra.compose.database.model.traits.OptionalNostrEventEntity +import press.mantra.compose.database.model.traits.TimestampedEntity +import press.mantra.compose.nostr.nip30303.TranslationContributorListEvent +import press.mantra.compose.nostr.nip30303.tags.ContributorTag +import kotlin.time.Clock +import kotlin.time.Instant + +/** + * 30312 + */ +@Entity +data class MantraTranslationContributor( + @PrimaryKey + val id: HexKey, + val dTag: String, + val publicKey: HexKey, + val translationId: HexKey, + val translatorPublicKey: HexKey, + + /** + * Signature will be an empty string if this is a rumor + */ + val signature: String, + + val relayHint: String? = null, + val marmotGroupEventId: HexKey? = null, + /** + * Related nostrEventId if this is not a rumor... + */ + override val nostrEventId: HexKey? = null, + override val createdAt: Instant = Clock.System.now(), + override val updatedAt: Instant = createdAt +): OptionalNostrEventEntity, TimestampedEntity { + + companion object { + fun toTranslationChapterProofReaderListEvent(mantraTranslationContributors: List): TranslationContributorListEvent? { + mantraTranslationContributors.firstOrNull()?.let { firstMantraTranslationTranslator -> + val allFromSameEvent = mantraTranslationContributors.all { + it.publicKey == firstMantraTranslationTranslator.publicKey + && it.createdAt == firstMantraTranslationTranslator.createdAt + && it.dTag == firstMantraTranslationTranslator.dTag + } + + if (allFromSameEvent) { + val translatorPublicKeys = mantraTranslationContributors.map { + ContributorTag.assemble( + pubKey = it.publicKey, + role = ContributorTag.ROLE_TRANSLATOR + ) + } + val template = eventTemplate( + kind = TranslationContributorListEvent.KIND, + description = "", + createdAt = firstMantraTranslationTranslator.createdAt.epochSeconds + ) { + addUnique( + DTag.assemble( + firstMantraTranslationTranslator.dTag + ) + ) + alt(TranslationContributorListEvent.ALT_DESCRIPTION) + + } + + + return TranslationContributorListEvent( + id = EventHasher.hashId( + pubKey = firstMantraTranslationTranslator.publicKey, + tags = template.tags, + createdAt = template.createdAt, + content = template.content, + kind = template.kind + ), + pubKey = firstMantraTranslationTranslator.publicKey, + createdAt = firstMantraTranslationTranslator.createdAt.epochSeconds, + tags = translatorPublicKeys.toTypedArray(), + content = template.content, + sig = firstMantraTranslationTranslator.signature + ) + } + } + return null + } + } +} + diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationTranslator.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationTranslator.kt deleted file mode 100644 index 69c3218d..00000000 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationTranslator.kt +++ /dev/null @@ -1,64 +0,0 @@ -package press.mantra.compose.database.model - -import androidx.room3.Entity -import androidx.room3.PrimaryKey -import com.vitorpamplona.quartz.nip01Core.core.HexKey -import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nipF4Podcasts.metadata.tags.AuthorTag -import com.vitorpamplona.quartz.utils.TimeUtils -import press.mantra.compose.database.model.traits.OptionalNostrEventEntity -import press.mantra.compose.database.model.traits.TimestampedEntity -import press.mantra.compose.nostr.nip30303.TranslationTranslatorListEvent -import press.mantra.compose.nostr.nip30303.tags.TranslationIdTag -import kotlin.time.Clock -import kotlin.time.Instant - -/** - * 30312 - */ -@Entity -data class MantraTranslationTranslator( - @PrimaryKey - val id: HexKey, - val publicKey: HexKey, - val translationId: HexKey, - val translatorPublicKey: HexKey, - - /** - * Signature will be an empty string if this is a rumor - */ - val signature: String, - - val relayHint: String? = null, - val marmotGroupEventId: HexKey? = null, - - /** - * Related nostrEventId if this is not a rumor... - */ - override val nostrEventId: HexKey? = null, - override val createdAt: Instant = Clock.System.now(), - override val updatedAt: Instant = createdAt -): OptionalNostrEventEntity, TimestampedEntity { - - companion object { - fun toTranslationChapterProofReaderListEvent(mantraTranslationChapterProofReaders: List): TranslationTranslatorListEvent { - // TODO: create TranslationChapterProofReaderListEvent from mantraTranslationChapterProofReaders - return TranslationTranslatorListEvent( - id = "", - pubKey = "", - createdAt = TimeUtils.now(), - tags = TagArrayBuilder() - .addUnique( - TranslationIdTag.assemble("") // TODO: Use actual translationId - ) - .addUnique( - AuthorTag.assemble("") // TODO: PublicKeyListTag - ) - .build(), - content = "", - sig = "" - ) - } - } -} - diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationArtifactVersionEditorListEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationArtifactVersionContributorListEvent.kt similarity index 88% rename from composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationArtifactVersionEditorListEvent.kt rename to composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationArtifactVersionContributorListEvent.kt index 5337c131..14af67f4 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationArtifactVersionEditorListEvent.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationArtifactVersionContributorListEvent.kt @@ -12,7 +12,7 @@ import com.vitorpamplona.quartz.utils.TimeUtils @Immutable -class TranslationArtifactVersionEditorListEvent( +class TranslationArtifactVersionContributorListEvent( id: HexKey, pubKey: HexKey, createdAt: Long, @@ -23,7 +23,7 @@ class TranslationArtifactVersionEditorListEvent( companion object { const val KIND = 30305 - const val ALT_DESCRIPTION = "TranslationArtifactVersionEditorList" + const val ALT_DESCRIPTION = "TranslationArtifactVersionContributorListEvent" fun build( content: String, diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterProofReaderListEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterContributorListEvent.kt similarity index 87% rename from composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterProofReaderListEvent.kt rename to composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterContributorListEvent.kt index 71519333..f32126a9 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterProofReaderListEvent.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterContributorListEvent.kt @@ -12,7 +12,7 @@ import com.vitorpamplona.quartz.utils.TimeUtils @Immutable -class TranslationChapterProofReaderListEvent( +class TranslationChapterContributorListEvent( id: HexKey, pubKey: HexKey, createdAt: Long, @@ -22,8 +22,8 @@ class TranslationChapterProofReaderListEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { - const val KIND = 30308 - const val ALT_DESCRIPTION = "TranslationChapterProofReaderList" + const val KIND = 30307 + const val ALT_DESCRIPTION = "TranslationChapterContributorListEvent" fun build( content: String, diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterEvent.kt index a8bb1cd4..f5725bac 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterEvent.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterEvent.kt @@ -22,7 +22,7 @@ class TranslationChapterEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { - const val KIND = 30307 + const val KIND = 30308 const val ALT_DESCRIPTION = "TranslationChapter" fun build( diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterTranslatorListEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterTranslatorListEvent.kt deleted file mode 100644 index 6fbe58f6..00000000 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChapterTranslatorListEvent.kt +++ /dev/null @@ -1,37 +0,0 @@ -package press.mantra.compose.nostr.nip30303 - -import androidx.compose.runtime.Immutable -import com.vitorpamplona.quartz.nip01Core.core.Event -import com.vitorpamplona.quartz.nip01Core.core.HexKey -import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip22Comments.RootScope -import com.vitorpamplona.quartz.nip31Alts.alt -import com.vitorpamplona.quartz.nip50Search.SearchableEvent -import com.vitorpamplona.quartz.utils.TimeUtils - - -@Immutable -class TranslationChapterTranslatorListEvent( - id: HexKey, - pubKey: HexKey, - createdAt: Long, - tags: Array>, - content: String, - sig: HexKey, -) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { - - companion object { - const val KIND = 30309 - const val ALT_DESCRIPTION = "TranslationChapterTranslatorList" - - fun build( - content: String, - createdAt: Long = TimeUtils.now(), - initializer: TagArrayBuilder.() -> Unit = {}, - ) = eventTemplate(KIND, content, createdAt) { - alt(ALT_DESCRIPTION) - initializer() - } - } -} diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChunkEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChunkEvent.kt index 08ccd0f5..2ceeb5bc 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChunkEvent.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationChunkEvent.kt @@ -22,7 +22,7 @@ class TranslationChunkEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { - const val KIND = 30310 + const val KIND = 30309 const val ALT_DESCRIPTION = "TranslationChunk" fun build( diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationTranslatorListEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationContributorListEvent.kt similarity index 88% rename from composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationTranslatorListEvent.kt rename to composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationContributorListEvent.kt index ffb85863..e2c2d026 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationTranslatorListEvent.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationContributorListEvent.kt @@ -12,7 +12,7 @@ import com.vitorpamplona.quartz.utils.TimeUtils @Immutable -class TranslationTranslatorListEvent( +class TranslationContributorListEvent( id: HexKey, pubKey: HexKey, createdAt: Long, @@ -22,8 +22,8 @@ class TranslationTranslatorListEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { - const val KIND = 30312 - const val ALT_DESCRIPTION = "TranslationTranslatorList" + const val KIND = 30310 + const val ALT_DESCRIPTION = "TranslationContributorListEvent" fun build( content: String, diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ContributorTag.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ContributorTag.kt new file mode 100644 index 00000000..d73e9e3e --- /dev/null +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ContributorTag.kt @@ -0,0 +1,52 @@ +package press.mantra.compose.nostr.nip30303.tags + +import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +/** + * Based on NIP-F4 + */ +class ContributorTag( + val pubKey: HexKey, + val role: String? = null, +) { + fun toTagArray() = assemble(pubKey, role) + + companion object { + const val TAG_NAME = "p" + + const val ROLE_TRANSLATOR = "translator" + const val ROLE_PROOF_READER = "proofreader" + const val ROLE_EDITOR = "editor" + + private val KNOWN_ROLES = setOf(ROLE_TRANSLATOR, ROLE_PROOF_READER, ROLE_EDITOR) + + fun isTagged(tag: Array) = tag.has(1) && tag[0] == TAG_NAME && tag[1].length == 64 + + fun parse(tag: Array): ContributorTag? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(tag[1].length == 64) { return null } + // NIP-F4 overloads slot 2 as role — but only host/cohost/editor are spec-defined. + // Anything else (notably a stale relay-hint URL copied from a kind:3 p-tag) gets + // dropped so it doesn't render as 'Role: wss://relay…' under the author chip. + val role = tag.getOrNull(2)?.takeIf { it in KNOWN_ROLES } + return ContributorTag(tag[1], role) + } + + fun assemble( + pubKey: HexKey, + role: String? = null, + ): Array = + if (role.isNullOrEmpty()) { + arrayOf(TAG_NAME, pubKey) + } else { + arrayOf(TAG_NAME, pubKey, role) + } + + fun assemble(author: ContributorTag) = assemble(author.pubKey, author.role) + + fun assemble(authors: List) = authors.map { assemble(it) } + } +} \ No newline at end of file