Add 'apps/mobile/' from commit '5fa30f365f21531094cd4d2045042bb4f1370ac3'
git-subtree-dir: apps/mobile git-subtree-mainline:86f8987dffgit-subtree-split:5fa30f365f
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
import { httpBatchLink } from "@trpc/client";
|
||||
import { createTRPCReact } from "@trpc/react-query";
|
||||
import {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
import SuperJSON from "superjson";
|
||||
|
||||
import { LoadingScreen } from "@/components/LoadingScreen";
|
||||
import { useAccounts } from "@/contexts/AccountsContext";
|
||||
import { useAuthClient, useSession } from "@/contexts/AuthContext";
|
||||
import { getAuthCookieHeaders } from "@/lib/auth-cookie";
|
||||
import { configureReactQueryOnlineManager } from "@/lib/network-status";
|
||||
import {
|
||||
persistOfflineQueryCache,
|
||||
restoreOfflineQueryCache,
|
||||
} from "@/lib/offline-cache";
|
||||
import { performAuthReset } from "@/lib/auth-session";
|
||||
import { createAppQueryClient } from "@/lib/query-client";
|
||||
import type { AppRouter } from "beenvoice/server/api/root";
|
||||
|
||||
export const api = createTRPCReact<AppRouter>();
|
||||
|
||||
export function TRPCProvider({
|
||||
apiUrl,
|
||||
children,
|
||||
}: {
|
||||
apiUrl: string;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const authClient = useAuthClient();
|
||||
const { authStoragePrefix, activeAccountId, clearActiveAccount } =
|
||||
useAccounts();
|
||||
const { refetch } = useSession();
|
||||
const authStoragePrefixRef = useRef(authStoragePrefix);
|
||||
authStoragePrefixRef.current = authStoragePrefix;
|
||||
const [cacheReady, setCacheReady] = useState(false);
|
||||
|
||||
const mountedRef = useRef(true);
|
||||
const resettingRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
mountedRef.current = true;
|
||||
return () => {
|
||||
mountedRef.current = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleUnauthorized = useCallback(async () => {
|
||||
if (!activeAccountId || resettingRef.current || !mountedRef.current) return;
|
||||
|
||||
const session = await authClient.getSession();
|
||||
if (session.data?.user || !mountedRef.current) return;
|
||||
|
||||
resettingRef.current = true;
|
||||
try {
|
||||
await performAuthReset({
|
||||
authClient,
|
||||
clearActiveAccount,
|
||||
activeAccountId,
|
||||
refetchSession: refetch,
|
||||
});
|
||||
} finally {
|
||||
resettingRef.current = false;
|
||||
}
|
||||
}, [authClient, clearActiveAccount, activeAccountId, refetch]);
|
||||
|
||||
const onUnauthorizedRef = useRef(handleUnauthorized);
|
||||
onUnauthorizedRef.current = handleUnauthorized;
|
||||
|
||||
const [queryClient] = useState(() =>
|
||||
createAppQueryClient(() => {
|
||||
void onUnauthorizedRef.current();
|
||||
}),
|
||||
);
|
||||
|
||||
const [trpcClient] = useState(() =>
|
||||
api.createClient({
|
||||
links: [
|
||||
httpBatchLink({
|
||||
url: `${apiUrl}/api/trpc`,
|
||||
transformer: SuperJSON,
|
||||
headers() {
|
||||
return getAuthCookieHeaders(
|
||||
authClient,
|
||||
authStoragePrefixRef.current,
|
||||
);
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
configureReactQueryOnlineManager();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
setCacheReady(false);
|
||||
|
||||
restoreOfflineQueryCache({
|
||||
queryClient,
|
||||
accountId: activeAccountId,
|
||||
apiUrl,
|
||||
}).finally(() => {
|
||||
if (!cancelled && mountedRef.current) {
|
||||
setCacheReady(true);
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [activeAccountId, apiUrl, queryClient]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!cacheReady) return;
|
||||
|
||||
return persistOfflineQueryCache({
|
||||
queryClient,
|
||||
accountId: activeAccountId,
|
||||
apiUrl,
|
||||
});
|
||||
}, [activeAccountId, apiUrl, cacheReady, queryClient]);
|
||||
|
||||
if (!cacheReady) {
|
||||
return <LoadingScreen message="Loading saved data…" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<api.Provider client={trpcClient} queryClient={queryClient}>
|
||||
{children}
|
||||
</api.Provider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user