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 <noreply@anthropic.com>
This commit is contained in:
@@ -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<out Event>,
|
||||
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,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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<MantraDialect>
|
||||
|
||||
@@ -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<MantraDialect> = 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user