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 { create } from "zustand";
|
||||||
import { persist, createJSONStorage } from "zustand/middleware";
|
import { persist, createJSONStorage } from "zustand/middleware";
|
||||||
|
|
||||||
import { invoke } from "@tauri-apps/api";
|
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;
|
backgroundHash: string;
|
||||||
|
|
||||||
|
fetchLatestBackground: () => Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGenshinStore = create(
|
export const useGenshinStore = create<GameDataStore>()(
|
||||||
persist(
|
persist(
|
||||||
(): GenshinStore => ({
|
(set): GameDataStore => ({
|
||||||
backgroundHash: ""
|
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)
|
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.
|
* React hook which returns the URL of the locally cached background image.
|
||||||
*/
|
*/
|
||||||
export function useBackground() {
|
export function useBackground() {
|
||||||
const { backgroundHash } = useGenshinStore();
|
const { backgroundHash, fetchLatestBackground } = useGenshinStore();
|
||||||
const [background, setBackground] = useState<string | null>(null);
|
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