Mobile: long-press a message opens a bottom sheet of actions (replaces the hover bar) #166

Open
opened 2026-09-17 23:06:35 -04:00 by jared · 1 comment
Owner

What it is: on phones there is no hover, so the hover action bar (react/reply/edit/…) is unreachable or only via an unreliable long-press. The standard mobile pattern is a bottom sheet — long-press (or tap the "…" affordance) slides up a panel from the bottom with the quick reactions row on top and the full action list beneath (Reply, React, Copy, Forward, Pin, Edit, Delete, Report…). This is the proper fix for LOTUS_TODO's open M2 item: nothing added per message, no unread-badge collision.

Scope

  • Touch devices only (pointer: coarse); desktop unchanged.
  • One sheet component (folds Overlay + drag-to-dismiss), reused by the room timeline, thread panel and search results.
  • Long-press must not fire on scroll; iOS Safari long-press quirks (callout menu, text selection) handled — test on a real iPhone and an Android phone before merging.
What it is: on phones there is no hover, so the hover action bar (react/reply/edit/…) is unreachable or only via an unreliable long-press. The standard mobile pattern is a **bottom sheet** — long-press (or tap the "…" affordance) slides up a panel from the bottom with the quick reactions row on top and the full action list beneath (Reply, React, Copy, Forward, Pin, Edit, Delete, Report…). This is the proper fix for LOTUS_TODO's open M2 item: nothing added per message, no unread-badge collision. ### Scope - Touch devices only (`pointer: coarse`); desktop unchanged. - One sheet component (folds `Overlay` + drag-to-dismiss), reused by the room timeline, thread panel and search results. - Long-press must not fire on scroll; iOS Safari long-press quirks (callout menu, text selection) handled — test on a real iPhone and an Android phone before merging.
jared added this to the Features 2026-Q4 milestone 2026-09-17 23:06:35 -04:00
jared added the enhancementpriority: mediumuxarea: mobile labels 2026-09-17 23:06:35 -04:00
jared self-assigned this 2026-09-17 23:06:35 -04:00
Author
Owner

Implemented in 53a80adb (ships with the next deploy):

  • useLongPress (450 ms, < 10 px movement, cancelled by scroll/lift; touch handlers only on pointer: coarse devices) on all three message layouts.
  • ActionSheet: slides up from the bottom, drag handle, swipe-down or backdrop tap dismisses, role=dialog + focus trap.
  • Contents: quick reactions row + "Add reaction" on top, then the same folds Menu the desktop popout uses (extracted to a shared menuJSX, so the two can't drift): Reply, Forward, Bookmark, Remind Me, Reply in Thread, Copy Link, Copy Lotus Link, Pin, Edit, Delete, Report… Menu items close the sheet.
  • The iOS/Android quirks the issue called out: Android's contextmenu echo of the same press is dropped; the press-induced text/image selection is cleared; the finger-lift's synthesised click is swallowed (preventDefault on touchend) so it can't land on a menu item; the sheet ignores "outside" clicks for its first 600 ms. Desktop is unchanged (right-click → anchored popout, verified).
  • Reused by the room timeline, thread panel and search results automatically (they all render Message).

Verified with Playwright touch emulation (Pixel 7, CDP touch events): long-press → sheet; swipe-down dismisses; a scroll gesture doesn't open it; tapping Reply closes it and arms the composer.
sheet

Left open for the device pass the issue asks for: iOS Safari callout/selection behaviour and Android Chrome on real hardware — emulation can't stand in for those. If both look right, close this and #199 together.

Implemented in `53a80adb` (ships with the next deploy): - `useLongPress` (450 ms, < 10 px movement, cancelled by scroll/lift; touch handlers only on `pointer: coarse` devices) on all three message layouts. - `ActionSheet`: slides up from the bottom, drag handle, swipe-down or backdrop tap dismisses, `role=dialog` + focus trap. - Contents: quick reactions row + "Add reaction" on top, then the **same** folds Menu the desktop popout uses (extracted to a shared `menuJSX`, so the two can't drift): Reply, Forward, Bookmark, Remind Me, Reply in Thread, Copy Link, Copy Lotus Link, Pin, Edit, Delete, Report… Menu items close the sheet. - The iOS/Android quirks the issue called out: Android's `contextmenu` echo of the same press is dropped; the press-induced text/image selection is cleared; the finger-lift's synthesised click is swallowed (`preventDefault` on `touchend`) so it can't land on a menu item; the sheet ignores "outside" clicks for its first 600 ms. Desktop is unchanged (right-click → anchored popout, verified). - Reused by the room timeline, thread panel and search results automatically (they all render `Message`). Verified with Playwright touch emulation (Pixel 7, CDP touch events): long-press → sheet; swipe-down dismisses; a scroll gesture doesn't open it; tapping Reply closes it and arms the composer. ![sheet](https://code.lotusguild.org/attachments/ee98dc8b-7f34-4792-83ed-89dde01d1c60) **Left open for the device pass** the issue asks for: iOS Safari callout/selection behaviour and Android Chrome on real hardware — emulation can't stand in for those. If both look right, close this and #199 together.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#166