From 42b7778ecc3062db234e9b0434cdbed56605c644 Mon Sep 17 00:00:00 2001 From: Ludea Date: Tue, 15 Oct 2024 08:16:55 +0200 Subject: [PATCH] fix: use Context to create store and fix download infos and progress bar --- src/App.tsx | 77 ++++++------ src/components/Footer.tsx | 240 ++++++++++++++++++------------------- src/components/Header.tsx | 4 +- src/components/Options.tsx | 19 +-- src/utils/Context.ts | 13 -- src/utils/Context.tsx | 26 ++++ 6 files changed, 191 insertions(+), 188 deletions(-) delete mode 100644 src/utils/Context.ts create mode 100644 src/utils/Context.tsx diff --git a/src/App.tsx b/src/App.tsx index 913c185a..3bccf9f8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,7 +7,7 @@ import { ThemeProvider, createTheme } from "@mui/material/styles"; import Header from "components/Header"; import { DesktopRoutes, MobileRoutes } from "routes"; import DesktopBackground from "assets/DesktopBackground.jpg"; -import SparusErrorContext from "utils/Context"; +import { SparusErrorContext, StoreProvider } from "utils/Context"; function App() { const [globalError, setGlobalError] = useState(""); @@ -26,7 +26,6 @@ function App() { useEffect(() => { if (import.meta.env.DEV) { - // window.addEventListener("contextmenu", event => event.preventDefault()); window.addEventListener("keydown", (event) => { if ( event.key === "F5" || @@ -41,43 +40,45 @@ function App() { return ( - - - -
+ + + + +
+ + {DesktopRouting} - {DesktopRouting} - - - {MobileRouting} - - + + {MobileRouting}{" "} + + + ); } diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 03ca8cc9..a7409502 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -1,19 +1,17 @@ import { useState, useEffect, useContext } from "react"; import LinearProgress from "@mui/material/LinearProgress"; import LoadingButton from "@mui/lab/LoadingButton"; -import Box from "@mui/material/Box"; -import Grid from "@mui/material/Grid"; +import Grid from "@mui/material/Grid2"; +import Paper from "@mui/material/Paper"; // Context -import SparusErrorContext from "utils/Context"; +import { SparusErrorContext, SparusStoreContext } from "utils/Context"; // Tauri api import { invoke } from "@tauri-apps/api/core"; -import { appConfigDir } from "@tauri-apps/api/path"; import { listen } from "@tauri-apps/api/event"; import { Command } from "@tauri-apps/plugin-shell"; import { platform } from "@tauri-apps/plugin-os"; -import { Store } from "tauri-plugin-store-api"; interface UpdateEvent { download: number; @@ -26,9 +24,6 @@ interface UpdateEvent { applied_output_bytes_per_sec: number; } -const userAgent = navigator.userAgent.toLowerCase(); -const isMobile = userAgent.includes("android") || userAgent.includes("iphone"); - const convertReadableData = (data: number): string => { if (data > 1024 && data < 1024 * 1024) { return `${String(Math.floor((data / 1024) * 100) / 100)} kiB`; @@ -48,49 +43,46 @@ function Footer() { const [progress, setProgress] = useState(0); const [buffer, setBuffer] = useState(0); const [gameState, setGameState] = useState("not_installed"); - const [gameLoading, setGameLoading] = useState(false); - const [workspacePath, setWorkspacePath] = useState(""); - const [gameName, setGameName] = useState(""); - const [repositoryUrl, setRepositoryUrl] = useState(""); + const [gameLoading, setGameLoading] = useState(false); + const [gameRunning, setGameRunning] = useState(false); + const [workspacePath, setWorkspacePath] = useState(); + const [gameName, setGameName] = useState(); + const [repositoryUrl, setRepositoryUrl] = useState(); const [downloadedBytesStart, setDownloadedBytesStart] = useState(""); const [downloadedBytesEnd, setDownloadedBytesEnd] = useState(""); const [downloadedBytesPerSec, setDownloadedBytesPerSec] = useState(""); const [appliedOutputBytesStart, setAppliedOutputBytesStart] = useState(""); const [appliedOutputBytesEnd, setAppliedOutputBytesEnd] = useState(""); const [appliedOutputBytesPerSec, setAppliedOutputBytesPerSec] = useState(""); - const [localConfig, setLocalConfig] = useState(""); const { setGlobalError } = useContext(SparusErrorContext); + const store = useContext(SparusStoreContext); useEffect(() => { - if (!isMobile) { - appConfigDir() - .then((dir) => setLocalConfig(dir)) - .catch((err: string) => setGlobalError(err)); - const store = new Store(`${localConfig}.settings.sparus`); - - store.load().catch((err: string) => setGlobalError(err)); - store - .get("game_url") - .then((value) => { - if (value) setRepositoryUrl(value); - }) - .catch((err: string) => setGlobalError(err)); - - store - .get("workspace_path") - .then((value) => { - if (value) setWorkspacePath(value); - }) - .catch((err: string) => setGlobalError(err)); - - store - .get("game_name") - .then((value) => { - if (value) setGameName(value); - }) - .catch((err: string) => setGlobalError(err)); - } + invoke("check_if_installed", { path: gameName }) + .then(() => setGameState("installed")) + .catch(() => setGameState("not_installed")); + + store + .get("game_url") + .then((value) => { + if (value) setRepositoryUrl(value); + }) + .catch((err: string) => setGlobalError(err)); + + store + .get("workspace_path") + .then((value) => { + if (value) setWorkspacePath(value); + }) + .catch((err: string) => setGlobalError(err)); + + store + .get("game_name") + .then((value) => { + if (value) setGameName(value); + }) + .catch((err: string) => setGlobalError(err)); listen("sparus://downloadinfos", (event) => { setProgress( @@ -122,120 +114,126 @@ function Footer() { convertReadableData(event.payload.applied_output_bytes_per_sec), ); }).catch((err: string) => setGlobalError(err)); - }); + }, [gameName, store, setGlobalError]); const spawn = () => { let extension; let shell: string; - let arg: string; + let arg: string[]; switch (platform()) { case "windows": extension = ".exe"; shell = "cmd"; - arg = "/C"; + arg = ["/C"]; break; case "macos": extension = ".app"; shell = "sh"; - arg = "-c"; + arg = ["-c"]; break; case "linux": extension = ".sh"; shell = "sh"; - arg = "-c"; + arg = ["-c"]; break; default: extension = ""; shell = ""; - arg = ""; + arg = [""]; break; } - Command.create(shell, [arg, workspacePath + gameName + extension]) - .execute() + const command = Command.create(shell, [ + ...arg, + "start ".concat(workspacePath, "/", gameName, extension), + ]); + + command + .spawn() + .then(() => { + setGameRunning(true); + }) .catch((err: string) => setGlobalError(err)); }; return ( - - - - - {gameLoading ? ( - - ) : null} - {gameState === "not_installed" ? ( - { - setGameLoading(true); - invoke("update_workspace", { - workspacePath, - repositoryUrl, + + {gameState === "not_installed" ? ( + + ) : null} + + + { + if (gameState === "not_installed") { + setGameLoading(!gameLoading); + setGameState("installing"); + invoke("update_workspace", { + workspacePath, + repositoryUrl, + }) + .then(() => { + setGameState("installed"); + setGameLoading(false); }) - .then(() => { - setGameState("installed"); - setGameLoading(false); - }) - .catch((err: string) => setGlobalError(err)); - }} - sx={{ - display: { - sm: "block", - xs: "none", - }, - position: "fixed", - right: "130px", - bottom: "70px", - }} - > - Install - - ) : null} - {gameState === "installed" ? ( - spawn()} - sx={{ - position: "fixed", - right: "130px", - bottom: "70px", - }} - > - Play - - ) : null} - - - {gameState === "installing" - ? `Download: ${downloadedBytesStart} / ${downloadedBytesEnd} @ ${downloadedBytesPerSec}/s Write : ${appliedOutputBytesStart} / ${appliedOutputBytesEnd} @ ${appliedOutputBytesPerSec}/s` - : null} - + .catch((err: string) => setGlobalError(err)); + } + if (gameState === "installed") { + spawn(); + } + }} + > + {gameState !== "installed" ? "Install" : "Play"} + + + + {gameState === "not_installed" ? ( + + Download: {downloadedBytesStart} / {downloadedBytesEnd} @ + {downloadedBytesPerSec}/s
Write : {appliedOutputBytesStart} / + {appliedOutputBytesEnd} @ {appliedOutputBytesPerSec}/s +
+ ) : null}
-
+ ); } diff --git a/src/components/Header.tsx b/src/components/Header.tsx index c4eef904..2fec2d88 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -10,13 +10,13 @@ import MinimizeIcon from "@mui/icons-material/Minimize"; import SettingsIcon from "@mui/icons-material/Settings"; // Components -import SparusContext from "utils/Context"; +import { SparusErrorContext } from "utils/Context"; // Tauri api import { getCurrentWindow } from "@tauri-apps/api/window"; function Header() { - const { setGlobalError } = useContext(SparusContext); + const { setGlobalError } = useContext(SparusErrorContext); const navigate = useNavigate(); const location = useLocation(); diff --git a/src/components/Options.tsx b/src/components/Options.tsx index 356c2af8..fd5b2b2b 100644 --- a/src/components/Options.tsx +++ b/src/components/Options.tsx @@ -9,13 +9,11 @@ import Checkbox from "@mui/material/Checkbox"; import IconButton from "@mui/material/IconButton"; // Components -import SparusContext from "utils/Context"; +import { SparusErrorContext, SparusStoreContext } from "utils/Context"; // Tauri api -import { appConfigDir } from "@tauri-apps/api/path"; import { remove } from "@tauri-apps/plugin-fs"; import { enable, disable } from "tauri-plugin-autostart-api"; -import { Store } from "tauri-plugin-store-api"; // Icons import DeleteIcon from "@mui/icons-material/Delete"; @@ -25,22 +23,15 @@ function Options() { const [autostart, setAutostart] = useState(); const [launcherURL, setLauncherURL] = useState(""); const [workspacePath, setWorkspacePath] = useState(""); - const [localConfig, setLocalConfig] = useState(""); - const { setGlobalError } = useContext(SparusContext); - - appConfigDir() - .then((dir) => setLocalConfig(dir)) - .catch((err: string) => setGlobalError(err)); - const store = new Store(`${localConfig}.settings.sparus`); + const { setGlobalError } = useContext(SparusErrorContext); + const store = useContext(SparusStoreContext); useEffect(() => { store.load().catch((err: string) => setGlobalError(err)); store - .get("game_url") - .then((value: string | null) => { - setGameURL(value); - }) + .get("game_url") + .then((value) => setGameURL(value)) .catch((err: string) => setGlobalError(err)); store .get("launcher_url") diff --git a/src/utils/Context.ts b/src/utils/Context.ts deleted file mode 100644 index 3088d8a0..00000000 --- a/src/utils/Context.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { createContext } from "react"; - -type SparusError = { - globalError: string; - setGlobalError: (err: string) => void; -}; - -const SparusErrorContext = createContext({ - globalError: "", - setGlobalError: () => {}, -}); - -export default SparusErrorContext; diff --git a/src/utils/Context.tsx b/src/utils/Context.tsx new file mode 100644 index 00000000..ddda6f2d --- /dev/null +++ b/src/utils/Context.tsx @@ -0,0 +1,26 @@ +import { ReactNode, createContext } from "react"; +import { Store } from "tauri-plugin-store-api"; + +type SparusError = { + globalError: string; + setGlobalError: (err: string) => void; +}; + +const SparusErrorContext = createContext({ + globalError: "", + setGlobalError: () => {}, +}); + +const store = new Store("Sparus.json"); + +const SparusStoreContext = createContext(store); + +function StoreProvider({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} + +export { SparusErrorContext, SparusStoreContext, StoreProvider };