(feat:background) Create stores for supported games & Create a React hook for fetching the background

This commit is contained in:
KingRainbow44
2023-11-29 23:49:54 -05:00
parent 0362f3124c
commit 7e916880a6

View File

@@ -1,28 +1,103 @@
import { useEffect, useState } from "preact/hooks";
import { create } from "zustand";
import { persist, createJSONStorage } from "zustand/middleware";
import { invoke } from "@tauri-apps/api";
import { exists } from "@tauri-apps/api/fs";
import { convertFileSrc } from "@tauri-apps/api/tauri";
export type GenshinStore = {
import { LauncherResponse, StoreWrite } from "@backend/types.ts";
import { AppDataPath, LauncherUrls } from "@app/constants.ts";
export type GameDataStore = {
backgroundHash: string;
fetchLatestBackground: () => Promise<void>;
};
export const useGenshinStore = create(
export const useGenshinStore = create<GameDataStore>()(
persist(
(): GenshinStore => ({
backgroundHash: ""
(set): GameDataStore => ({
backgroundHash: "",
fetchLatestBackground: () => fetchLatestBackground(
set as StoreWrite, LauncherUrls.GENSHIN_IMPACT)
}),
{
name: "genshin",
name: "genshin_data",
storage: createJSONStorage(() => localStorage)
}
)
);
export const useStarRailStore = create<GameDataStore>()(
persist(
(set) => ({
backgroundHash: "",
fetchLatestBackground: () => fetchLatestBackground(
set as StoreWrite, LauncherUrls.STAR_RAIL)
}),
{
name: "starrail_data",
storage: createJSONStorage(() => localStorage)
}
)
);
/**
* Fetches the latest background image.
*
* @param set The store write function.
* @param serviceUrl The URL used for fetching the background.
*/
export async function fetchLatestBackground(set: StoreWrite, serviceUrl: string): Promise<void> {
// Fetch the launcher data.
const launcherData = await fetch(serviceUrl, { cache: "force-cache" });
const responseData = await launcherData.json() as LauncherResponse;
// Check if the background exists on the system.
const backgroundUrl = responseData.data.adv.background;
const backgroundHash = backgroundUrl.split("/").pop()?.substring(0, 32);
if (backgroundHash == undefined) throw new Error("Unable to find the hash of the background.");
// Check if the file exists on the system.
const filePath = `${AppDataPath}/bg/${backgroundHash}.png`;
if (!await exists(filePath)) {
// Download the image.
await invoke("download_file", {
url: backgroundUrl, toFile: filePath
});
// Update the store.
set({ backgroundHash });
}
}
/**
* Attempts to get the file of the background.
*
* @param hash The hash of the background.
*/
export async function getBackgroundFile(hash: string): Promise<string> {
return convertFileSrc(`${AppDataPath}/bg/${hash}.png`);
}
/**
* React hook which returns the URL of the locally cached background image.
*/
export function useBackground() {
const { backgroundHash } = useGenshinStore();
const { backgroundHash, fetchLatestBackground } = useGenshinStore();
const [background, setBackground] = useState<string | null>(null);
useEffect(() => {
(async () => {
if (backgroundHash != "") {
setBackground(await getBackgroundFile(backgroundHash));
} else {
fetchLatestBackground();
}
})();
}, [backgroundHash, fetchLatestBackground]);
return background;
}