2026-06-15 23:49:47 +07:00
|
|
|
/**
|
|
|
|
|
* Lightweight Tauri environment detection and utilities.
|
|
|
|
|
* Avoids importing @tauri-apps/api at module level so the web build
|
|
|
|
|
* doesn't bundle Tauri internals.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
let _isTauri: boolean | null = null;
|
|
|
|
|
|
|
|
|
|
export function isTauri(): boolean {
|
|
|
|
|
if (_isTauri !== null) return _isTauri;
|
|
|
|
|
_isTauri =
|
|
|
|
|
typeof window !== 'undefined' &&
|
|
|
|
|
'__TAURI_INTERNALS__' in window;
|
|
|
|
|
return _isTauri;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function openUrl(url: string): Promise<void> {
|
|
|
|
|
if (!isTauri()) {
|
|
|
|
|
window.location.href = url;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const { openUrl: tauriOpenUrl } = await import('@tauri-apps/plugin-opener');
|
|
|
|
|
await tauriOpenUrl(url);
|
|
|
|
|
}
|
2026-06-16 01:03:45 +07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Listen for deep link URLs when the app is opened from an external link.
|
|
|
|
|
* On Android, after Google OAuth completes in the system browser, the
|
|
|
|
|
* callback page redirects to zeavisedu://... which triggers this listener.
|
|
|
|
|
* We extract the path + query and navigate the WebView there.
|
|
|
|
|
*/
|
|
|
|
|
export async function setupDeepLinkHandler(): Promise<void> {
|
|
|
|
|
if (!isTauri()) return;
|
|
|
|
|
|
|
|
|
|
const { onOpenUrl } = await import('@tauri-apps/plugin-deep-link');
|
|
|
|
|
onOpenUrl((urls) => {
|
|
|
|
|
for (const url of urls) {
|
2026-06-16 02:44:21 +07:00
|
|
|
// url looks like: zeavisedu://login/login?token=xxx
|
2026-06-16 01:03:45 +07:00
|
|
|
// Extract path + query after the host
|
|
|
|
|
try {
|
|
|
|
|
const u = new URL(url);
|
|
|
|
|
const target = u.pathname + u.search + u.hash;
|
|
|
|
|
if (target && target !== '/') {
|
|
|
|
|
window.location.href = target;
|
2026-06-16 02:44:21 +07:00
|
|
|
return;
|
2026-06-16 01:03:45 +07:00
|
|
|
}
|
2026-06-16 02:44:21 +07:00
|
|
|
} catch { /* try fallback below */ }
|
|
|
|
|
|
|
|
|
|
// Fallback: extract everything after scheme, handling both // and /
|
|
|
|
|
let match = url.match(/^[^:]+:\/\/(?:[^/]+)?(\/.*)?$/);
|
|
|
|
|
if (!match) {
|
|
|
|
|
// Also handle single-slash non-hierarchical URLs (e.g. zeavisedu:/path)
|
|
|
|
|
match = url.match(/^[^:]+:\/(\/.*)?$/);
|
|
|
|
|
}
|
|
|
|
|
if (match?.[1]) {
|
|
|
|
|
window.location.href = match[1];
|
2026-06-16 01:03:45 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|