Kgothatso Ngako 3f4f05162d feat: say who opened the ceremony on the shared key screen
The screen showed the quorum, the ladder and now the roster, but never named the
member whose ceremony it was. Any member can open one and it settles the group's
signing quorum for good, so who opened this one belongs on the screen that
describes it — the same reason the chat notice names them.

  Alice started this ceremony.
  2 of 3 members will be needed to sign with this key.

It sits above the failure branch so it holds in every state. A ceremony that was
abandoned or has already produced a key is still worth attributing: a member
arriving at a finished ceremony they do not remember agreeing to should be able
to see whose it was, and DkgSession.coordinatorPublicKey is kept for the life of
the row either way.

## One naming rule, in one place

HexKey.memberName() resolves a member's display name from the profiles joined
onto the room, falling back to a shortened key. The roster switched to it, so the
opener line and the rows below it cannot disagree about what to call somebody,
and the chat notice's copy of the fallback went with it.

This replaces a second private SHORTENED_PUBLIC_KEY_LENGTH I had added to
ChatMessageListViewModel. A third still lives in SelectChatRoomTypeViewModel at a
different value (12) and is deliberately untouched: that is a different choice
about a different surface, not a duplicate of this one, and folding them together
is a call about that screen rather than about this feature.

## Still reads a raw key on one surface

The abandoned card shows DkgSession.failureReason verbatim, which for a ceremony
ended by another member begins "Abandoned by 1a2b3c4d:" -- a truncated key where
the chat line now shows a name. Naming them there needs the culprit stored beside
the reason rather than inside it, which is a column on DkgSession and a schema
version, so it is left as it is rather than parsed back out of the string.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 00:52:35 +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%