Files
mantra-kmp/composeApp
Kgothatso Ngako 2c3c949b86 feat(subgroups): ask for a room from the thing that needs one
Four buttons, one per entity, each opening the existing picker with the name
already in it. This is the cheap version of the feature complete: a member
looking at a translation can give it a room without backing out to the group,
finding "Add subgroup" and retyping a name the app already knew.

`SelectSubgroupAdminsRoute` grows three nullable fields. The name is a
suggestion and stays editable -- a group renaming its own room is not a route's
business to prevent -- and it is seeded in the view model's constructor rather
than in `initiate`, because a field somebody may already be typing into must not
be overwritten by a load completing underneath them.

The origin is two flat fields rather than one type, because a route is
`@Serializable` and is rebuilt from a bundle. The nav host reassembles them and
requires both or neither: half a reference is a reference with the resolvable
part removed. The view model then only holds it. Riding it onto the ceremony
needs a `DkgSession` column and a tag on the proposal, which is Phase 5, and the
comment at the `proposeRitual` call says so rather than leaving a parameter that
looks forgotten.

The gate is `canAddSubgroup` on all four states and not `canSign`: a share of
the key *and* `mlsGroupState != null`, because a NIP-17 room has no admins to be
a parent's and these entities can live in one. Three states had to learn it.
`ProjectDetailUIState` and `TranslationArtifactVersionDetailUIState` already
carried `canSign`; `ArtifactDetailUIState` carried no capability flag at all, so
the artifact screen and its view model gained a `ChatRepository` as well -- the
one place this phase is more than a button.

Each flag is computed off `SubgroupOrigin.of(entity).parentChatRoomId` rather
than the route's `chatRoomId`. They are the same room in every path that exists,
and reading it through the function is what keeps the parent of a subgroup the
room the entity actually lives in if a route is ever built by hand.

Hidden rather than disabled where it cannot work, which is what the room's own
subgroup entry does and for the same reason: a device with no share cannot open
the certificate session at all, and `proposeSigningBatch` throws rather than
refusing.

Phase 3 of docs/subgroups-for-entities.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-03 01:27:47 +02:00
..