1import { useSyncExternalStore } from "react";
2
3import { hasCloudPublicConfig } from "./publicConfig";
4
5const STORAGE_KEY = "knife:t3-connect-enabled";
6const listeners = new Set<() => void>();
7
8function restoredOptIn(): boolean {
9 try {
10 return globalThis.localStorage?.getItem(STORAGE_KEY) === "true";
11 } catch {
12 return false;
13 }
14}
15
16let state = { enabled: restoredOptIn(), signInRequested: false };
17
18export function activateCloudAuthentication(signInRequested = false): void {
19 if (!hasCloudPublicConfig()) return;
20 const requested = state.signInRequested || signInRequested;
21 if (state.enabled && state.signInRequested === requested) return;
22 state = { enabled: true, signInRequested: requested };
23 try {
24 localStorage.setItem(STORAGE_KEY, "true");
25 } catch {
26 // The current session can still use Connect when browser storage is blocked.
27 }
28 for (const listener of listeners) listener();
29}
30
31export function deactivateCloudAuthentication(): void {
32 state = { enabled: false, signInRequested: false };
33 try {
34 localStorage.removeItem(STORAGE_KEY);
35 } catch {
36 // Blocked storage does not prevent signing out in this window.
37 }
38 for (const listener of listeners) listener();
39}
40
41export function finishCloudSignInRequest(): void {
42 if (!state.signInRequested) return;
43 state = { ...state, signInRequested: false };
44 for (const listener of listeners) listener();
45}
46
47export function useCloudAuthentication() {
48 return useSyncExternalStore(
49 (listener) => {
50 listeners.add(listener);
51 return () => listeners.delete(listener);
52 },
53 () => state,
54 );
55}