"use client" import { useEffect, useRef, type ReactNode } from "react" import { useRouter } from "next/navigation" import { useNativeRuntime } from "@/lib/platform" import { listen } from "@/lib/native/bridge" import { routeForDeepLink } from "@/lib/native/deep-links" import { takePendingShare, stashShare, shareLandingRoute, } from "@/lib/native/share" import { registerPushAfterLogin } from "@/lib/native/push" import { useAuthStore } from "@/lib/api/auth-store" /** * Wires the native shell capabilities into the React app: deep-link routing, * inbound share intake, and push-token registration after login. Inert on web. */ export function NativeBridgeProvider({ children }: { children: ReactNode }) { const native = useNativeRuntime() const router = useRouter() const accessToken = useAuthStore((s) => s.accessToken) const pushDone = useRef(false) // Deep links -> client navigation. useEffect(() => { if (!native) return let unlisten: (() => void) | null = null void (async () => { unlisten = await listen("ulti://deep-link", (payload) => { const urls = Array.isArray(payload) ? payload : [payload] for (const raw of urls) { if (typeof raw !== "string") continue const route = routeForDeepLink(raw) if (route) router.push(route) } }) })() return () => { if (unlisten) unlisten() } }, [native, router]) // Inbound share content (cold start: drain the native queue). useEffect(() => { if (!native) return void (async () => { const payload = await takePendingShare() if (payload) { stashShare(payload) router.push(shareLandingRoute()) } })() }, [native, router]) // Register the push device token once we have a session. useEffect(() => { if (!native || !accessToken || pushDone.current) return pushDone.current = true void registerPushAfterLogin() }, [native, accessToken]) return <>{children} }