Files
mc-webui/app
MarekWoandClaude Opus 5 e4a98a427e feat(chat): add the share composer — "+" button, pickers and live preview
Completes the sharing feature: you can now send what the cards render.

A "+" button next to the emoji button opens a three-item menu — contact,
channel, location. Five actions in the official app collapse into three
because "me" and "my position" are not separate destinations, just the
first, pinned entry of the picker they belong to. Same number of taps,
one less menu level, and every entry behaves identically.

The payload is inserted into the input as plain text, byte-identical to
what the official app sends. A protected "chip" was considered and
dropped: it is unknown whether the official app renders a card when the
token is not the whole message body, and that risk is not worth the
cosmetics. The reassurance went into a live preview above the composer
instead, rendered through the very same processMessageContent() the
recipient will use — so it cannot drift. Edit the token by hand and the
preview vanishes, which is immediate feedback that the message will no
longer render as a card.

Details worth knowing:

- The contact picker lists device memory and cache together, since the
  cache is where adverts land and those are the contacts worth passing
  on. It renders at most 150 rows: this mesh has over 1500 cached
  contacts, and the full list costs thousands of DOM nodes for something
  nobody scrolls to the end of. Search runs over the whole set.
- The channel picker carries the region scope along, because a recipient
  transmitting under the firmware default would not match the sender.
- The location picker holds both cases in one dialog: our own position as
  a button, plus a Leaflet map for any other point.
- Byte budgets are enforced up front (135 channel / 150 DM). A token that
  cannot fit is refused rather than truncated — shortening a public key
  or a channel secret destroys it.
- The DM composer starts disabled until a conversation is chosen, so the
  button mirrors the input's disabled state via a MutationObserver.

Also fixes _selfInfo being populated only inside the map modal's shown
handler, which left it null on a fresh page — the location cards need our
own position at render time for distance and bearing.

Verified in a real browser against the live device: 32 assertions on the
channel composer, 13 on the DM panel (including its local map modal),
both suites green with no console errors.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 11:12:58 +02:00
..