Skip to content

modal cleanup#29002

Merged
chrisnojima merged 65 commits intonojima/HOTPOT-next-670-cleanfrom
nojima/HOTPOT-modal-cleanup
Mar 11, 2026
Merged

modal cleanup#29002
chrisnojima merged 65 commits intonojima/HOTPOT-next-670-cleanfrom
nojima/HOTPOT-modal-cleanup

Conversation

@chrisnojima
Copy link
Contributor

@chrisnojima chrisnojima commented Mar 9, 2026

Chat

  • 1. Block/Report user — Conversation → info panel (i) → user → Block
  • 2. Attachment fullscreen (desktop) — Conversation → click an image attachment
  • 3. Attach files (get titles) — Conversation → drag-and-drop or attach a file
  • 4. Bot install/search/team-picker — Conversation → info panel → Add a bot → search → pick team → install
  • 5. Forward message — Long-press/right-click a message → Forward
  • 6. Info panel / Add to channel — Conversation → info panel (i); then "Add members to channel" in a team channel
  • 7. Location sharing (mobile) — Conversation → + menu → Location
  • 8. Suggestors / emoji row / reaction tooltip — Type @ or : for suggestors; hover message for emoji row (desktop); hover reactions
  • 9. Message popup menu — Long-press/right-click any message; also test exploding messages
  • 10. Map unfurl popup — Tap a map preview in a location unfurl
  • 11. Create channel — Team chat → Create a channel
  • 12. Delete history warning — Team chat → message popup → Delete message history
  • 13. PDF viewer — Tap a PDF attachment in chat
  • 14. Send to chat / Choose conversation — Share/forward content → conversation picker
  • 15. Formatting toolbar (desktop) — Conversation → click format button in input area

Teams

  • 16. Add members wizard (all steps) — Team page → Add members → pick method (contacts/email/phone) → confirm
  • 17. New team wizard (all steps) — Teams tab → Create a team → purpose → info → big team? → channels → subteams
  • 18. Join team / Join from invite — Teams tab → Join a team; or open a team invite link
  • 19. Edit team description / Team info — Team page → edit description or team info
  • 20. Invite by email / contact — Team page → Add members → by email or contacts
  • 21. Rename subteam — Subteam page → settings → Rename subteam
  • 22. Leave team / Last owner warning — Team page → Leave team
  • 23. Role picker — Team member list → tap member → change role
  • 24. Open team / Retention warnings — Team → Settings → toggle Open team; change retention policy
  • 25. Channel settings / Add to channels / Edit channel — Team → Channels → gear icon; or member page → Add to channels
  • 26. Custom emoji / Add alias — Team page → Custom emoji → add alias
  • 27. Selection popup / Team link popup — Bulk member selection; share team invite link

Profile

  • 28. Edit profile — Your profile → Edit profile
  • 29. Edit avatar — Your profile → tap avatar → Edit photo
  • 30. Add to team — View another user's profile → Add to team
  • 31. Prove identity (enter username / proofs list / result) — Your profile → Prove your identity → pick service → enter username
  • 32. Showcase team offer — Your profile → Feature your teams

Settings

  • 33. Add email / Add phone — Settings → Your Account → Add email / Add phone
  • 34. Archive/Backup modal — Settings → Backup → Start a backup
  • 35. Contacts joined — Appears after enabling contacts
  • 36. Delete account (mobile) — Settings → Your Account → Delete account → enter passphrase
  • 37. Logout — Avatar → Sign out, or Settings → Sign out
  • 38. Push notifications prompt (mobile) — Appears after signup if push not enabled
  • 39. Change/Set password — Settings → Your Account → Change password
  • 40. Proxy settings — Login screen → Proxy settings, or Settings → Advanced → Proxy

Devices / Git / Files / Wallets

  • 41. Add device — Settings → Devices → Add a device
  • 42. New/Delete git repo, Select channel — Settings → Git → New repository / delete / notification channel
  • 43. Files destination picker — Files → select file → Move or Copy
  • 44. Kext permission popup (macOS) — Files → Finder integration banner (if kext needed)
  • 45. SFMI popup — Files → system file manager integration banner
  • 46. Wallet remove account — Wallets → account settings → Remove account → confirm

Login / Signup / Provision

  • 47. Recover password error — Password recovery flow → trigger error
  • 48. Reset account — Account reset flow → confirm
  • 49. Signup email/phone/feedback — Create account → enter phone → enter email; or Send feedback
  • 50. Provision code page / Troubleshooting — Add new device → code page; troubleshooting if errors

Other

  • 51. Team building (new chat, add to team, crypto, people) — Chat → New chat; Team → Add members → search; Crypto → Encrypt → recipients; People → search
  • 52. Contact restricted — Team building → if contact access restricted
  • 53. Incoming share (mobile) — Share content from another app → Keybase
  • 54. Deeplink error — Open an invalid Keybase deep link
  • 55. Tracker assertion popup — View user profile → tap a proof (Twitter, etc.)
  • 56. Account switcher — Tap your avatar in People tab header

Cross-cutting: Desktop Modal Infrastructure

For every modal above, on desktop verify:

  • Header renders correctly (title, close/back button)
  • Overlay dims the background
  • Clicking outside the modal dismisses it
  • Pressing Escape dismisses it
  • Modal sizing looks correct
  • 17. New team wizard (all steps) — Teams tab → Create a team → purpose → info → big team? → channels → subteams
  • 18. Join team / Join from invite — Teams tab → Join a team; or open a team invite link
  • 25. Channel settings / Add to channels / Edit channel — Team → Channels → gear icon; or member page → Add to channels
  • 29. Edit avatar — Your profile → tap avatar → Edit photo
  • 33. Add email / Add phone — Settings → Your Account → Add email / Add phone
  • 43. Files destination picker — Files → select file → Move or Copy
  • 50. Provision code page / Troubleshooting — Add new device → code page; troubleshooting if errors
  • 51. Team building (new chat, add to team, crypto, people) — Chat → New chat; Team → Add members → search; Crypto → Encrypt → recipients; People → search
  • 53. Incoming share (mobile) — Share content from another app → Keybase

Steps 1-2 of modal cleanup: convert all PopupWrapper usages to Modal2
with proper header/onClose patterns. Add popupStyleClipContainer prop
to Modal2 for consumers whose content width differs from the default
400px mode. Convert MobilePopup in join-from-invite to Modal.
Use RNText onPress instead of wrapping in Pressable in Kb.Icon native,
so style props like position/left apply to the actual rendered element.
Step 3 of modal cleanup: convert 7 files that directly used PopupDialog
or MaybePopup to use Modal2 instead. Removes Wrapper shim components
from warning dialogs, converts fullscreen attachment viewer with
popupStyleContainer fill, and migrates proxy settings from
HeaderHocWrapper to Modal2 header.
Step 4 of modal cleanup: no consumer changes needed, just swaps the
internal wrapper from deprecated Modal to Modal2.
The old Modal2 was a bare fragment (header + children + footer with no
wrapping). Our Modal cleanup added PopupDialog/ScrollView wrapping which
broke the 3 pre-existing Modal2 consumers whose router already provides
the outer chrome. bare={true} restores the original behavior.
Convert the last 2 HeaderHocWrapper consumers to Modal2 bare and remove
HeaderHocWrapper from barrel exports.
Remove HeaderHocWrapper from header-hoc source files (zero consumers
after barrel export removal) and delete orphaned header-or-popup.tsx.
Clean up unused imports.
Replace the custom FloatingBox+KeyboardAvoidingView+underlay overlay
with @gorhom/bottom-sheet BottomSheetModal, following the same pattern
as FloatingMenu. Add onDismiss prop for swipe-to-dismiss support and
snapPoints for height control. Update all 3 consumers to pass dismiss
callbacks.
- Delete Modal2, PopupDialog, Overlay, MobilePopup components
- Add unified Popup component (desktop/native)
- Router layout defaults modal2=true, provides overlay/close button
- Remove modal2Type system (Wide/SuperWide/etc) — screens set own sizes
- Remove ScrollView from modal chrome — screens manage own scrolling
- Convert all ~100 modal screens to render header/footer directly
- Change default modal height from maxHeight to fixed height (560px)
  so virtualized lists get a proper parent height
- Add modalStyle to LayoutOptions for per-route size overrides
- Add modalStyle overrides for modals needing non-default dimensions:
  deviceAdd (620w), profileEdit (350x450), profileGeneric* (560x485),
  profileShowcaseTeamOffer (600x600), teamRename (560x480),
  kextPermission (700w), chatAttachmentFullscreen, chatPDF
- Fix fullHeight on modal container to prevent box2_centered collapse
- Replace stack-based EscapeHandler with capture-phase window listener
  to ensure Escape always closes the topmost modal
- Move React.Suspense outside ModalWrapper to prevent white box flash
  while lazy content loads
Layout wrappers (desktop + native) now read standard React Navigation
header options (title, headerTitle, headerLeft, headerRight, headerShown)
from getOptions and render ModalHeader. Screens declare headers
declaratively instead of rendering them inline.

Migrated ~25 screens across chat, teams, settings, profile, git, login,
and deeplinks modules. Screens with dynamic/state-dependent headers
remain inline for now. Native layout only renders headers for modal
screens to avoid doubling with RN's native header on regular screens.
… headers

- Move header configuration to getOptions in route definitions instead of
  rendering HeaderHocHeader/ModalHeader inline in components
- Remove setOptions usage for headers that can be declared at push time
- Add title: '' to modal group defaults to prevent route names leaking as titles
- Move team-building headers to page.tsx using direct zustand store access
- Remove WalletPopup inline headers, use default modal Cancel
- Add skipMobileHeader to signup modal screens with route-level Skip buttons
- Hide native header for screens with custom layouts (emoji picker, attachment titles)
- Delete dead modal-header-props.tsx
- Move account switcher Sign Out button to route getOptions
…lse for fs barePreview

- modal2Style → overlayStyle, modal2AvoidTabs → overlayAvoidTabs
- modal2ClearCover → overlayTransparent, modal2NoClose → overlayNoClose
- modal2Footer → modalFooter, modal2Header → modalHeader
- Delete dead modal2 boolean branch and modalContainer style
- Hide native header for fs/barePreview (custom fullscreen layout)
Move header configuration (title, headerLeft, headerRight, headerStyle)
from runtime setOptions calls in screen components to static getOptions
in route definitions. This follows the idiomatic React Navigation pattern
where static header config lives in the route definition rather than
being set imperatively from inside the screen.

Also fixes desktop info panel not opening (StrictMode double-effect
cleanup was calling showInfoPanel(false) on desktop where the panel
is inline), changes default modal height to maxHeight, and adds
modalStyle overrides for routes that used the old modal2Type system.
…ader into consumers

ModalFooter replaced with <Box2> + local modalFooter style definitions
across 37+ screen files. ModalHeader inlined into its 3 remaining
consumers (signup/common, screen-layout.desktop, login/reset/modal,
provision/troubleshooting). Removed ModalFooter, ModalHeader,
useModalHeaderTitleAndCancel, modalFooterStyle, modalFooterNoBorderStyle
from barrel exports.
PopupHeaderText inlined as styled Text in its 3 consumers.
Overlay and MobilePopup were unused aliases for Popup — removed
from barrel exports.
…e into popup/ directory

- Extend native Popup with Portal mode (attachTo → Portal, no onHidden → Portal, onHidden → BottomSheet)
- Make onHidden optional on Popup; desktop skips positioned chrome when absent
- Migrate FloatingBox consumers to Popup (role-picker, add-alias, emoji-row, suggestors, selection-popup, toast)
- Remove FloatingBox from barrel exports (now internal to popup/)
- Move popup, floating-box, bottom-sheet, use-popup into common-adapters/popup/ directory
…h mode prop

Replaces 4 overlapping header button components with one unified
HeaderLeftButton that accepts mode ('back'|'cancel') and
autoDetectCanGoBack props. Also cleans up dead LeftAction props
from deleted HeaderHocHeader. Renames header-hoc/ to header-buttons.
- Add padding to the ellipsis icon for a larger click target
- Add windowDraggingClickable to opt out of the Electron drag region
- Simplify desktop Icon: render a single span instead of div+span wrapper
… mobile

Pass undefined for attachTo on mobile so Popup uses bottom sheet behavior.
Previously mobile ignored attachTo, but now it respects it, causing menus
and popups to render as positioned overlays instead of bottom sheets.
Center all desktop modals in the overlay and override maxHeight for
the PDF viewer so it actually reaches 80% of the viewport.
…r reactivity

- Wrap mobile button spinner in absolute-positioned View so it centers over the button
- Add HeaderRightUpdater inside TBProvider to drive header updates via setOptions,
  fixing the Add button not appearing when users are selected
…r components

Components now write dynamic state to a new ModalHeaderStore (stores/modal-header.tsx),
and header components in routes.tsx files read from it. This eliminates imperative
header mutations from useEffect and removes setOptions from the useNav() hook entirely.
…to nojima/HOTPOT-modal-cleanup

# Conflicts:
#	shared/chat/conversation/input-area/filepicker-popup/index.native.tsx
#	shared/chat/conversation/input-area/normal/moremenu-popup.native.tsx
#	shared/chat/conversation/input-area/normal/set-explode-popup/index.native.tsx
#	shared/chat/conversation/messages/message-popup/index.tsx
#	shared/profile/routes.tsx
#	shared/settings/account/add-modals.tsx
Remove the role picker's own border/shadow since Popup now provides
elevation styling. Remove all floatingContainerStyle position hacks
(relative offsets) that caused see-through gaps inside the Popup wrapper.
The emoji Modal component rendered its own title header on desktop,
duplicating the router-provided header. Remove the custom header and
rely on native headers. Add Cancel button on mobile via HeaderLeftButton.
…ponents

Modal routes already define title and modalStyle dimensions via the
router. Components were duplicating both, causing double headers and
size conflicts that hid content (e.g. missing Save button in Edit
Profile).

- Remove desktop-only header text from: edit-profile, proofs-list,
  showcase-team-offer, add-device
- Remove hardcoded width/height from container styles in: edit-profile,
  enter-username, result, proofs-list, showcase-team-offer
- Fix proofs-list flex layout so it fills the modal properly
navigateUp() only popped the add-to-team modal, leaving the search
dialog with a spinner stuck underneath. Use clearModals() instead.
The Move or Copy modal had no explicit height, causing the folder
list to collapse to zero. Add modalStyle with proper dimensions to
the route definition, replacing the old Kb.Modal wrapper sizing.
The virtualized list header height was 60px but the actual content
(3 lines of text + padding) needs ~90px, causing items to overlap.
Remove the custom ModalHeader from SignupScreen and use React Navigation's
native header instead. Add titles to all logged-out route definitions so
they display properly in the nav header.
The options dictionary in the unsafeBitCast call to UIApplication.open
was causing a crash because iOS internally calls universalLinksOnly on
the options object, which fails on Swift/NSDictionary types. Passing
nil instead lets ObjC nil-messaging safely return false.
@chrisnojima chrisnojima changed the title WIP: modal cleanup modal cleanup Mar 11, 2026
@chrisnojima chrisnojima merged commit 0df5d4c into nojima/HOTPOT-next-670-clean Mar 11, 2026
1 check passed
@chrisnojima chrisnojima deleted the nojima/HOTPOT-modal-cleanup branch March 11, 2026 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants