2025-06-23 09:34:30 +00:00
|
|
|
import { createStore, StoreApi, useStore } from "zustand";
|
|
|
|
|
import React from "react";
|
|
|
|
|
import { supabase } from "@ui/hooks/auth";
|
|
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
|
|
|
import { Tables } from "@ui/types/database.types";
|
|
|
|
|
import { useSession } from "@ui/contexts/SessionContext";
|
|
|
|
|
import { api } from "@ui/lib/api";
|
2025-06-24 19:20:24 +00:00
|
|
|
import { LoadingSpinner } from "@ui/components/LoadingSpinner";
|
2025-06-23 09:34:30 +00:00
|
|
|
|
|
|
|
|
type User = Tables<"profiles"> & {
|
|
|
|
|
streamToken: string | null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const UserStoreContext = React.createContext<StoreApi<User> | null>(null);
|
|
|
|
|
|
|
|
|
|
export const UserStoreProvider = ({
|
|
|
|
|
children,
|
|
|
|
|
}: {
|
|
|
|
|
children: React.ReactNode;
|
|
|
|
|
}) => {
|
|
|
|
|
const { session } = useSession();
|
2025-06-28 12:52:57 +00:00
|
|
|
const shouldFetchUser = !!session?.access_token;
|
2025-06-23 09:34:30 +00:00
|
|
|
const { data, isPending } = useQuery<User | null>({
|
|
|
|
|
queryKey: ["user"],
|
|
|
|
|
queryFn: async () => {
|
|
|
|
|
const { data, error } = await supabase.from("profiles").select("*");
|
|
|
|
|
if (error) throw error;
|
2025-06-24 19:20:24 +00:00
|
|
|
let token = null;
|
|
|
|
|
try {
|
|
|
|
|
const {
|
|
|
|
|
data: { token: streamToken },
|
|
|
|
|
} = await api.get("/api/v1/users/get-stream-token", {
|
|
|
|
|
headers: {
|
|
|
|
|
Authorization: `Bearer ${session?.access_token}`,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
token = streamToken;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Failed to get stream token:", error);
|
|
|
|
|
}
|
2025-06-23 09:34:30 +00:00
|
|
|
return {
|
|
|
|
|
...data[0],
|
|
|
|
|
streamToken: token,
|
|
|
|
|
};
|
|
|
|
|
},
|
2025-06-28 12:52:57 +00:00
|
|
|
enabled: shouldFetchUser,
|
2025-06-23 09:34:30 +00:00
|
|
|
});
|
|
|
|
|
|
2025-06-28 12:52:57 +00:00
|
|
|
if (isPending && shouldFetchUser) {
|
2025-06-24 19:20:24 +00:00
|
|
|
return <LoadingSpinner />;
|
2025-06-23 09:34:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!data) {
|
|
|
|
|
return children;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const store = createStore<User>()(() => data);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<UserStoreContext.Provider value={store as StoreApi<User>}>
|
|
|
|
|
{children}
|
|
|
|
|
</UserStoreContext.Provider>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useUser = () => {
|
|
|
|
|
const store = React.useContext(UserStoreContext);
|
|
|
|
|
if (!store) {
|
|
|
|
|
throw new Error("Missing UserStoreProvider");
|
|
|
|
|
}
|
|
|
|
|
return useStore(store);
|
|
|
|
|
};
|