Date: 2025-01-26 (Updated: 2025-01-29)
Status: Phase 5 Complete - UX Polish & Testing
Successfully implemented single WebView architecture. All authenticated content now flows through one PrimaryWebView component instead of multiple specialized WebView screens and complex navigation stacks.
Latest Updates (2025-01-29):
- ✅ Pull-to-refresh with hold-to-confirm gesture (web-side)
- ✅ Expanded touch targets for navigation
- ✅ Menu closes properly on all navigation actions
- ✅ Create modal history fix (replace instead of push)
- ✅ ViewHeader chevron always opens menu on mobile
- ✅ Mobile-friendly padding on CreateGroup page
- ✅ "Download App" hidden in WebView context
Before: Deeply nested structure
<AuthRoot.Navigator>
<AuthRoot.Screen name='Drawer' component={DrawerNavigator} />
<AuthRoot.Screen name='Create Group' component={CreateGroup} />
<AuthRoot.Screen name='Notifications' component={NotificationsList} />
// ... 10+ more screens and modals
</AuthRoot.Navigator>After: Simplified to single screen
<AuthRoot.Navigator>
<AuthRoot.Screen name='Main' component={PrimaryWebView} />
<AuthRoot.Screen name='Loading' component={LoadingScreen} />
// All other screens commented out with deprecation notice
</AuthRoot.Navigator>Changes:
- ✅ Replaced
Drawerscreen withPrimaryWebView - ✅ Removed 10+ modal screens
- ✅ Commented out deprecated imports
- ✅ Added deprecation comments explaining the change
Message Handling - Before:
case WebViewMessageTypes.NAVIGATION: {
// Complex routing to native screens
if (nativeRouteHandler) {
// ... 20+ lines of navigation logic
}
}
case WebViewMessageTypes.GROUP_DELETED: {
// Clear state, navigate away
setCurrentGroupSlug('my')
queryCurrentUser()
openURL('/groups/my/no-context-fallback')
}Message Handling - After:
// Both cases commented out with deprecation notices
// NAVIGATION: No longer needed - web handles all navigation
// GROUP_DELETED: No longer needed - web handles group deletion
default:
// Log unknown messages in dev for debugging
if (__DEV__ && type) {
console.log('📱 Unhandled WebView message type:', type, data)
}Changes:
- ✅ Deprecated NAVIGATION message handling
- ✅ Deprecated GROUP_DELETED message handling
- ✅ Added default case for debugging unknown messages
- ✅ Kept code as comments for reference
New Feature: Mobile-friendly navigation gestures
Created apps/web/src/hooks/useSwipeGesture.js:
- Detects swipe-from-left-edge to open navigation menu
- Detects swipe-right-to-left to close menu
- Configurable sensitivity and edge detection
- Uses passive touch events for performance
Integrated into apps/web/src/routes/AuthLayoutRouter/AuthLayoutRouter.js:
- Swipe from left edge (30px zone) opens context menu
- Swipe left when menu open closes it
- Provides familiar mobile UX pattern
- No native bridge needed - all handled in web app
New Feature: Pull-to-refresh gesture handled by web app
Created apps/web/src/hooks/usePullToRefresh.js:
- Detects pull-down gesture when at scroll top
- Requires user to hold at threshold for 400ms (prevents accidental triggers)
- Three visual states: pulling (arrow), ready (checkmark), refreshing (spinner)
- Only enabled in WebView context (via
isWebView())
Integrated into apps/web/src/routes/AuthLayoutRouter/AuthLayoutRouter.js:
- Shows visual indicator during pull gesture
- Triggers page reload on successful gesture
- Native pull-to-refresh disabled (doesn't work with AutoHeightWebView)
Commented out native props in HyloWebView.js and PrimaryWebView.js:
pullToRefreshEnabled,onRefresh,refreshing- now handled web-side
Expanded Touch Targets
Modified apps/web/src/components/ViewHeader/ViewHeader.jsx:
- Wrapped ChevronLeft icons in
<button>elements withp-2padding - Increased touch target from 24px to ~40px (closer to 44px recommendation)
Menu Close on Navigation
Modified apps/web/src/components/GroupMenuHeader/GroupMenuHeader.jsx:
- Bell icon, Settings icon, Members link, About icon now close menu on click
- Added
navigateAndClosehelper that dispatchestoggleNavMenu(false)
Modified apps/web/src/components/CreateMenu/CreateMenu.jsx:
- All creation links (post types, track, funding round, group) now close menu
- Added
handleLinkClickcallback to dispatchtoggleNavMenu(false)
Hide "Download App" in WebView
Modified apps/web/src/routes/AuthLayoutRouter/components/GlobalNav/GlobalNav.jsx:
- "Download App" link hidden when
isWebView()returns true - Users in mobile app don't need to see app download link
Fixed Create Modal History
Modified apps/web/src/components/CreateModal/CreateModal.js:
- Changed
navigate(returnToLocation)tonavigate(returnToLocation, { replace: true }) - Prevents back button from reopening closed modals
- Cleaner browser history on both mobile and desktop
Fixed ViewHeader Chevron Behavior
Modified apps/web/src/components/ViewHeader/ViewHeader.jsx:
- On small screens: chevron always toggles nav menu
- On larger screens (sm+): chevron navigates back if
backButtonis true - Fixes issue where
backButton: truewas overriding menu toggle on mobile
CreateGroup Page Padding
Modified apps/web/src/routes/CreateGroup/CreateGroup.jsx:
- Added
px-4to container for horizontal padding on small screens - Prevents content from touching screen edges on mobile
Added deprecation headers to the following files:
// DEPRECATED: This screen is no longer used in the app.
// All content (including chat) is now handled by PrimaryWebView.
// The web app provides the chat interface.
// Kept for reference - may revisit native implementation in the future.
// Last used: 2025-01-26// DEPRECATED: This screen is no longer used in the app.
// All content (including group settings) is now handled by PrimaryWebView.
// The web app provides the settings interface.
// Kept for reference - may revisit native implementation in the future.
// Last used: 2025-01-26// DEPRECATED: This screen is no longer used in the app.
// All content (including user settings) is now handled by PrimaryWebView.
// The web app provides the settings interface and handles logout.
// Kept for reference - may revisit native implementation in the future.
// Last used: 2025-01-26// DEPRECATED: This screen is no longer used in the app.
// All content (including maps) is now handled by PrimaryWebView.
// The web app provides the map interface.
// Note: This was the most complex WebView screen with custom navigation handling,
// drawer disabling, and back button management - all now handled by web.
// Kept for reference - may revisit native implementation in the future.
// Last used: 2025-01-26// DEPRECATED: This screen is no longer used in the app.
// All content (including group exploration) is now handled by PrimaryWebView.
// The web app provides the group exploration interface.
// Kept for reference - may revisit native implementation in the future.
// Last used: 2025-01-26RootNavigator
└── AuthRootNavigator
├── DrawerNavigator (animated sidebar)
│ └── TabsNavigator (bottom tabs)
│ ├── HomeNavigator (stack)
│ │ ├── Stream (native)
│ │ ├── PostDetails (native)
│ │ ├── ChatRoomWebView
│ │ ├── GroupSettingsWebView
│ │ ├── UserSettingsWebView
│ │ ├── MapWebView
│ │ └── ... 15+ more native screens
│ ├── MessagesNavigator (stack)
│ └── SearchNavigator (stack)
└── Multiple modal screens
RootNavigator
└── AuthRootNavigator
└── PrimaryWebView (full screen)
└── Web app handles everything:
- Navigation (drawer, tabs, routing)
- All content (chat, settings, maps, etc.)
- State management
- UI/UX
- Swipe Gesture Navigation - Mobile-friendly gestures for opening/closing menu
- ChatRoom Navigation Fix - Consistent back/menu button across all devices
- Pull-to-Refresh (Web-side) - Hold-to-confirm gesture with visual feedback
- Expanded Touch Targets - Navigation chevron easier to tap on mobile
- Proper Menu Close Behavior - All header/menu items close menu on navigation
- Clean Modal History - Create modals don't pollute browser history
- mobileSubscriptionExchange - Commented out and no longer used
- File:
apps/mobile/src/urql/mobileSubscriptionExchange.js - Only deprecated screen (PostDetails) used subscriptions
- Web app in WebView handles all real-time updates now
- Updated
makeUrqlClient.jsto filter out undefined exchanges - Updated
index.jsto not pass subscriptionExchange
- File:
All navigator files have been commented out with no-op exports:
| File | Purpose | Status |
|---|---|---|
HomeNavigator.js |
Main content stack (Stream, Posts, Settings) | ✅ Deprecated |
DrawerNavigator.js |
Sidebar drawer menu | ✅ Deprecated |
TabsNavigator.js |
Bottom tab navigation | ✅ Deprecated |
MessagesNavigator.js |
Messages/threads stack | ✅ Deprecated |
SearchNavigator.js |
Search functionality | ✅ Deprecated |
headers/TabStackHeader.js |
Native stack header | ✅ Deprecated |
headers/ModalHeader.js |
Native modal header | ✅ Deprecated |
Phase 1 - Unused packages (11):
react-native-tab-viewreact-native-pager-view@react-navigation/material-top-tabsreact-native-localizationtinycolor2re-reselectreact-native-modalemoji-datasource-applereact-native-ssereact-native-render-html@native-html/iframe-plugin
Phase 2 - Deprecated screen packages (5):
@shopify/flash-listreact-native-date-pickerreact-native-bouncy-checkboxreact-native-image-viewingreact-native-emoji-popup
Phase 3 - Navigation packages (2):
@react-navigation/drawer@react-navigation/bottom-tabs
Code Fixes (no package existed):
react-native-triangle- Replaced with CSS-based trianglesreact-native-background-timer- Removed (was never in package.json)
Ready to remove:
@react-navigation/elements- Only used by deprecated headers
- ChatRoomWebView - Chat interface
- GroupSettingsWebView - Group settings with native menu
- UserSettingsWebView - User settings and logout handling
- MapWebView - Map view with complex navigation handling
- GroupExploreWebView - Group exploration modal
- NAVIGATION - Routed to native screens based on web navigation
- GROUP_DELETED - Cleared state and navigated on group deletion
- CreateGroup
- DrawerNavigator
- CreationOptions
- GroupExploreWebView
- MemberProfile
- PostDetails
- PostEditor
- NotificationsList
- Thread
- UploadAction
- (And their respective screen registrations)
- Login/Signup flow - Remains native (as intended)
- LoadingScreen - Used during initialization
- PrimaryWebView - New main screen
- HyloWebView component - Base WebView wrapper (simplified)
- ✅ Native navigators (Drawer, Tabs, Home, Messages, Search) - All commented out with no-op exports
- ✅ Header components (TabStackHeader, ModalHeader) - Commented out
- ✅ 18+ packages removed from package.json
@react-navigation/native- Core navigation (still needed)@react-navigation/stack- Auth flow navigationurql- Used for useCurrentUser in auth screens- Native screen components (Stream, PostDetails, etc.) - Files exist but not bundled
- ✅ 90% reduction in navigation code
- ✅ Removed 4 specialized WebView screens → 1 unified screen
- ✅ Removed complex message passing for navigation
- ✅ Single WebView instance (better performance)
- ✅ No mismatch between mobile 'stack' nav and web 'path' nav; almost pure path navigation
- ✅ Single source of truth (web app)
- ✅ No more building features twice
- ✅ Instant feature parity with web
- ✅ Easier debugging (one code path)
- ✅ Can revisit native additions later; DMs for example, could benefit from being stored on the device
- ✅ Clear deprecation notices explain what changed
- ✅ Reference implementation for future decisions
The usePostActionSheet hook and react-native-share library provide a native sharing UX pattern
that may be worth keeping or reimplementing:
- Native iOS/Android share sheets feel more integrated than web alternatives
- Action sheets with native icons provide familiar mobile UX
- Could implement a WebView → Native bridge for share functionality
- See TODO in
docs/webview-transition-todo.mdfor follow-up
- ✅ App launches to PrimaryWebView
- ✅ Login flow works (native → WebView)
- ✅ Logout works (WebView triggers native logout)
- ✅ Basic navigation within web app works
- ✅ All web app features accessible
- ✅ File uploads work (iOS & Android)
- ✅ Pull-to-refresh gesture works
- ✅ Swipe gestures work
- ✅ Menu close behavior works
- ✅ Cross-platform (iOS & Android)
- ⏳ Deep links from push notifications
- ⏳ Deep links from email
- ✅ Simplify linking table - Update routes to point to PrimaryWebView
- ✅ Add swipe gestures - Swipe from left edge to open menu, swipe right to close
- ✅ Fix ChatRoom navigation arrow - Added backButton: true to header config
- ✅ Test file uploads - Verify HTML inputs work in WebView (iOS & Android)
- ✅ Add pull-to-refresh - Web-side gesture with hold-to-confirm
- ✅ Deprecate remaining code - Navigator files, native screens, dependencies
- ✅ Verify signup flow - Works with new architecture
- ✅ Test core user flows - Post, comment, profile, messages
- ✅ Cross-platform testing - iOS & Android verified
- ✅ UX polish - Touch targets, menu close, modal history, padding
- ⏳ Verify deep links - Push notifications, email, universal links
- ⏳ Polish loading states - Error handling improvements
- ⏳ Review AuthRootNavigator - Final cleanup of unused setup code
- All deprecated code kept for reference
- Clear comments explain why changes were made
- Can revert if issues found
- Web app must handle logout by sending message to native
- Session cookie sharing already works (proven by existing WebViews)