Skip to content

fix(messaging): reduce composer recomposition and typing jank#6318

Draft
jeremiah-k wants to merge 2 commits into
meshtastic:mainfrom
jeremiah-k:bugfix/messaging-input-lifecycle-jank
Draft

fix(messaging): reduce composer recomposition and typing jank#6318
jeremiah-k wants to merge 2 commits into
meshtastic:mainfrom
jeremiah-k:bugfix/messaging-input-lifecycle-jank

Conversation

@jeremiah-k

Copy link
Copy Markdown
Contributor

Overview

This reduces message-composer recomposition and per-keystroke work, particularly on active meshes where node telemetry changes frequently and inline Markdown is enabled.

The composer previously received full Node objects, so telemetry-only node updates could invalidate the input subtree even when no mention-visible identity data had changed. The live editor also performed more text processing and state persistence than necessary during rapid typing.

This keeps the existing Markdown wire format and user-visible behavior while narrowing the composer’s reactive inputs and making the typing path bounded.

Changes

  • Replaced full Node composer inputs with lightweight mention candidates containing only ID, long name, and short name.
  • Kept telemetry, position, metrics, status, and other unrelated node changes from invalidating the message input subtree.
  • Cached normalized mention fields once per candidate instead of lowercasing every field on every keystroke.
  • Made mention matching lazy and stopped scanning once the bounded suggestion limit was reached.
  • Removed the obsolete duplicate full-Node and candidate matching implementations.
  • Added a plain-text fast path that skips Markdown processing when no supported inline delimiter is present.
  • Replaced the full GFM parser in the live text-field styling path with lightweight inline-only pattern detection.
  • Preserved the established full Markdown renderer for sent message bubbles.
  • Preserved raw Markdown delimiters in stored and transmitted message text.
  • Kept mention transformation and inline Markdown styling composable in the same display-only output path.
  • Debounced draft persistence to SavedStateHandle by 300 ms during rapid typing.
  • Kept send and explicit clear operations immediate, cancelling any pending delayed persistence.
  • Removed the ineffective onCleared() draft write.
  • Kept newly exposed matching and parser helpers internal.

Validation

Added focused coverage for:

  • mention matching across ID, long name, and short name;
  • case-insensitive matching;
  • deterministic ordering and bounded early termination;
  • plain-text and incomplete-Markdown fast paths;
  • bold, italic, strikethrough, and inline-code live styling;
  • bold delimiters not being double-counted as italic;
  • exact 300 ms draft persistence behavior;
  • rapid edits collapsing into one stored draft;
  • explicit draft clearing cancelling pending persistence and clearing immediately.

Existing messaging tests continue to cover raw Markdown transmission, mention completion, formatting behavior, send handling, and draft restoration.

Scope

This change is limited to the message-composer hot path. It does not change transport, database, node-identity, or application-lifecycle behavior.

…omposition

Replace the full List<Node> dependency in MessageInput with a stable
MentionCandidate projection (id, longName, shortName) derived via
derivedStateOf. Telemetry, position, lastHeard, and other high-frequency
Node changes leave MentionCandidate structurally identical, preventing
OutputTransformation recreation and platform input-connection churn.

Replace the IntelliJ GFM parser on the live TextField transformation
path with a bounded regex-based inline-markdown scanner (bold, italic,
strikethrough, code only). The full parser remains available for
rendered message bubbles via InlineMarkdown.kt.

The existing Node import is preserved for MessageListPaged (full node
list at render time) and NodeDetails navigation events.
Remove the duplicate mention-matching implementations and cache normalized candidate fields so each keystroke performs one query normalization instead of repeatedly lowercasing every node identity field.

Evaluate candidates through a lazy sequence and stop once the bounded suggestion list is full. Keep the helper and live-markdown span surfaces internal so common tests can exercise the production hot path without expanding the public API.

Add regression coverage for case-insensitive mention matching, stable ordering and limits, live inline-style parsing, exact draft debounce timing, and synchronous draft clearing.
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d9f320a4-d17b-4c8e-b01d-20e085642437

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the bugfix PR tag label Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix PR tag

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant