modal cleanup#29002
Merged
chrisnojima merged 65 commits intonojima/HOTPOT-next-670-cleanfrom Mar 11, 2026
Merged
Conversation
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.
… barrel, MaybePopup
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Chat
Teams
Profile
Settings
Devices / Git / Files / Wallets
Login / Signup / Provision
Other
Cross-cutting: Desktop Modal Infrastructure
For every modal above, on desktop verify: