/ hooks / useNavigationHistory.ts
useNavigationHistory.ts
  1  import { useEffect, useCallback, useState } from 'react';
  2  import { usePathname, useRouter } from 'expo-router';
  3  import navigationService from '@/services/navigationHistoryService';
  4  import { NavigationState, NavigationSettings } from '@/types/navigation';
  5  
  6  export const useNavigationHistory = () => {
  7    const pathname = usePathname();
  8    const router = useRouter();
  9    const [navigationState, setNavigationState] = useState<NavigationState>({
 10      canGoBack: false,
 11      canGoForward: false,
 12      currentDepth: 0,
 13      contextHistory: [],
 14      breadcrumbs: [],
 15      suggestions: [],
 16    });
 17    const [settings, setSettings] = useState<NavigationSettings | null>(null);
 18  
 19    const handleBackPress = useCallback(
 20      async (gestureType: 'tap' | 'swipe' = 'tap') => {
 21        try {
 22          const previousRoute =
 23            await navigationService.getPreviousRoute(pathname);
 24  
 25          // Record gesture usage
 26          await navigationService.recordGestureUsage(
 27            gestureType === 'swipe' ? 'swipeBack' : 'tapBack'
 28          );
 29  
 30          router.replace(previousRoute as any);
 31        } catch (error) {
 32          console.error('Error handling back press:', error);
 33          router.replace('/mangasearch' as any);
 34        }
 35      },
 36      [pathname, router]
 37    );
 38  
 39    const navigateTo = useCallback(
 40      async (
 41        path: string,
 42        options?: {
 43          title?: string;
 44          metadata?: any;
 45          replace?: boolean;
 46        }
 47      ) => {
 48        try {
 49          // Add to history with optional metadata
 50          await navigationService.addToHistory(path, {
 51            ...(options?.title && { title: options.title }),
 52            metadata: options?.metadata,
 53          });
 54  
 55          if (options?.replace) {
 56            router.replace(path as any);
 57          } else {
 58            router.push(path as any);
 59          }
 60        } catch (error) {
 61          console.error('Error navigating:', error);
 62        }
 63      },
 64      [router]
 65    );
 66  
 67    const navigateToBreadcrumb = useCallback(
 68      async (path: string) => {
 69        try {
 70          await navigationService.recordGestureUsage('breadcrumbUsage');
 71          router.replace(path as any);
 72        } catch (error) {
 73          console.error('Error navigating via breadcrumb:', error);
 74        }
 75      },
 76      [router]
 77    );
 78  
 79    const clearHistory = useCallback(async () => {
 80      try {
 81        await navigationService.clearHistory();
 82        // Refresh navigation state
 83        const newState = await navigationService.getNavigationState(pathname);
 84        setNavigationState(newState);
 85      } catch (error) {
 86        console.error('Error clearing history:', error);
 87      }
 88    }, [pathname]);
 89  
 90    const updateSettings = useCallback(
 91      async (newSettings: Partial<NavigationSettings>) => {
 92        try {
 93          await navigationService.updateSettings(newSettings);
 94          const updatedSettings = await navigationService.getSettings();
 95          setSettings(updatedSettings);
 96        } catch (error) {
 97          console.error('Error updating settings:', error);
 98        }
 99      },
100      []
101    );
102  
103    const getAnalytics = useCallback(async () => {
104      try {
105        return await navigationService.getAnalytics();
106      } catch (error) {
107        console.error('Error getting analytics:', error);
108        return null;
109      }
110    }, []);
111  
112    // Update navigation state when pathname changes
113    useEffect(() => {
114      const updateState = async () => {
115        try {
116          // Add current path to history
117          await navigationService.addToHistory(pathname);
118  
119          // Get updated navigation state
120          const state = await navigationService.getNavigationState(pathname);
121          setNavigationState(state);
122        } catch (error) {
123          console.error('Error updating navigation state:', error);
124        }
125      };
126  
127      updateState();
128    }, [pathname]);
129  
130    // Load settings on mount
131    useEffect(() => {
132      const loadSettings = async () => {
133        try {
134          const currentSettings = await navigationService.getSettings();
135          setSettings(currentSettings);
136        } catch (error) {
137          console.error('Error loading settings:', error);
138        }
139      };
140  
141      loadSettings();
142    }, []);
143  
144    return {
145      // Navigation actions
146      handleBackPress,
147      navigateTo,
148      navigateToBreadcrumb,
149      clearHistory,
150  
151      // Settings management
152      updateSettings,
153  
154      // Analytics
155      getAnalytics,
156  
157      // State
158      navigationState,
159      settings,
160  
161      // Computed values
162      canGoBack: navigationState.canGoBack,
163      breadcrumbs: navigationState.breadcrumbs,
164      suggestions: navigationState.suggestions,
165      currentDepth: navigationState.currentDepth,
166    };
167  };