Hooks for game logic

This commit is contained in:
Santiago Fisela 2026-03-12 18:44:32 -03:00
parent 25f7921c7d
commit 9ed76290f4
3 changed files with 114 additions and 74 deletions

View file

@ -1,9 +1,10 @@
import { useState, useEffect } from "react";
import { listen } from "@tauri-apps/api/event";
import { useAudio } from "./hooks/useAudio";
import { useSettings } from "./hooks/useSettings";
import { useGameInstances } from "./hooks/useGameInstances";
import { useLauncher } from "./hooks/useLauncher";
import { TauriService } from "./services/tauri";
import { AppConfig, Runner, InstalledStatus, ReinstallModalData, McNotification } from "./types";
import { AppConfig, Runner, ReinstallModalData, McNotification } from "./types";
import { Sidebar } from "./components/layout/Sidebar";
import { HomeView } from "./components/views/HomeView";
import { VersionsView } from "./components/views/VersionsView";
@ -17,13 +18,6 @@ export default function App() {
const [username, setUsername] = useState("");
const [activeTab, setActiveTab] = useState("home");
const [isFirstRun, setIsFirstRun] = useState(true);
const [isRunning, setIsRunning] = useState(false);
const [installingInstance, setInstallingInstance] = useState<string | null>(null);
const [downloadProgress, setDownloadProgress] = useState<number>(0);
const [installedStatus, setInstalledStatus] = useState<InstalledStatus>({
vanilla_tu19: false,
vanilla_tu24: false,
});
const [selectedInstance, setSelectedInstance] = useState<string>("vanilla_tu19");
const [reinstallModal, setReinstallModal] = useState<ReinstallModalData | null>(null);
const [mcNotif, setMcNotif] = useState<McNotification | null>(null);
@ -33,61 +27,8 @@ export default function App() {
const { musicVol, setMusicVol, sfxVol, setSfxVol, isMuted, setIsMuted } = useSettings();
const { musicRef, playRandomMusic, playSfx, ensureAudio } = useAudio(musicVol, sfxVol, isMuted);
const updateAllStatus = async () => {
const v19 = await TauriService.checkGameInstalled("vanilla_tu19");
const v24 = await TauriService.checkGameInstalled("vanilla_tu24");
setInstalledStatus({ vanilla_tu19: v19, vanilla_tu24: v24 });
};
const fadeAndLaunch = async () => {
playSfx('levelup.ogg', 0.4);
setIsRunning(true);
if (musicRef.current && !isMuted) {
const startVol = musicRef.current.volume;
const steps = 20;
let currentStep = 0;
const fade = setInterval(() => {
currentStep++;
if (musicRef.current) {
musicRef.current.volume = Math.max(0, startVol * (1 - currentStep / steps));
}
if (currentStep >= steps) {
clearInterval(fade);
if (musicRef.current) musicRef.current.pause();
}
}, 50);
}
setTimeout(async () => {
try {
await TauriService.launchGame(selectedInstance);
} catch (e) {
alert(`Failed to launch game: ${e}`);
} finally {
setIsRunning(false);
if (musicRef.current) {
musicRef.current.volume = isMuted ? 0 : musicVol;
playRandomMusic();
}
}
}, 1500);
};
const executeInstall = async (id: string, url: string) => {
setInstallingInstance(id);
setDownloadProgress(0);
try {
await TauriService.downloadAndInstall(url, id);
setMcNotif({ t: "Success!", m: "Ready to play." });
playSfx('orb.ogg');
setTimeout(() => setMcNotif(null), 4000);
updateAllStatus();
} catch (e) {
console.error(e);
alert("Error during installation: " + e);
}
setInstallingInstance(null);
};
const { installedStatus, installingInstance, downloadProgress, executeInstall, updateAllStatus } = useGameInstances(playSfx, setMcNotif);
const { isRunning, fadeAndLaunch } = useLauncher(selectedInstance, musicRef, isMuted, musicVol, playRandomMusic, playSfx);
useEffect(() => {
TauriService.loadConfig().then((c) => {
@ -107,19 +48,11 @@ export default function App() {
setAvailableRunners(runners);
});
}
updateAllStatus();
const unlisten = listen<number>("download-progress", (e) =>
setDownloadProgress(Math.round(e.payload))
);
return () => {
unlisten.then((f) => f());
};
}, []);
if (isFirstRun) {
return (
<FirstRunView
<FirstRunView
username={username}
setUsername={setUsername}
isLinux={isLinux}
@ -139,7 +72,7 @@ export default function App() {
onContextMenu={(e) => e.preventDefault()}
>
<audio ref={musicRef} onEnded={playRandomMusic} />
<Sidebar
activeTab={activeTab}
setActiveTab={setActiveTab}

View file

@ -0,0 +1,56 @@
import { useState, useEffect } from 'react';
import { listen } from "@tauri-apps/api/event";
import { TauriService } from '../services/tauri';
import { InstalledStatus, McNotification } from '../types';
export const useGameInstances = (
playSfx: (name: string, multiplier?: number) => void,
setMcNotif: (notif: McNotification | null) => void
) => {
const [installingInstance, setInstallingInstance] = useState<string | null>(null);
const [downloadProgress, setDownloadProgress] = useState<number>(0);
const [installedStatus, setInstalledStatus] = useState<InstalledStatus>({
vanilla_tu19: false,
vanilla_tu24: false,
});
const updateAllStatus = async () => {
const v19 = await TauriService.checkGameInstalled("vanilla_tu19");
const v24 = await TauriService.checkGameInstalled("vanilla_tu24");
setInstalledStatus({ vanilla_tu19: v19, vanilla_tu24: v24 });
};
const executeInstall = async (id: string, url: string) => {
setInstallingInstance(id);
setDownloadProgress(0);
try {
await TauriService.downloadAndInstall(url, id);
setMcNotif({ t: "Success!", m: "Ready to play." });
playSfx('orb.ogg');
setTimeout(() => setMcNotif(null), 4000);
updateAllStatus();
} catch (e) {
console.error(e);
alert("Error during installation: " + e);
}
setInstallingInstance(null);
};
useEffect(() => {
updateAllStatus();
const unlisten = listen<number>("download-progress", (e) =>
setDownloadProgress(Math.round(e.payload))
);
return () => {
unlisten.then((f) => f());
};
}, []);
return {
installedStatus,
installingInstance,
downloadProgress,
executeInstall,
updateAllStatus,
};
};

51
src/hooks/useLauncher.ts Normal file
View file

@ -0,0 +1,51 @@
import { useState } from 'react';
import { TauriService } from '../services/tauri';
export const useLauncher = (
selectedInstance: string,
musicRef: React.RefObject<HTMLAudioElement | null>,
isMuted: boolean,
musicVol: number,
playRandomMusic: () => void,
playSfx: (name: string, multiplier?: number) => void
) => {
const [isRunning, setIsRunning] = useState(false);
const fadeAndLaunch = async () => {
playSfx('levelup.ogg', 0.4);
setIsRunning(true);
if (musicRef.current && !isMuted) {
const startVol = musicRef.current.volume;
const steps = 20;
let currentStep = 0;
const fade = setInterval(() => {
currentStep++;
if (musicRef.current) {
musicRef.current.volume = Math.max(0, startVol * (1 - currentStep / steps));
}
if (currentStep >= steps) {
clearInterval(fade);
if (musicRef.current) musicRef.current.pause();
}
}, 50);
}
setTimeout(async () => {
try {
await TauriService.launchGame(selectedInstance);
} catch (e) {
alert(`Failed to launch game: ${e}`);
} finally {
setIsRunning(false);
if (musicRef.current) {
musicRef.current.volume = isMuted ? 0 : musicVol;
playRandomMusic();
}
}
}, 1500);
};
return {
isRunning,
fadeAndLaunch,
};
};