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