2023-07-07 13:56:08 +03:00
|
|
|
/* eslint-disable max-lines */
|
|
|
|
import { UUID } from "crypto";
|
2023-07-26 00:12:46 +03:00
|
|
|
import { useCallback, useEffect, useState } from "react";
|
2023-07-07 13:56:08 +03:00
|
|
|
|
2023-07-26 00:12:46 +03:00
|
|
|
import { CreateBrainInput } from "@/lib/api/brain/types";
|
2023-07-07 13:56:08 +03:00
|
|
|
import { useBrainApi } from "@/lib/api/brain/useBrainApi";
|
|
|
|
import { useToast } from "@/lib/hooks";
|
|
|
|
import { useEventTracking } from "@/services/analytics/useEventTracking";
|
|
|
|
|
|
|
|
import {
|
|
|
|
getBrainFromLocalStorage,
|
|
|
|
saveBrainInLocalStorage,
|
|
|
|
} from "../helpers/brainLocalStorage";
|
2023-07-18 15:30:19 +03:00
|
|
|
import { MinimalBrainForUser } from "../types";
|
2023-07-07 13:56:08 +03:00
|
|
|
|
|
|
|
// CAUTION: This hook should be use in BrainProvider only. You may be need `useBrainContext` instead.
|
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
|
|
export const useBrainProvider = () => {
|
|
|
|
const { publish } = useToast();
|
|
|
|
const { track } = useEventTracking();
|
2023-07-18 15:30:19 +03:00
|
|
|
const { createBrain, deleteBrain, getBrains, getDefaultBrain } =
|
2023-07-07 13:56:08 +03:00
|
|
|
useBrainApi();
|
|
|
|
|
2023-07-18 15:30:19 +03:00
|
|
|
const [allBrains, setAllBrains] = useState<MinimalBrainForUser[]>([]);
|
2023-07-07 13:56:08 +03:00
|
|
|
const [currentBrainId, setCurrentBrainId] = useState<null | UUID>(null);
|
2023-07-26 00:12:46 +03:00
|
|
|
const [defaultBrainId, setDefaultBrainId] = useState<UUID>();
|
2023-07-07 13:56:08 +03:00
|
|
|
const [isFetchingBrains, setIsFetchingBrains] = useState(false);
|
|
|
|
|
|
|
|
const currentBrain = allBrains.find((brain) => brain.id === currentBrainId);
|
|
|
|
const createBrainHandler = async (
|
2023-07-25 13:08:08 +03:00
|
|
|
brain: CreateBrainInput
|
2023-07-07 13:56:08 +03:00
|
|
|
): Promise<UUID | undefined> => {
|
2023-07-25 13:08:08 +03:00
|
|
|
const createdBrain = await createBrain(brain);
|
2023-07-07 13:56:08 +03:00
|
|
|
try {
|
|
|
|
setAllBrains((prevBrains) => [...prevBrains, createdBrain]);
|
|
|
|
saveBrainInLocalStorage(createdBrain);
|
|
|
|
void track("BRAIN_CREATED");
|
|
|
|
|
|
|
|
return createdBrain.id;
|
|
|
|
} catch {
|
|
|
|
publish({
|
|
|
|
variant: "danger",
|
2023-07-16 00:21:24 +03:00
|
|
|
text: "Error occurred while creating a brain",
|
2023-07-07 13:56:08 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const deleteBrainHandler = async (id: UUID) => {
|
|
|
|
await deleteBrain(id);
|
|
|
|
setAllBrains((prevBrains) => prevBrains.filter((brain) => brain.id !== id));
|
|
|
|
void track("DELETE_BRAIN");
|
2023-07-17 15:38:34 +03:00
|
|
|
publish({
|
|
|
|
variant: "success",
|
|
|
|
text: "Brain deleted",
|
|
|
|
});
|
2023-07-07 13:56:08 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
const fetchAllBrains = useCallback(async () => {
|
|
|
|
setIsFetchingBrains(true);
|
|
|
|
try {
|
|
|
|
const brains = await getBrains();
|
|
|
|
setAllBrains(brains);
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
} finally {
|
|
|
|
setIsFetchingBrains(false);
|
|
|
|
}
|
2023-08-25 11:33:14 +03:00
|
|
|
}, [getBrains]);
|
2023-07-07 13:56:08 +03:00
|
|
|
|
|
|
|
const setActiveBrain = useCallback(
|
|
|
|
({ id, name }: { id: UUID; name: string }) => {
|
|
|
|
const newActiveBrain = { id, name };
|
|
|
|
saveBrainInLocalStorage(newActiveBrain);
|
|
|
|
setCurrentBrainId(id);
|
|
|
|
void track("CHANGE_BRAIN");
|
|
|
|
},
|
2023-08-25 11:33:14 +03:00
|
|
|
[track]
|
2023-07-07 13:56:08 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
const setDefaultBrain = useCallback(async () => {
|
2023-07-26 00:12:46 +03:00
|
|
|
const userDefaultBrain = await getDefaultBrain();
|
|
|
|
if (userDefaultBrain !== undefined) {
|
|
|
|
saveBrainInLocalStorage(userDefaultBrain);
|
|
|
|
setActiveBrain(userDefaultBrain);
|
2023-07-07 13:56:08 +03:00
|
|
|
} else {
|
|
|
|
console.warn("No brains found");
|
|
|
|
}
|
2023-08-25 11:33:14 +03:00
|
|
|
}, [getDefaultBrain, setActiveBrain]);
|
2023-07-07 13:56:08 +03:00
|
|
|
|
|
|
|
const fetchAndSetActiveBrain = useCallback(async () => {
|
|
|
|
const storedBrain = getBrainFromLocalStorage();
|
|
|
|
if (storedBrain?.id !== undefined) {
|
|
|
|
setActiveBrain({ ...storedBrain });
|
|
|
|
} else {
|
|
|
|
await setDefaultBrain();
|
|
|
|
}
|
|
|
|
}, [setDefaultBrain, setActiveBrain]);
|
|
|
|
|
2023-07-26 17:54:03 +03:00
|
|
|
const fetchDefaultBrain = async () => {
|
|
|
|
setDefaultBrainId((await getDefaultBrain())?.id);
|
|
|
|
};
|
2023-07-26 00:12:46 +03:00
|
|
|
useEffect(() => {
|
|
|
|
void fetchDefaultBrain();
|
|
|
|
}, []);
|
|
|
|
|
2023-07-07 13:56:08 +03:00
|
|
|
return {
|
|
|
|
currentBrain,
|
|
|
|
currentBrainId,
|
|
|
|
allBrains,
|
|
|
|
createBrain: createBrainHandler,
|
|
|
|
deleteBrain: deleteBrainHandler,
|
|
|
|
setActiveBrain,
|
2023-08-08 19:18:05 +03:00
|
|
|
setCurrentBrainId,
|
2023-07-07 13:56:08 +03:00
|
|
|
fetchAllBrains,
|
|
|
|
setDefaultBrain,
|
|
|
|
fetchAndSetActiveBrain,
|
|
|
|
isFetchingBrains,
|
2023-07-26 00:12:46 +03:00
|
|
|
defaultBrainId,
|
2023-07-26 17:54:03 +03:00
|
|
|
fetchDefaultBrain,
|
2023-07-07 13:56:08 +03:00
|
|
|
};
|
|
|
|
};
|