227 lines
6.4 KiB
TypeScript
227 lines
6.4 KiB
TypeScript
|
import type { ApiError } from "browserfs/dist/node/core/api_error";
|
||
|
import type { SortBy } from "components/system/Files/FileManager/useSortBy";
|
||
|
import { useFileSystem } from "contexts/fileSystem";
|
||
|
import type {
|
||
|
IconPositions,
|
||
|
SessionContextState,
|
||
|
SessionData,
|
||
|
SortOrders,
|
||
|
WallpaperFit,
|
||
|
WindowStates,
|
||
|
} from "contexts/session/types";
|
||
|
import defaultSession from "public/session.json";
|
||
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||
|
import {
|
||
|
DEFAULT_AI_API,
|
||
|
DEFAULT_ASCENDING,
|
||
|
DEFAULT_CLOCK_SOURCE,
|
||
|
DEFAULT_THEME,
|
||
|
DEFAULT_WALLPAPER,
|
||
|
DEFAULT_WALLPAPER_FIT,
|
||
|
SESSION_FILE,
|
||
|
} from "utils/constants";
|
||
|
|
||
|
const DEFAULT_SESSION = (defaultSession || {}) as unknown as SessionData;
|
||
|
|
||
|
const useSessionContextState = (): SessionContextState => {
|
||
|
const { deletePath, readFile, rootFs, writeFile, lstat } = useFileSystem();
|
||
|
const [sessionLoaded, setSessionLoaded] = useState(false);
|
||
|
const [foregroundId, setForegroundId] = useState("");
|
||
|
const [aiApi, setAiApi] = useState(DEFAULT_AI_API);
|
||
|
const [stackOrder, setStackOrder] = useState<string[]>([]);
|
||
|
const [themeName, setThemeName] = useState(DEFAULT_THEME);
|
||
|
const [clockSource, setClockSource] = useState(DEFAULT_CLOCK_SOURCE);
|
||
|
const [windowStates, setWindowStates] = useState(
|
||
|
Object.create(null) as WindowStates
|
||
|
);
|
||
|
const [sortOrders, setSortOrders] = useState(
|
||
|
Object.create(null) as SortOrders
|
||
|
);
|
||
|
const [iconPositions, setIconPositions] = useState(
|
||
|
Object.create(null) as IconPositions
|
||
|
);
|
||
|
const [wallpaperFit, setWallpaperFit] = useState(DEFAULT_WALLPAPER_FIT);
|
||
|
const [wallpaperImage, setWallpaperImage] = useState(DEFAULT_WALLPAPER);
|
||
|
const [runHistory, setRunHistory] = useState<string[]>([]);
|
||
|
const prependToStack = useCallback(
|
||
|
(id: string) =>
|
||
|
setStackOrder((currentStackOrder) =>
|
||
|
currentStackOrder[0] === id
|
||
|
? currentStackOrder
|
||
|
: [id, ...currentStackOrder.filter((stackId) => stackId !== id)]
|
||
|
),
|
||
|
[]
|
||
|
);
|
||
|
const removeFromStack = useCallback(
|
||
|
(id: string) =>
|
||
|
setStackOrder((currentStackOrder) =>
|
||
|
currentStackOrder.filter((stackId) => stackId !== id)
|
||
|
),
|
||
|
[]
|
||
|
);
|
||
|
const setWallpaper = useCallback(
|
||
|
(image: string, fit?: WallpaperFit): void => {
|
||
|
if (fit) setWallpaperFit(fit);
|
||
|
setWallpaperImage(image);
|
||
|
},
|
||
|
[]
|
||
|
);
|
||
|
const [haltSession, setHaltSession] = useState(false);
|
||
|
const setSortOrder = useCallback(
|
||
|
(
|
||
|
directory: string,
|
||
|
order: string[] | ((currentSortOrder: string[]) => string[]),
|
||
|
sortBy?: SortBy,
|
||
|
ascending?: boolean
|
||
|
): void =>
|
||
|
setSortOrders((currentSortOrder = {}) => {
|
||
|
const [currentOrder, currentSortBy, currentAscending] =
|
||
|
currentSortOrder[directory] || [];
|
||
|
const newOrder =
|
||
|
typeof order === "function" ? order(currentOrder) : order;
|
||
|
|
||
|
return {
|
||
|
...currentSortOrder,
|
||
|
[directory]: [
|
||
|
newOrder,
|
||
|
sortBy ?? currentSortBy,
|
||
|
ascending ?? currentAscending ?? DEFAULT_ASCENDING,
|
||
|
],
|
||
|
};
|
||
|
}),
|
||
|
[]
|
||
|
);
|
||
|
const initializedSession = useRef(false);
|
||
|
|
||
|
useEffect(() => {
|
||
|
if (sessionLoaded && !haltSession) {
|
||
|
const updateSessionFile = (): void => {
|
||
|
writeFile(
|
||
|
SESSION_FILE,
|
||
|
JSON.stringify({
|
||
|
aiApi,
|
||
|
clockSource,
|
||
|
iconPositions,
|
||
|
runHistory,
|
||
|
sortOrders,
|
||
|
themeName,
|
||
|
wallpaperFit,
|
||
|
wallpaperImage,
|
||
|
windowStates,
|
||
|
}),
|
||
|
true
|
||
|
);
|
||
|
};
|
||
|
|
||
|
if (
|
||
|
"requestIdleCallback" in window &&
|
||
|
typeof window.requestIdleCallback === "function"
|
||
|
) {
|
||
|
requestIdleCallback(updateSessionFile);
|
||
|
} else {
|
||
|
updateSessionFile();
|
||
|
}
|
||
|
}
|
||
|
}, [
|
||
|
aiApi,
|
||
|
clockSource,
|
||
|
haltSession,
|
||
|
iconPositions,
|
||
|
runHistory,
|
||
|
sessionLoaded,
|
||
|
sortOrders,
|
||
|
themeName,
|
||
|
wallpaperFit,
|
||
|
wallpaperImage,
|
||
|
windowStates,
|
||
|
writeFile,
|
||
|
]);
|
||
|
|
||
|
useEffect(() => {
|
||
|
if (!initializedSession.current && rootFs) {
|
||
|
const initSession = async (): Promise<void> => {
|
||
|
initializedSession.current = true;
|
||
|
|
||
|
try {
|
||
|
let session: SessionData;
|
||
|
|
||
|
try {
|
||
|
session =
|
||
|
(await lstat(SESSION_FILE)).blocks <= 0
|
||
|
? DEFAULT_SESSION
|
||
|
: (JSON.parse(
|
||
|
(await readFile(SESSION_FILE)).toString()
|
||
|
) as SessionData);
|
||
|
} catch {
|
||
|
session = DEFAULT_SESSION;
|
||
|
}
|
||
|
|
||
|
if (session.aiApi) setAiApi(session.aiApi);
|
||
|
if (session.clockSource) setClockSource(session.clockSource);
|
||
|
if (session.themeName) setThemeName(session.themeName);
|
||
|
if (session.wallpaperImage) {
|
||
|
setWallpaper(session.wallpaperImage, session.wallpaperFit);
|
||
|
}
|
||
|
if (
|
||
|
session.sortOrders &&
|
||
|
Object.keys(session.sortOrders).length > 0
|
||
|
) {
|
||
|
setSortOrders(session.sortOrders);
|
||
|
}
|
||
|
if (
|
||
|
session.iconPositions &&
|
||
|
Object.keys(session.iconPositions).length > 0
|
||
|
) {
|
||
|
setIconPositions(session.iconPositions);
|
||
|
}
|
||
|
if (
|
||
|
session.windowStates &&
|
||
|
Object.keys(session.windowStates).length > 0
|
||
|
) {
|
||
|
setWindowStates(session.windowStates);
|
||
|
}
|
||
|
if (session.runHistory && session.runHistory.length > 0) {
|
||
|
setRunHistory(session.runHistory);
|
||
|
}
|
||
|
} catch (error) {
|
||
|
if ((error as ApiError)?.code === "ENOENT") {
|
||
|
deletePath(SESSION_FILE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
setSessionLoaded(true);
|
||
|
};
|
||
|
|
||
|
initSession();
|
||
|
}
|
||
|
}, [deletePath, lstat, readFile, rootFs, setWallpaper]);
|
||
|
|
||
|
return {
|
||
|
aiApi,
|
||
|
clockSource,
|
||
|
foregroundId,
|
||
|
iconPositions,
|
||
|
prependToStack,
|
||
|
removeFromStack,
|
||
|
runHistory,
|
||
|
sessionLoaded,
|
||
|
setClockSource,
|
||
|
setForegroundId,
|
||
|
setHaltSession,
|
||
|
setIconPositions,
|
||
|
setRunHistory,
|
||
|
setSortOrder,
|
||
|
setThemeName,
|
||
|
setWallpaper,
|
||
|
setWindowStates,
|
||
|
sortOrders,
|
||
|
stackOrder,
|
||
|
themeName,
|
||
|
wallpaperFit,
|
||
|
wallpaperImage,
|
||
|
windowStates,
|
||
|
};
|
||
|
};
|
||
|
|
||
|
export default useSessionContextState;
|