a tool for shared writing and social publishing
at main 62 lines 1.9 kB view raw
1"use client"; 2import { getIdentityData } from "actions/getIdentityData"; 3import { createContext, useContext, useEffect } from "react"; 4import useSWR, { KeyedMutator, mutate } from "swr"; 5import { DashboardState } from "./PageLayouts/DashboardLayout"; 6import { supabaseBrowserClient } from "supabase/browserClient"; 7import { produce, Draft } from "immer"; 8 9export type InterfaceState = { 10 dashboards: { [id: string]: DashboardState | undefined }; 11}; 12export type Identity = Awaited<ReturnType<typeof getIdentityData>>; 13let IdentityContext = createContext({ 14 identity: null as Identity, 15 mutate: (() => {}) as KeyedMutator<Identity>, 16}); 17export const useIdentityData = () => useContext(IdentityContext); 18 19export function mutateIdentityData( 20 mutate: KeyedMutator<Identity>, 21 recipe: (draft: Draft<NonNullable<Identity>>) => void, 22) { 23 mutate( 24 (data) => { 25 if (!data) return data; 26 return produce(data, recipe); 27 }, 28 { revalidate: false }, 29 ); 30} 31export function IdentityContextProvider(props: { 32 children: React.ReactNode; 33 initialValue: Identity; 34}) { 35 let { data: identity, mutate } = useSWR("identity", () => getIdentityData(), { 36 fallbackData: props.initialValue, 37 revalidateOnFocus: false, 38 revalidateOnReconnect: false, 39 revalidateIfStale: false, 40 revalidateOnMount: false, 41 }); 42 useEffect(() => { 43 mutate(props.initialValue); 44 }, [props.initialValue]); 45 useEffect(() => { 46 if (!identity?.atp_did) return; 47 let supabase = supabaseBrowserClient(); 48 let channel = supabase.channel(`identity.atp_did:${identity.atp_did}`); 49 channel.on("broadcast", { event: "notification" }, () => { 50 mutate(); 51 }); 52 channel.subscribe(); 53 return () => { 54 channel.unsubscribe(); 55 }; 56 }, [identity?.atp_did]); 57 return ( 58 <IdentityContext.Provider value={{ identity, mutate }}> 59 {props.children} 60 </IdentityContext.Provider> 61 ); 62}