NavigationContext.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import React, { createContext, useContext, useEffect, useState } from 'react';
  2. import { Linking } from 'react-native';
  3. import { CommonActions, 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 = () => useContext(NavigationContext);
  17. export const NavigationProvider = ({ children }: { children: React.ReactNode }) => {
  18. const navigation = useNavigation();
  19. const token = storage.get('token', StoreType.STRING);
  20. const [initialUrlProcessed, setInitialUrlProcessed] = useState(false);
  21. const handleDeepLink = async (url?: string) => {
  22. const link = url || (await Linking.getInitialURL());
  23. if (link) {
  24. const { path } = parseURL(link);
  25. if (path.startsWith('/profile') && token) {
  26. const segments = path.split('/');
  27. const userId = segments[2];
  28. navigation.navigate(...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId }] as never));
  29. } else if (path.startsWith('/event')) {
  30. const segments = path.split('/');
  31. const eventUrl = segments[2];
  32. navigation.dispatch(
  33. CommonActions.reset({
  34. index: 1,
  35. routes: [
  36. {
  37. name: 'DrawerApp',
  38. state: {
  39. routes: [
  40. {
  41. name: NAVIGATION_PAGES.IN_APP_TRAVELS_TAB,
  42. state: {
  43. routes: [
  44. { name: NAVIGATION_PAGES.EVENTS },
  45. {
  46. name: NAVIGATION_PAGES.EVENT,
  47. params: { url: eventUrl }
  48. }
  49. ]
  50. }
  51. }
  52. ]
  53. }
  54. }
  55. ]
  56. })
  57. );
  58. }
  59. }
  60. if (!initialUrlProcessed) {
  61. setInitialUrlProcessed(true);
  62. }
  63. };
  64. useEffect(() => {
  65. if (!initialUrlProcessed) {
  66. handleDeepLink();
  67. }
  68. const subscription = Linking.addEventListener('url', (event) => {
  69. handleDeepLink(event.url);
  70. });
  71. return () => {
  72. subscription.remove();
  73. };
  74. }, [initialUrlProcessed]);
  75. return (
  76. <NavigationContext.Provider value={{ handleDeepLink }}>{children}</NavigationContext.Provider>
  77. );
  78. };