a tool for shared writing and social publishing
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}