43 lines
1.5 KiB
TypeScript
43 lines
1.5 KiB
TypeScript
import { useEffect } from 'react';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { App, type URLOpenListenerEvent } from '@capacitor/app';
|
|
import { isNativePlatform } from '../utils/capacitor';
|
|
|
|
// When Capacitor's WebView is launched via an App Link (or handed a URL while
|
|
// already running), its own location is the local bundle URL — it does NOT
|
|
// navigate to the incoming https URL. We have to read the URL from the App
|
|
// plugin and feed it into react-router ourselves. Covers both cold-launch
|
|
// (getLaunchUrl) and warm taps (appUrlOpen).
|
|
export const useAppUrlOpen = (): void => {
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
if (!isNativePlatform()) return undefined;
|
|
|
|
let active = true;
|
|
|
|
const route = (rawUrl: string | undefined) => {
|
|
if (!active || !rawUrl) return;
|
|
try {
|
|
const u = new URL(rawUrl);
|
|
if (u.hostname !== 'vojo.chat') return;
|
|
// Strip any ?web=1 fallback marker and forward path+hash to the SPA
|
|
// router, which owns the /u/:user route.
|
|
if (!u.pathname.startsWith('/u/')) return;
|
|
navigate(u.pathname + u.hash, { replace: true });
|
|
} catch {
|
|
// malformed URL — ignore
|
|
}
|
|
};
|
|
|
|
App.getLaunchUrl().then((r) => route(r?.url));
|
|
const listenerPromise = App.addListener('appUrlOpen', (event: URLOpenListenerEvent) =>
|
|
route(event.url)
|
|
);
|
|
|
|
return () => {
|
|
active = false;
|
|
listenerPromise.then((l) => l.remove());
|
|
};
|
|
}, [navigate]);
|
|
};
|