From 1b19c6a1be7adfa0b7206ceccf4b176ce3b05ffc Mon Sep 17 00:00:00 2001 From: Kgothatso Ngako Date: Sun, 19 Jul 2026 19:15:42 +0200 Subject: [PATCH] Create nostr events from database data --- .../compose/database/model/MantraArtifact.kt | 36 +++++++- .../database/model/MantraArtifactVersion.kt | 30 ++++++- .../compose/database/model/MantraChapter.kt | 50 ++++++++++- .../compose/database/model/MantraChunk.kt | 43 ++++++++- .../compose/database/model/MantraDialect.kt | 36 +++++++- .../database/model/MantraTranslation.kt | 24 ++++- .../model/MantraTranslationArtifactVersion.kt | 32 +++++++ .../model/MantraTranslationChapter.kt | 25 ++++++ .../database/model/MantraTranslationChunk.kt | 30 ++++++- .../compose/nostr/nip30303/ArtifactEvent.kt | 10 +++ .../nostr/nip30303/ArtifactVersionEvent.kt | 7 ++ .../compose/nostr/nip30303/ChapterEvent.kt | 18 +++- .../compose/nostr/nip30303/ChunkEvent.kt | 11 +++ .../compose/nostr/nip30303/DialectEvent.kt | 6 ++ .../TranslationArtifactVersionEvent.kt | 13 ++- .../nostr/nip30303/TranslationChapterEvent.kt | 11 +++ .../nostr/nip30303/TranslationChunkEvent.kt | 12 +++ .../nostr/nip30303/TranslationEvent.kt | 8 ++ .../nip30303/tags/ArtifactMetadataTag.kt | 49 ++++++++++ .../tags/ArtifactVersionMetadataTag.kt | 36 ++++++++ .../nostr/nip30303/tags/ChapterMetadataTag.kt | 42 +++++++++ .../nostr/nip30303/tags/DialectMetadataTag.kt | 48 ++++++++++ .../compose/nostr/nip30303/tags/IndexTag.kt | 36 ++++++++ .../TranslationArtifactVersionMetadataTag.kt | 49 ++++++++++ .../nostr/nip30303/tags/WordStatisticsTag.kt | 42 +++++++++ .../ui/composable/ChatRoomDetailScreen.kt | 90 ++++++++++++++++++- 26 files changed, 771 insertions(+), 23 deletions(-) create mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ArtifactMetadataTag.kt create mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ArtifactVersionMetadataTag.kt create mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ChapterMetadataTag.kt create mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/DialectMetadataTag.kt create mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/IndexTag.kt create mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/TranslationArtifactVersionMetadataTag.kt create mode 100644 composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/WordStatisticsTag.kt diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraArtifact.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraArtifact.kt index d7ff1818..5063eadd 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraArtifact.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraArtifact.kt @@ -4,9 +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.nip31Alts.AltTag import press.mantra.compose.database.model.traits.OptionalNostrEventEntity import press.mantra.compose.database.model.traits.TimestampedEntity import press.mantra.compose.nostr.nip30303.ArtifactEvent +import press.mantra.compose.nostr.nip30303.tags.ArtifactMetadataTag import press.mantra.compose.nostr.nip30303.tags.DialectIdTag import kotlin.time.Clock import kotlin.time.Instant @@ -19,10 +21,10 @@ data class MantraArtifact( @PrimaryKey val id: HexKey, val publicKey: String, + val name: String, val url: String, // Hash this to get the dTag... val visibility: String, // public, private, permissioned (public, but only members can contribute) val dialectId: String, - val copyrightOwner: String, // Put this in artifactContributor val license: String, // val artifactApprovalId: String, @@ -47,12 +49,42 @@ data class MantraArtifact( pubKey = publicKey, createdAt = createdAt.epochSeconds, tags = TagArrayBuilder() + .addUnique( + ArtifactMetadataTag.assemble( + url = url, + visibility = visibility, + license = license + ) + ) .addUnique( DialectIdTag.assemble(dialectId) ) + .addUnique( + AltTag.assemble(ArtifactEvent.ALT_DESCRIPTION) + ) .build(), - content = "", + content = name, sig = signature ) } + + companion object { + fun fromArtifactEvent(artifactEvent: ArtifactEvent): MantraArtifact? { + return artifactEvent.artifactMetadata?.let { artifactMetadata -> + artifactEvent.dialectId()?.let { dialectId -> + MantraArtifact( + id = artifactEvent.id, + publicKey = artifactEvent.pubKey, + dialectId = dialectId, + createdAt = Instant.fromEpochSeconds(artifactEvent.createdAt), + url = artifactMetadata.url, + license = artifactMetadata.license, + visibility = artifactMetadata.visibility, + name = artifactEvent.content, + signature = artifactEvent.sig, + ) + } + } + } + } } diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraArtifactVersion.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraArtifactVersion.kt index c9f24107..133cbe07 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraArtifactVersion.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraArtifactVersion.kt @@ -5,10 +5,12 @@ import androidx.room3.ForeignKey import androidx.room3.PrimaryKey import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder +import com.vitorpamplona.quartz.nip31Alts.AltTag import press.mantra.compose.database.model.traits.OptionalNostrEventEntity import press.mantra.compose.database.model.traits.TimestampedEntity import press.mantra.compose.nostr.nip30303.ArtifactVersionEvent import press.mantra.compose.nostr.nip30303.tags.ArtifactIdTag +import press.mantra.compose.nostr.nip30303.tags.ArtifactVersionMetadataTag import kotlin.time.Clock import kotlin.time.Instant @@ -57,11 +59,31 @@ data class MantraArtifactVersion( id = id, pubKey = publicKey, createdAt = createdAt.epochSeconds, - tags = TagArrayBuilder().addUnique( - ArtifactIdTag.assemble(artifactId) - ).build(), - content = "", + tags = TagArrayBuilder() + .addUnique( + ArtifactIdTag.assemble(artifactId) + ) + .addUnique( + AltTag.assemble(ArtifactVersionEvent.ALT_DESCRIPTION) + ) + .build(), + content = versionLabel, sig = signature ) } + + companion object { + fun fromArtifactVersionEvent(artifactVersionEvent: ArtifactVersionEvent): MantraArtifactVersion? { + return artifactVersionEvent.artifactId()?.let { artifactId -> + MantraArtifactVersion( + id = artifactVersionEvent.id, + publicKey = artifactVersionEvent.pubKey, + createdAt = Instant.fromEpochSeconds(artifactVersionEvent.createdAt), + artifactId = artifactId, + versionLabel = artifactVersionEvent.content, + signature = artifactVersionEvent.sig + ) + } + } + } } diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraChapter.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraChapter.kt index 1bce85c9..a36d0bc8 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraChapter.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraChapter.kt @@ -10,6 +10,9 @@ import press.mantra.compose.database.model.traits.TimestampedEntity import press.mantra.compose.nostr.nip30303.ArtifactVersionEvent import press.mantra.compose.nostr.nip30303.ChapterEvent import press.mantra.compose.nostr.nip30303.tags.ArtifactVersionIdTag +import press.mantra.compose.nostr.nip30303.tags.ChapterMetadataTag +import press.mantra.compose.nostr.nip30303.tags.IndexTag +import press.mantra.compose.nostr.nip30303.tags.WordStatisticsTag import kotlin.time.Clock import kotlin.time.Instant @@ -59,11 +62,52 @@ data class MantraChapter( id = id, pubKey = publicKey, createdAt = createdAt.epochSeconds, - tags = TagArrayBuilder().addUnique( - ArtifactVersionIdTag.assemble(artifactVersionId) - ).build(), + tags = TagArrayBuilder() + .addUnique( + ArtifactVersionIdTag.assemble(artifactVersionId) + ) + .addUnique( + ChapterMetadataTag.assemble( + name = name, + originalText = originalText, + ) + ) + .addUnique( + IndexTag.assemble( + index + ) + ) + .addUnique( + WordStatisticsTag.assemble(wordCount, characterCount) + ) + .build(), content = "", sig = signature ) } + + companion object { + fun fromChapterEvent(chapterEvent: ChapterEvent): MantraChapter? { + return chapterEvent.chapterMetadata?.let { chapterMetadata -> + chapterEvent.wordStatisticsTag?.let { wordStatisticsTag -> + chapterEvent.artifactVersionId()?.let { artifactId -> + chapterEvent.index()?.let { index -> + MantraChapter( + id = chapterEvent.id, + publicKey = chapterEvent.pubKey, + createdAt = Instant.fromEpochSeconds(chapterEvent.createdAt), + artifactVersionId = artifactId, + name = chapterMetadata.name, + originalText = chapterMetadata.originalText, + index = index, + wordCount = wordStatisticsTag.wordCount, + characterCount = wordStatisticsTag.characterCount, + signature = chapterEvent.sig + ) + } + } + } + } + } + } } diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraChunk.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraChunk.kt index e7358789..38329735 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraChunk.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraChunk.kt @@ -9,6 +9,8 @@ import press.mantra.compose.database.model.traits.OptionalNostrEventEntity import press.mantra.compose.database.model.traits.TimestampedEntity import press.mantra.compose.nostr.nip30303.ChunkEvent import press.mantra.compose.nostr.nip30303.tags.ChapterIdTag +import press.mantra.compose.nostr.nip30303.tags.IndexTag +import press.mantra.compose.nostr.nip30303.tags.WordStatisticsTag import kotlin.time.Clock import kotlin.time.Instant @@ -56,11 +58,44 @@ data class MantraChunk( id = id, pubKey = publicKey, createdAt = createdAt.epochSeconds, - tags = TagArrayBuilder().addUnique( - ChapterIdTag.assemble(chapterId) - ).build(), - content = "", + tags = TagArrayBuilder() + .addUnique( + ChapterIdTag.assemble(chapterId) + ) + .addUnique( + IndexTag.assemble( + index + ) + ) + .addUnique( + WordStatisticsTag.assemble(wordCount, characterCount) + ) + .build(), + content = text, sig = signature ) } + + companion object { + fun fromChunkEvent(chunkEvent: ChunkEvent): MantraChunk? { + return chunkEvent.wordStatisticsTag?.let { wordStatisticsTag -> + chunkEvent.index()?.let { index -> + chunkEvent.chapterId()?.let { chapterId -> + MantraChunk( + id = chunkEvent.id, + publicKey = chunkEvent.pubKey, + createdAt = Instant.fromEpochSeconds(chunkEvent.createdAt), + index = index, + wordCount = wordStatisticsTag.wordCount, + characterCount = wordStatisticsTag.characterCount, + chapterId = chapterId, + text = chunkEvent.content, + signature = chunkEvent.sig + ) + } + + } + } + } + } } diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraDialect.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraDialect.kt index f591dec6..a0f5c168 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraDialect.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraDialect.kt @@ -3,9 +3,13 @@ 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 press.mantra.compose.database.model.traits.OptionalNostrEventEntity import press.mantra.compose.database.model.traits.TimestampedEntity +import press.mantra.compose.nostr.nip30303.ChunkEvent import press.mantra.compose.nostr.nip30303.DialectEvent +import press.mantra.compose.nostr.nip30303.tags.ChapterIdTag +import press.mantra.compose.nostr.nip30303.tags.DialectMetadataTag import kotlin.time.Clock import kotlin.time.Instant @@ -39,10 +43,38 @@ data class MantraDialect( id = id, pubKey = publicKey, createdAt = createdAt.epochSeconds, - tags = emptyArray(), - content = "", + tags = TagArrayBuilder() + .addUnique( + DialectMetadataTag.assemble( + name = name, + country = country, + language = language + ) + ) + .build(), + content = language, // TODO: Consider using the isoCode... as content? sig = signature ) } + companion object { + fun fromDialectEvent(dialectEvent: DialectEvent): MantraDialect? { + return dialectEvent.name()?.let { name -> + dialectEvent.language()?.let { language -> + dialectEvent.country()?.let { country -> + + MantraDialect( + id = dialectEvent.id, + publicKey = dialectEvent.pubKey, + createdAt = Instant.fromEpochSeconds(dialectEvent.createdAt), + name = name, + language = language, + country = country, + signature = dialectEvent.sig + ) + } + } + } + } + } } diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslation.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslation.kt index 15c4dd69..b18c64c7 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslation.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslation.kt @@ -5,6 +5,7 @@ import androidx.room3.ForeignKey import androidx.room3.PrimaryKey import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder +import com.vitorpamplona.quartz.utils.ensure import press.mantra.compose.database.model.traits.OptionalNostrEventEntity import press.mantra.compose.database.model.traits.TimestampedEntity import press.mantra.compose.nostr.nip30303.TranslationEvent @@ -66,8 +67,29 @@ data class MantraTranslation( TranslationChunkIdTag.assemble(translationChunkId) ) .build(), - content = "", + content = text, sig = signature ) } + + companion object { + fun fromTranslationEvent(translationEvent: TranslationEvent): MantraTranslation? { + ensure(translationEvent.translationChunkId() != null) { return null} + ensure(translationEvent.translationArtifactVersionId() != null) { return null} + + return translationEvent.translationChunkId()?.let { translationChunkId -> + translationEvent.translationArtifactVersionId()?.let { translationArtifactVersionId -> + MantraTranslation( + id = translationEvent.id, + publicKey = translationEvent.pubKey, + createdAt = Instant.fromEpochSeconds(translationEvent.createdAt), + text = translationEvent.content, + translationChunkId = translationChunkId, + translationArtifactVersionId = translationArtifactVersionId, + signature = translationEvent.sig + ) + } + } + } + } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationArtifactVersion.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationArtifactVersion.kt index 446da0fd..4f857ee3 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationArtifactVersion.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationArtifactVersion.kt @@ -11,6 +11,7 @@ import press.mantra.compose.nostr.nip30303.ArtifactVersionEvent import press.mantra.compose.nostr.nip30303.TranslationArtifactVersionEvent import press.mantra.compose.nostr.nip30303.tags.ArtifactVersionIdTag import press.mantra.compose.nostr.nip30303.tags.DialectIdTag +import press.mantra.compose.nostr.nip30303.tags.TranslationArtifactVersionMetadataTag import kotlin.time.Clock import kotlin.time.Instant @@ -35,6 +36,7 @@ data class MantraTranslationArtifactVersion( val dialectId: HexKey, val name: String, val visibility: String, + val license: String, /** * Signature will be an empty string if this is a rumor @@ -64,10 +66,40 @@ data class MantraTranslationArtifactVersion( .addUnique( DialectIdTag.assemble(dialectId) ) + .addUnique( + TranslationArtifactVersionMetadataTag.assemble( + name = name, + visibility = visibility, + license = license + ) + ) .build(), content = "", sig = signature ) } + + companion object { + fun fromTranslationArtifactVersionEvent(translationArtifactVersionEvent: TranslationArtifactVersionEvent): MantraTranslationArtifactVersion? { + + return translationArtifactVersionEvent.artifactVersionId()?.let { artifactVersionId -> + translationArtifactVersionEvent.dialectId()?.let { dialectId -> + translationArtifactVersionEvent.translationArtifactVersionMetadata?.let { translationArtifactVersionMetadata -> + MantraTranslationArtifactVersion( + id = translationArtifactVersionEvent.id, + publicKey = translationArtifactVersionEvent.pubKey, + createdAt = Instant.fromEpochSeconds(translationArtifactVersionEvent.createdAt), + artifactVersionId = artifactVersionId, + dialectId = dialectId, + name = translationArtifactVersionMetadata.name, + visibility = translationArtifactVersionMetadata.visibility, + license = translationArtifactVersionMetadata.license, + signature = translationArtifactVersionEvent.sig + ) + } + } + } + } + } } diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapter.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapter.kt index b4259d8a..9085eab3 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapter.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChapter.kt @@ -6,8 +6,10 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import press.mantra.compose.database.model.traits.OptionalNostrEventEntity import press.mantra.compose.database.model.traits.TimestampedEntity +import press.mantra.compose.nostr.nip30303.ChapterEvent import press.mantra.compose.nostr.nip30303.TranslationChapterEvent import press.mantra.compose.nostr.nip30303.tags.ChapterIdTag +import press.mantra.compose.nostr.nip30303.tags.IndexTag import press.mantra.compose.nostr.nip30303.tags.TranslationArtifactVersionIdTag import kotlin.time.Clock import kotlin.time.Instant @@ -59,10 +61,33 @@ data class MantraTranslationChapter( .addUnique( ChapterIdTag.assemble(chapterId) ) + .addUnique( + IndexTag.assemble(index) + ) .build(), content = "", sig = signature ) } + + companion object { + fun fromTranslationChapterEvent(translationChapterEvent: TranslationChapterEvent): MantraTranslationChapter? { + return translationChapterEvent.chapterId()?.let { chapterId -> + translationChapterEvent.translationArtifactVersionId()?.let { translationArtifactVersionId -> + translationChapterEvent.index()?.let { index -> + MantraTranslationChapter( + id = translationChapterEvent.id, + publicKey = translationChapterEvent.pubKey, + createdAt = Instant.fromEpochSeconds(translationChapterEvent.createdAt), + chapterId = chapterId, + translationArtifactVersionId = translationArtifactVersionId, + index = index, + signature = translationChapterEvent.sig + ) + } + } + } + } + } } diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChunk.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChunk.kt index 647516b5..8f93189f 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChunk.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/model/MantraTranslationChunk.kt @@ -7,8 +7,10 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import press.mantra.compose.database.model.traits.OptionalNostrEventEntity import press.mantra.compose.database.model.traits.TimestampedEntity +import press.mantra.compose.nostr.nip30303.ChunkEvent import press.mantra.compose.nostr.nip30303.TranslationChunkEvent import press.mantra.compose.nostr.nip30303.tags.ChunkIdTag +import press.mantra.compose.nostr.nip30303.tags.IndexTag import press.mantra.compose.nostr.nip30303.tags.TranslationChapterIdTag import kotlin.time.Clock import kotlin.time.Instant @@ -67,11 +69,35 @@ data class MantraTranslationChunk( TranslationChapterIdTag.assemble(translationChapterId) ) .addUnique( - ChunkIdTag.assemble(chunkId) // TODO: PublicKeyListTag + ChunkIdTag.assemble(chunkId) + ) + .addUnique( + IndexTag.assemble(index) ) .build(), - content = "", + content = text, sig = signature ) } + + companion object { + fun fromTranslationChunkEvent(translationChunkEvent: TranslationChunkEvent): MantraTranslationChunk? { + return translationChunkEvent.translationChapterId()?.let { translationChapterId -> + translationChunkEvent.chunkId()?.let { chunkId -> + translationChunkEvent.index()?.let { index -> + MantraTranslationChunk( + id = translationChunkEvent.id, + publicKey = translationChunkEvent.pubKey, + createdAt = Instant.fromEpochSeconds(translationChunkEvent.createdAt), + translationChapterId = translationChapterId, + chunkId = chunkId, + index = index, + text = translationChunkEvent.content, + signature = translationChunkEvent.sig + ) + } + } + } + } + } } diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ArtifactEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ArtifactEvent.kt index 8b2e33da..bddd5af0 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ArtifactEvent.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ArtifactEvent.kt @@ -9,6 +9,8 @@ import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils +import press.mantra.compose.nostr.nip30303.tags.ArtifactMetadataTag +import press.mantra.compose.nostr.nip30303.tags.DialectIdTag @Immutable @@ -20,6 +22,14 @@ class ArtifactEvent( content: String, sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { + val artifactMetadata = tags.firstNotNullOfOrNull(ArtifactMetadataTag::parse) + + fun url() = artifactMetadata?.url + fun visibility() = artifactMetadata?.visibility + fun license() = artifactMetadata?.license + + fun dialectIdReference() = tags.firstNotNullOfOrNull(DialectIdTag::parse)?.ref + fun dialectId() = dialectIdReference()?.eventId companion object { const val KIND = 30300 diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ArtifactVersionEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ArtifactVersionEvent.kt index 350f54ed..795ecc41 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ArtifactVersionEvent.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ArtifactVersionEvent.kt @@ -9,6 +9,8 @@ import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils +import press.mantra.compose.nostr.nip30303.tags.ArtifactIdTag +import press.mantra.compose.nostr.nip30303.tags.ArtifactVersionMetadataTag @Immutable @@ -21,6 +23,11 @@ class ArtifactVersionEvent( sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { + fun versionLabel() = tags.firstNotNullOfOrNull(ArtifactVersionMetadataTag::parse)?.versionLabel + + fun artifactIdReference() = tags.firstNotNullOfOrNull(ArtifactIdTag::parse)?.ref + fun artifactId() = artifactIdReference()?.eventId + companion object { const val KIND = 30301 const val ALT_DESCRIPTION = "ArtifactVersion" diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ChapterEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ChapterEvent.kt index a0cc1ccf..f7b439cf 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ChapterEvent.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ChapterEvent.kt @@ -5,10 +5,12 @@ 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 +import press.mantra.compose.nostr.nip30303.tags.ArtifactVersionIdTag +import press.mantra.compose.nostr.nip30303.tags.ChapterMetadataTag +import press.mantra.compose.nostr.nip30303.tags.IndexTag +import press.mantra.compose.nostr.nip30303.tags.WordStatisticsTag @Immutable @@ -20,6 +22,18 @@ class ChapterEvent( content: String, sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { + val chapterMetadata = tags.firstNotNullOfOrNull(ChapterMetadataTag::parse) + val wordStatisticsTag = tags.firstNotNullOfOrNull(WordStatisticsTag::parse) + + fun artifactVersionIdReference() = tags.firstNotNullOfOrNull(ArtifactVersionIdTag::parse)?.ref + fun artifactVersionId() = artifactVersionIdReference()?.eventId + + fun name() = chapterMetadata?.name + fun originalText() = chapterMetadata?.originalText + + fun index() = tags.firstNotNullOfOrNull(IndexTag::parse)?.index + fun wordCount() = wordStatisticsTag?.wordCount + fun characterCount() = wordStatisticsTag?.characterCount companion object { const val KIND = 30302 diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ChunkEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ChunkEvent.kt index d672472e..e90486b9 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ChunkEvent.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/ChunkEvent.kt @@ -9,6 +9,9 @@ import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils +import press.mantra.compose.nostr.nip30303.tags.ChapterIdTag +import press.mantra.compose.nostr.nip30303.tags.IndexTag +import press.mantra.compose.nostr.nip30303.tags.WordStatisticsTag @Immutable @@ -20,6 +23,14 @@ class ChunkEvent( content: String, sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { + val wordStatisticsTag = tags.firstNotNullOfOrNull(WordStatisticsTag::parse) + + fun index() = tags.firstNotNullOfOrNull(IndexTag::parse)?.index + fun wordCount() = wordStatisticsTag?.wordCount + fun characterCount() = wordStatisticsTag?.characterCount + + fun chapterIdReference() = tags.firstNotNullOfOrNull(ChapterIdTag::parse)?.ref + fun chapterId() = chapterIdReference()?.eventId companion object { const val KIND = 30303 diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/DialectEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/DialectEvent.kt index 59030582..bb7a82ad 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/DialectEvent.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/DialectEvent.kt @@ -9,6 +9,7 @@ import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils +import press.mantra.compose.nostr.nip30303.tags.DialectMetadataTag @Immutable @@ -20,6 +21,11 @@ class DialectEvent( content: String, sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { + val dialectMetadata = tags.firstNotNullOfOrNull(DialectMetadataTag::parse) + + fun name() = dialectMetadata?.name + fun country() = dialectMetadata?.country + fun language() = dialectMetadata?.language companion object { const val KIND = 30304 diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationArtifactVersionEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationArtifactVersionEvent.kt index 79638de6..68bdb99e 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationArtifactVersionEvent.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationArtifactVersionEvent.kt @@ -5,10 +5,11 @@ 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 +import press.mantra.compose.nostr.nip30303.tags.ArtifactVersionIdTag +import press.mantra.compose.nostr.nip30303.tags.DialectIdTag +import press.mantra.compose.nostr.nip30303.tags.TranslationArtifactVersionMetadataTag @Immutable @@ -21,6 +22,14 @@ class TranslationArtifactVersionEvent( sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { + val translationArtifactVersionMetadata = tags.firstNotNullOfOrNull(TranslationArtifactVersionMetadataTag::parse) + + fun artifactVersionIdReference() = tags.firstNotNullOfOrNull(ArtifactVersionIdTag::parse)?.ref + fun artifactVersionId() = artifactVersionIdReference()?.eventId + + fun dialectIdReference() = tags.firstNotNullOfOrNull(DialectIdTag::parse)?.ref + fun dialectId() = dialectIdReference()?.eventId + companion object { const val KIND = 30306 const val ALT_DESCRIPTION = "TranslationArtifactVersion" 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 f5725bac..e3f6a8e4 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 @@ -9,6 +9,9 @@ import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils +import press.mantra.compose.nostr.nip30303.tags.ChapterIdTag +import press.mantra.compose.nostr.nip30303.tags.IndexTag +import press.mantra.compose.nostr.nip30303.tags.TranslationArtifactVersionIdTag @Immutable @@ -21,6 +24,14 @@ class TranslationChapterEvent( sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { + fun translationArtifactVersionIdReference() = tags.firstNotNullOfOrNull(TranslationArtifactVersionIdTag::parse)?.ref + fun translationArtifactVersionId() = translationArtifactVersionIdReference()?.eventId + + fun chapterIdReference() = tags.firstNotNullOfOrNull(ChapterIdTag::parse)?.ref + fun chapterId() = chapterIdReference()?.eventId + + fun index() = tags.firstNotNullOfOrNull(IndexTag::parse)?.index + companion object { const val KIND = 30308 const val ALT_DESCRIPTION = "TranslationChapter" 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 2ceeb5bc..e493f19d 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 @@ -9,6 +9,10 @@ import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils +import press.mantra.compose.nostr.nip30303.tags.ChunkIdTag +import press.mantra.compose.nostr.nip30303.tags.IndexTag +import press.mantra.compose.nostr.nip30303.tags.TranslationArtifactVersionIdTag +import press.mantra.compose.nostr.nip30303.tags.TranslationChapterIdTag @Immutable @@ -21,6 +25,14 @@ class TranslationChunkEvent( sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { + fun translationChapterIdReference() = tags.firstNotNullOfOrNull(TranslationChapterIdTag::parse)?.ref + fun translationChapterId() = translationChapterIdReference()?.eventId + + fun index() = tags.firstNotNullOfOrNull(IndexTag::parse)?.index + + fun chunkIdReference() = tags.firstNotNullOfOrNull(ChunkIdTag::parse)?.ref + fun chunkId() = chunkIdReference()?.eventId + companion object { const val KIND = 30309 const val ALT_DESCRIPTION = "TranslationChunk" diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationEvent.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationEvent.kt index 87dbf382..7994267c 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationEvent.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/TranslationEvent.kt @@ -9,6 +9,8 @@ import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils +import press.mantra.compose.nostr.nip30303.tags.TranslationArtifactVersionIdTag +import press.mantra.compose.nostr.nip30303.tags.TranslationChunkIdTag @Immutable @@ -21,6 +23,12 @@ class TranslationEvent( sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { + fun translationChunkIdReference() = tags.firstNotNullOfOrNull(TranslationChunkIdTag::parse)?.ref + fun translationChunkId() = translationChunkIdReference()?.eventId + + fun translationArtifactVersionIdReference() = tags.firstNotNullOfOrNull(TranslationArtifactVersionIdTag::parse)?.ref + fun translationArtifactVersionId() = translationArtifactVersionIdReference()?.eventId + companion object { const val KIND = 30311 const val ALT_DESCRIPTION = "Translation" diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ArtifactMetadataTag.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ArtifactMetadataTag.kt new file mode 100644 index 00000000..30801cef --- /dev/null +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ArtifactMetadataTag.kt @@ -0,0 +1,49 @@ +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 + +class ArtifactMetadataTag( + val url: String, + val visibility: String, + val license: String, +) { + fun toTagArray() = assemble( + url = url, + visibility = visibility, + license = license + ) + + companion object { + const val TAG_NAME = "artifact" + + fun parse(tag: Array): ArtifactMetadataTag? { + ensure(tag.has(3)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + + return ArtifactMetadataTag( + url = tag[1], + visibility = tag[2], + license = tag[3], + ) + } + + fun assemble( + url: String, + visibility: String, + license: String, + ): Array = arrayOf( + TAG_NAME, + url, + visibility, + license + ) + + fun assemble(artifactMetadataTag: ArtifactMetadataTag) = assemble( + url = artifactMetadataTag.url, + visibility = artifactMetadataTag.visibility, + license = artifactMetadataTag.license + ) + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ArtifactVersionMetadataTag.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ArtifactVersionMetadataTag.kt new file mode 100644 index 00000000..ebfabc95 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ArtifactVersionMetadataTag.kt @@ -0,0 +1,36 @@ +package press.mantra.compose.nostr.nip30303.tags + +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +class ArtifactVersionMetadataTag( + val versionLabel: String, +) { + fun toTagArray() = assemble( + versionLabel = versionLabel, + ) + + companion object { + const val TAG_NAME = "artifactVersion" + + fun parse(tag: Array): ArtifactVersionMetadataTag? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + + return ArtifactVersionMetadataTag( + versionLabel = tag[1], + ) + } + + fun assemble( + versionLabel: String, + ): Array = arrayOf( + TAG_NAME, + versionLabel + ) + + fun assemble(artifactVersionMetadataTag: ArtifactVersionMetadataTag) = assemble( + versionLabel = artifactVersionMetadataTag.versionLabel, + ) + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ChapterMetadataTag.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ChapterMetadataTag.kt new file mode 100644 index 00000000..d9963589 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/ChapterMetadataTag.kt @@ -0,0 +1,42 @@ +package press.mantra.compose.nostr.nip30303.tags + +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +class ChapterMetadataTag( + val name: String, + val originalText: String, +) { + fun toTagArray() = assemble( + name = name, + originalText = originalText, + ) + + companion object { + const val TAG_NAME = "chapter" + + fun parse(tag: Array): ChapterMetadataTag? { + ensure(tag.has(2)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + + return ChapterMetadataTag( + name = tag[1], + originalText = tag[2], + ) + } + + fun assemble( + name: String, + originalText: String, + ): Array = arrayOf( + TAG_NAME, + name, + originalText, + ) + + fun assemble(chapterMetadataTag: ChapterMetadataTag) = assemble( + name = chapterMetadataTag.name, + originalText = chapterMetadataTag.originalText, + ) + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/DialectMetadataTag.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/DialectMetadataTag.kt new file mode 100644 index 00000000..ca7a4d81 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/DialectMetadataTag.kt @@ -0,0 +1,48 @@ +package press.mantra.compose.nostr.nip30303.tags + +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +class DialectMetadataTag( + val name: String, + val country: String, + val language: String, +) { + fun toTagArray() = assemble( + name = name, + country = country, + language = language + ) + + companion object { + const val TAG_NAME = "dialect" + + fun parse(tag: Array): DialectMetadataTag? { + ensure(tag.has(3)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + + return DialectMetadataTag( + name = tag[1], + country = tag[2], + language = tag[3], + ) + } + + fun assemble( + name: String, + country: String, + language: String, + ): Array = arrayOf( + TAG_NAME, + name, + country, + language + ) + + fun assemble(dialectMetadataTag: DialectMetadataTag) = assemble( + name = dialectMetadataTag.name, + country = dialectMetadataTag.country, + language = dialectMetadataTag.language + ) + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/IndexTag.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/IndexTag.kt new file mode 100644 index 00000000..53f45096 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/IndexTag.kt @@ -0,0 +1,36 @@ +package press.mantra.compose.nostr.nip30303.tags + +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +class IndexTag( + val index: Int, +) { + fun toTagArray() = assemble( + index = index, + ) + + companion object { + const val TAG_NAME = "index" + + fun parse(tag: Array): IndexTag? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + // TODO: Check that it is an int... + return IndexTag( + index = tag[1].toInt(), + ) + } + + fun assemble( + index: Int, + ): Array = arrayOf( + TAG_NAME, + index.toString() + ) + + fun assemble(indexTag: IndexTag) = assemble( + index = indexTag.index, + ) + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/TranslationArtifactVersionMetadataTag.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/TranslationArtifactVersionMetadataTag.kt new file mode 100644 index 00000000..b0449df3 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/TranslationArtifactVersionMetadataTag.kt @@ -0,0 +1,49 @@ +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 + +class TranslationArtifactVersionMetadataTag( + val name: String, + val visibility: String, + val license: String, +) { + fun toTagArray() = assemble( + name = name, + visibility = visibility, + license = license + ) + + companion object { + const val TAG_NAME = "artifact" + + fun parse(tag: Array): TranslationArtifactVersionMetadataTag? { + ensure(tag.has(3)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + + return TranslationArtifactVersionMetadataTag( + name = tag[1], + visibility = tag[2], + license = tag[3], + ) + } + + fun assemble( + name: String, + visibility: String, + license: String, + ): Array = arrayOf( + TAG_NAME, + name, + visibility, + license + ) + + fun assemble(translationArtifactVersionMetadataTag: TranslationArtifactVersionMetadataTag) = assemble( + name = translationArtifactVersionMetadataTag.name, + visibility = translationArtifactVersionMetadataTag.visibility, + license = translationArtifactVersionMetadataTag.license + ) + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/WordStatisticsTag.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/WordStatisticsTag.kt new file mode 100644 index 00000000..ff215dab --- /dev/null +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/nostr/nip30303/tags/WordStatisticsTag.kt @@ -0,0 +1,42 @@ +package press.mantra.compose.nostr.nip30303.tags + +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +class WordStatisticsTag( + val wordCount: Int, + val characterCount: Int, +) { + fun toTagArray() = assemble( + wordCount = wordCount, + characterCount = characterCount, + ) + + companion object { + const val TAG_NAME = "word_stats" + + fun parse(tag: Array): WordStatisticsTag? { + ensure(tag.has(3)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + + return WordStatisticsTag( + wordCount = tag[1].toInt(), + characterCount = tag[2].toInt(), + ) + } + + fun assemble( + wordCount: Int, + characterCount: Int, + ): Array = arrayOf( + TAG_NAME, + wordCount.toString(), + characterCount.toString(), + ) + + fun assemble(wordStatisticsTag: WordStatisticsTag) = assemble( + wordCount = wordStatisticsTag.wordCount, + characterCount = wordStatisticsTag.characterCount, + ) + } +} \ No newline at end of file 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 36489477..f5c9e16e 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 @@ -11,10 +11,14 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.AccountTree import androidx.compose.material.icons.filled.ChevronRight import androidx.compose.material.icons.filled.DeleteForever +import androidx.compose.material.icons.filled.LibraryBooks import androidx.compose.material.icons.filled.PersonAdd +import androidx.compose.material.icons.filled.Schema import androidx.compose.material.icons.filled.Unsubscribe +import androidx.compose.material.icons.filled.WaterfallChart import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.ExperimentalMaterial3Api @@ -120,8 +124,92 @@ fun ChatRoomDetailScreen( item { HorizontalDivider() - // Should add media and attachments here } + + item { + // Artifacts + Text( + text = "Library", + style = MaterialTheme.typography.labelMedium + ) + } + + item { + Text("No artifacts exists in this group.") + } + + item { + TextButton( + onClick = { + // Navigate to the invite user screen... + onNavigateToRoute.invoke( + ImplementationPendingRoute( + "Add new artifact" + ) + ) + } + ) { + + Icon( + Icons.Default.LibraryBooks, + contentDescription = "Add new artifact" + ) + + Spacer( + modifier = Modifier.width(10.dp) + ) + + Text("Add Artifact to Library") + } + } + + item { + HorizontalDivider() + } + + // TODO: Add projects... + + item { + // Artifacts + Text( + text = "Projects", + style = MaterialTheme.typography.labelMedium + ) + } + + item { + Text("No projects exists in this group.") + } + + item { + TextButton( + onClick = { + // Navigate to the invite user screen... + onNavigateToRoute.invoke( + ImplementationPendingRoute( + "Add new project" + ) + ) + } + ) { + + Icon( + Icons.Default.Schema, + contentDescription = "create new projec" + ) + + Spacer( + modifier = Modifier.width(10.dp) + ) + + Text("Create project") + } + } + + item { + HorizontalDivider() + } + item { Text( text = "members",