NavigationContext.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import React, { createContext, useContext, useEffect, useState } from 'react';
  2. import { Linking, Platform } from 'react-native';
  3. import { useNavigation } from '@react-navigation/native';
  4. import { NAVIGATION_PAGES } from 'src/types';
  5. import { storage, StoreType } from 'src/storage';
  6. interface NavigationContextType {
  7. handleDeepLink: () => Promise<void>;
  8. }
  9. const NavigationContext = createContext<NavigationContextType | null>(null);
  10. const parseURL = (url: string) => {
  11. const parsedUrl = new URL(url);
  12. const path = parsedUrl.pathname;
  13. const queryParams = Object.fromEntries(parsedUrl.searchParams.entries());
  14. return { path, queryParams };
  15. };
  16. export const useNavigationContext = () => {
  17. const context = useContext(NavigationContext);
  18. if (!context) {
  19. throw new Error('useNavigationContext must be used within a NavigationProvider');
  20. }
  21. return context;
  22. };
  23. export const NavigationProvider = ({ children }: { children: React.ReactNode }) => {
  24. const navigation = useNavigation();
  25. const token = storage.get('token', StoreType.STRING);
  26. const [initialUrlProcessed, setInitialUrlProcessed] = useState(false);
  27. const handleDeepLink = async (url?: string) => {
  28. const link = url || (await Linking.getInitialURL());
  29. console.log('Deep Link URL:', link);
  30. if (link) {
  31. const { path } = parseURL(link);
  32. console.log('Parsed URL:', { path });
  33. if (path.startsWith('/profile') && token) {
  34. const segments = path.split('/');
  35. const userId = segments[2];
  36. console.log('Navigating to public profile:', userId);
  37. navigation.navigate(...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId }] as never));
  38. }
  39. }
  40. if (!initialUrlProcessed) {
  41. setInitialUrlProcessed(true);
  42. }
  43. };
  44. useEffect(() => {
  45. if (!initialUrlProcessed) {
  46. handleDeepLink();
  47. }
  48. const subscription = Linking.addEventListener('url', (event) => {
  49. console.log('Linking event:', event);
  50. handleDeepLink(event.url);
  51. });
  52. return () => {
  53. subscription.remove();
  54. };
  55. }, [initialUrlProcessed]);
  56. return (
  57. <NavigationContext.Provider value={{ handleDeepLink }}>{children}</NavigationContext.Provider>
  58. );
  59. };