fix: composer popup staying open after programmatic text changes

Merged
RI
2mo ago
+67-45

Proposed changes (including videos or screenshots)

Root cause

The composer popup (mentions, emojis, slash commands) only updates on keyboard events (keyup/focus), but programmatic text changes (setText, clear) emit input/change — so the popup gets out of sync with the composer. Canceling an edit restores the text via setText; the popup.update() workaround from #38635 then re-matches the restored text, reopening the popup when the message ends with a mention. The un-awaited cancel()/stop() also raced the dismissal.

The fix

  • useComposerBoxPopup: react to the input event, covering every text change (typed, pasted or programmatic) at the source. keyup keeps only what input can't cover: Escape and cursor-only movement. clear() no longer bails out when no option is rendered, so a dismissal can't be swallowed by a pending reopen.
  • MessageBox: closeEditing awaits reset/cancel/stop and calls popup.clear() last in all cases. popup.update() was removed — its only caller was this workaround, now handled by the input listener.

Issue(s)

Steps to test or reproduce

  1. Send hello @rocket.cat, edit it (↑) and type @ — popup opens
  2. Click Cancel (or Esc): before, the popup stayed open; now it closes

Also fixed: Send with text ending in a trigger, paste ending with a mention, and Escape reopening the popup on a second press.

Further comments

  • Listening to input is the intended integration point, not a workaround: createComposerAPI already dispatches an input event after every programmatic text change precisely so the UI can react to it. The popup was the only piece not listening.
  • No debouncing was added, addressing the concern in the issue: setOptionByInput only runs a few regexes and sets state, and calling it twice with the same text is a no-op — while a debounce would add visible latency to the popup.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed mention, slash-command, and emoji popups remaining open after text changes.
    • Improved popup behavior when text is inserted programmatically.
    • Ensured popups close correctly after sending messages or pressing Escape.
    • Preserved message content when canceling edits through the cancel button or Escape.