mirror of
https://github.com/Grasscutters/Cultivation.git
synced 2025-12-13 07:34:36 +01:00
(feat:background) Create stores for supported games & Create a React hook for fetching the background
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user