a tool for shared writing and social publishing
at update/delete-blocks 58 lines 1.8 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 }); 38 useEffect(() => { 39 mutate(props.initialValue); 40 }, [props.initialValue]); 41 useEffect(() => { 42 if (!identity?.atp_did) return; 43 let supabase = supabaseBrowserClient(); 44 let channel = supabase.channel(`identity.atp_did:${identity.atp_did}`); 45 channel.on("broadcast", { event: "notification" }, () => { 46 mutate(); 47 }); 48 channel.subscribe(); 49 return () => { 50 channel.unsubscribe(); 51 }; 52 }, [identity?.atp_did]); 53 return ( 54 <IdentityContext.Provider value={{ identity, mutate }}> 55 {props.children} 56 </IdentityContext.Provider> 57 ); 58}