Files
buzz/mobile/test/features
Kalvin C 3c0adc1882 fix(mobile): qualify every namesake mention and keep authored mention casing (#9325)
## problem

When a message mentions two different identities that share a display
name, the mobile composer qualified only the later selection as `@Name
(<64-hex>)` and left the first one bare. A qualified occurrence denies
the plain name on render, so the first mention rendered as plain text on
mobile and desktop. `MessageContent` also displayed every mention in the
lowercased binding key rather than its authored spelling.

## change

- `mention_bindings.dart`:
- `selectedMentionLabel` qualifies a selection whenever another selected
identity shares its name, without regard to case.
- `namesakeRequalifications` and `renameMentions` qualify earlier plain
selections. Each occurrence keeps its authored spelling, and occurrences
in code stay as typed.
- `compose_bar/helpers.dart` and `compose_bar_widget.dart`:
- Selecting a namesake qualifies earlier same-name mentions before the
new label is inserted, keeping the caret in place.
- Occurrences inside code that the composer styles are skipped:
single-backtick spans and closed triple-backtick fences, found by the
same walk the editor uses to draw them. A key whose occurrence stays in
code remains bound beside its qualified label, so its recipient still
sends.
- `agent_mention_prefill.dart`: automatic addressing qualifies every
same-name agent it inserts.
- `message_content.dart`: mentions render in their authored spelling,
and bindings still resolve case-insensitively.
- `docs/mention-editor.md`: describes the behavior, including that
Markdown code forms the composer does not style (tilde fences, indented
code) are qualified like prose.

## tests

- `mention_bindings_test.dart`: requalification, spelling preservation
and code exclusion.
- Composer journeys:
  - picker selections qualify both namesakes and send both keys;
- styled code (fences, list fences, spans, spans after bold or italics)
stays as typed while surrounding prose is qualified;
  - a selection left only in code keeps its recipient;
  - automatic prefill of two same-name agents qualifies both.
- `message_content_exact_mentions_test.dart`: authored casing with
case-insensitive resolution.
- `just mobile-check mobile-test` passes.
- Real relay: composed bodies exchanged through a local relay render as
correctly targeted chips in desktop and in Flutter `MessageContent`.

---------

Signed-off-by: Kalvin Chau <kalvin@block.xyz>
Signed-off-by: Tom Brow <tomb@squareup.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: goose-wayne <ae6b377e5b6d090ee22558d19246413a5731628a127e25371111badfd4861535@buzz.block.builderlab.xyz>
Co-authored-by: Tom Brow <tomb@squareup.com>
Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz>
2026-11-12 19:11:37 -08:00
..