Kgothatso Ngako 6c63027912 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>
2026-09-05 20:21:52 +02:00
2026-07-05 23:21:02 +02:00
2026-07-28 09:10:20 +02:00
2026-03-24 04:47:19 +02:00
2026-03-23 01:41:39 +02:00
2026-03-23 01:41:39 +02:00
2026-03-23 01:41:39 +02:00

This is a Kotlin Multiplatform project targeting Android, iOS, Desktop (JVM).

  • /composeApp is for code that will be shared across your Compose Multiplatform applications. It contains several subfolders:

    • commonMain is for code thats common for all targets.
    • Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name. For example, if you want to use Apples CoreCrypto for the iOS part of your Kotlin app, the iosMain folder would be the right place for such calls. Similarly, if you want to edit the Desktop (JVM) specific part, the jvmMain folder is the appropriate location.
  • /iosApp contains iOS applications. Even if youre sharing your UI with Compose Multiplatform, you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project.

Build and Run Android Application

To build and run the development version of the Android app, use the run configuration from the run widget in your IDEs toolbar or build it directly from the terminal:

  • on macOS/Linux
    ./gradlew :composeApp:assembleDebug
    
  • on Windows
    .\gradlew.bat :composeApp:assembleDebug
    

Build and Run Desktop (JVM) Application

To build and run the development version of the desktop app, use the run configuration from the run widget in your IDEs toolbar or run it directly from the terminal:

  • on macOS/Linux
    ./gradlew :composeApp:run
    
  • on Windows
    .\gradlew.bat :composeApp:run
    

Build and Run iOS Application

To build and run the development version of the iOS app, use the run configuration from the run widget in your IDEs toolbar or open the /iosApp directory in Xcode and run it from there.


Learn more about Kotlin Multiplatform

Description
Mantra as a kotlin multiplatform project
https://mantra.press
Readme 8.2 MiB
Languages
Kotlin 100%