Skip to content

Latest commit

 

History

History
451 lines (356 loc) · 15.6 KB

File metadata and controls

451 lines (356 loc) · 15.6 KB

WebView Architecture Migration - Changes Made

Date: 2025-01-26 (Updated: 2025-01-29)
Status: Phase 5 Complete - UX Polish & Testing

Summary

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

Files Modified

1. /apps/mobile/src/navigation/AuthRootNavigator.js

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 Drawer screen with PrimaryWebView
  • ✅ Removed 10+ modal screens
  • ✅ Commented out deprecated imports
  • ✅ Added deprecation comments explaining the change

2. /apps/mobile/src/components/HyloWebView/HyloWebView.js

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

3. Added Swipe Gesture Navigation

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

4. Added Pull-to-Refresh (Web-side)

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

5. UX Improvements for Mobile WebView

Expanded Touch Targets

Modified apps/web/src/components/ViewHeader/ViewHeader.jsx:

  • Wrapped ChevronLeft icons in <button> elements with p-2 padding
  • 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 navigateAndClose helper that dispatches toggleNavMenu(false)

Modified apps/web/src/components/CreateMenu/CreateMenu.jsx:

  • All creation links (post types, track, funding round, group) now close menu
  • Added handleLinkClick callback to dispatch toggleNavMenu(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) to navigate(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 backButton is true
  • Fixes issue where backButton: true was overriding menu toggle on mobile

CreateGroup Page Padding

Modified apps/web/src/routes/CreateGroup/CreateGroup.jsx:

  • Added px-4 to container for horizontal padding on small screens
  • Prevents content from touching screen edges on mobile

6. Deprecated WebView Screen Files

Added deprecation headers to the following files:

/apps/mobile/src/screens/ChatRoomWebView/ChatRoomWebView.js

// 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

/apps/mobile/src/screens/GroupSettingsWebView/GroupSettingsWebView.js

// 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

/apps/mobile/src/screens/UserSettingsWebView/UserSettingsWebView.js

// 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

/apps/mobile/src/screens/MapWebView/MapWebView.js

// 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

/apps/mobile/src/screens/GroupExploreWebView/GroupExploreWebView.js

// 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-26

Architecture Change Summary

Before: Complex Nested Navigation

RootNavigator
└── 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

After: Simple Single WebView

RootNavigator
└── AuthRootNavigator
    └── PrimaryWebView (full screen)
        └── Web app handles everything:
            - Navigation (drawer, tabs, routing)
            - All content (chat, settings, maps, etc.)
            - State management
            - UI/UX

What Was Removed/Deprecated

New Features Added

  1. Swipe Gesture Navigation - Mobile-friendly gestures for opening/closing menu
  2. ChatRoom Navigation Fix - Consistent back/menu button across all devices
  3. Pull-to-Refresh (Web-side) - Hold-to-confirm gesture with visual feedback
  4. Expanded Touch Targets - Navigation chevron easier to tap on mobile
  5. Proper Menu Close Behavior - All header/menu items close menu on navigation
  6. Clean Modal History - Create modals don't pollute browser history

Code Deprecated

  1. 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.js to filter out undefined exchanges
    • Updated index.js to not pass subscriptionExchange

Deprecated Navigator Files

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

Dependencies Removed

Phase 1 - Unused packages (11):

  • react-native-tab-view
  • react-native-pager-view
  • @react-navigation/material-top-tabs
  • react-native-localization
  • tinycolor2
  • re-reselect
  • react-native-modal
  • emoji-datasource-apple
  • react-native-sse
  • react-native-render-html
  • @native-html/iframe-plugin

Phase 2 - Deprecated screen packages (5):

  • @shopify/flash-list
  • react-native-date-picker
  • react-native-bouncy-checkbox
  • react-native-image-viewing
  • react-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 triangles
  • react-native-background-timer - Removed (was never in package.json)

Ready to remove:

  • @react-navigation/elements - Only used by deprecated headers

Deprecated Screen Components (5)

  1. ChatRoomWebView - Chat interface
  2. GroupSettingsWebView - Group settings with native menu
  3. UserSettingsWebView - User settings and logout handling
  4. MapWebView - Map view with complex navigation handling
  5. GroupExploreWebView - Group exploration modal

Deprecated Message Handling (2 cases)

  1. NAVIGATION - Routed to native screens based on web navigation
  2. GROUP_DELETED - Cleared state and navigated on group deletion

Commented Out Imports (11)

  • CreateGroup
  • DrawerNavigator
  • CreationOptions
  • GroupExploreWebView
  • MemberProfile
  • PostDetails
  • PostEditor
  • NotificationsList
  • Thread
  • UploadAction
  • (And their respective screen registrations)

What Remains

Still Active

  • Login/Signup flow - Remains native (as intended)
  • LoadingScreen - Used during initialization
  • PrimaryWebView - New main screen
  • HyloWebView component - Base WebView wrapper (simplified)

Recently Deprecated

  • ✅ 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

Still Active (Minimal)

  • @react-navigation/native - Core navigation (still needed)
  • @react-navigation/stack - Auth flow navigation
  • urql - Used for useCurrentUser in auth screens
  • Native screen components (Stream, PostDetails, etc.) - Files exist but not bundled

Benefits Achieved

Simplification

  • ✅ 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

Maintainability

  • ✅ Single source of truth (web app)
  • ✅ No more building features twice
  • ✅ Instant feature parity with web
  • ✅ Easier debugging (one code path)

Future-Proofing

  • ✅ 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

Worth Revisiting: Native Action Sheet UX

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.md for follow-up

Testing Status

Completed Testing

  1. ✅ App launches to PrimaryWebView
  2. ✅ Login flow works (native → WebView)
  3. ✅ Logout works (WebView triggers native logout)
  4. ✅ Basic navigation within web app works
  5. ✅ All web app features accessible
  6. ✅ File uploads work (iOS & Android)
  7. ✅ Pull-to-refresh gesture works
  8. ✅ Swipe gestures work
  9. ✅ Menu close behavior works
  10. ✅ Cross-platform (iOS & Android)

Remaining Testing

  • ⏳ Deep links from push notifications
  • ⏳ Deep links from email

Next Tasks

Completed

  1. Simplify linking table - Update routes to point to PrimaryWebView
  2. Add swipe gestures - Swipe from left edge to open menu, swipe right to close
  3. Fix ChatRoom navigation arrow - Added backButton: true to header config
  4. Test file uploads - Verify HTML inputs work in WebView (iOS & Android)
  5. Add pull-to-refresh - Web-side gesture with hold-to-confirm
  6. Deprecate remaining code - Navigator files, native screens, dependencies
  7. Verify signup flow - Works with new architecture
  8. Test core user flows - Post, comment, profile, messages
  9. Cross-platform testing - iOS & Android verified
  10. UX polish - Touch targets, menu close, modal history, padding

Remaining

  • Verify deep links - Push notifications, email, universal links
  • Polish loading states - Error handling improvements
  • Review AuthRootNavigator - Final cleanup of unused setup code

Notes

  • 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)