Files
jrshikoku/lib/useStartupDeepLinkNavigation.ts

107 lines
2.6 KiB
TypeScript

import { useEffect } from "react";
import { Linking } from "react-native";
import { SheetManager } from "react-native-actions-sheet";
import {
markStartupExplicitTarget,
resolveStartupNavigationSource,
rootNavigationRef,
stackAwareNavigate,
} from "@/lib/rootNavigation";
import {
parseStartupDeepLinkIntent,
type StartupDeepLinkIntent,
} from "@/lib/startupDeepLink";
const MAX_NAVIGATION_READY_RETRIES = 8;
const NAVIGATION_READY_RETRY_DELAY_MS = 250;
function navigateWhenReady(
callback: () => void,
retryCount = 0,
): void {
if (!rootNavigationRef.isReady()) {
if (retryCount < MAX_NAVIGATION_READY_RETRIES) {
setTimeout(
() =>
navigateWhenReady(
callback,
retryCount + 1,
),
NAVIGATION_READY_RETRY_DELAY_MS,
);
}
return;
}
callback();
}
function useStartupDeepLinkNavigation(): void {
useEffect(() => {
const openFelicaPage = (retryCount = 0): void => {
if (!rootNavigationRef.isReady()) {
if (retryCount < MAX_NAVIGATION_READY_RETRIES) {
setTimeout(
() => openFelicaPage(retryCount + 1),
NAVIGATION_READY_RETRY_DELAY_MS,
);
}
return;
}
stackAwareNavigate("topMenu", {
screen: "setting",
params: {
screen: "FelicaHistoryPage",
},
});
};
const startupRouteActions: Record<StartupDeepLinkIntent, () => void> = {
felicaHistory: openFelicaPage,
trainInfo: () => {
stackAwareNavigate("topMenu", { screen: "menu" });
setTimeout(() => {
SheetManager.show("JRSTraInfo");
}, 450);
},
operation: () => stackAwareNavigate("information"),
settings: () =>
stackAwareNavigate("topMenu", {
screen: "setting",
}),
topMenu: () =>
stackAwareNavigate("topMenu", {
screen: "menu",
}),
positions: () => stackAwareNavigate("positions"),
};
const routeFromUrl = (url: string): boolean => {
const intent = parseStartupDeepLinkIntent(url);
if (!intent) return false;
markStartupExplicitTarget();
navigateWhenReady(startupRouteActions[intent]);
return true;
};
Linking.getInitialURL()
.then((url) => {
if (url) routeFromUrl(url);
})
.finally(() => {
resolveStartupNavigationSource();
});
const subscription = Linking.addEventListener("url", ({ url }) => {
routeFromUrl(url);
});
return () => {
subscription.remove();
};
}, []);
}
export { useStartupDeepLinkNavigation };