Stateful launch

This commit is contained in:
2026-04-03 17:09:21 +02:00
parent 808f776056
commit 4fe8f91371
2 changed files with 36 additions and 26 deletions
+21 -6
View File
@@ -1,4 +1,4 @@
use tauri::State; use tauri::{AppHandle, Emitter, State};
use crate::{GameVersion, LauncherSettings, Mod, SharedState}; use crate::{GameVersion, LauncherSettings, Mod, SharedState};
@@ -49,11 +49,26 @@ pub fn update_settings(state: State<SharedState>, new_settings: LauncherSettings
} }
#[tauri::command] #[tauri::command]
pub fn launch_game(version_id: String) -> Result<String, String> { pub fn launch_game(app: AppHandle, version_id: String) -> Result<(), String> {
println!("Launching Saturn Client with version {}", version_id); std::thread::spawn(move || {
app.emit("is-launching", "true").unwrap();
app.emit("launch-status", "Preparing...").unwrap();
// Replace this with real launcher logic std::thread::sleep(std::time::Duration::from_millis(500));
std::thread::sleep(std::time::Duration::from_secs(2)); app.emit("launch-status", "Verifying assets...").unwrap();
Ok("Game launched successfully!".into()) std::thread::sleep(std::time::Duration::from_millis(700));
app.emit("launch-status", "Applying Saturn optimizations...")
.unwrap();
std::thread::sleep(std::time::Duration::from_millis(700));
app.emit("launch-status", "Starting game...").unwrap();
std::thread::sleep(std::time::Duration::from_millis(1000));
app.emit("launch-status", "Game launched!").unwrap();
app.emit("is-launching", "false").unwrap();
});
Ok(())
} }
+14 -19
View File
@@ -1,7 +1,8 @@
import React, { useState } from "react"; import React, { useEffect, useState } from "react";
import { Play, Loader2 } from "lucide-react"; import { Play, Loader2 } from "lucide-react";
import { launchGame, type GameVersion } from "../services/LauncherService"; import { launchGame, type GameVersion } from "../services/LauncherService";
import Bg from "@/assets/bg.png"; import Bg from "@/assets/bg.png";
import { listen } from "@tauri-apps/api/event";
interface PlaySectionProps { interface PlaySectionProps {
version: GameVersion; version: GameVersion;
@@ -11,26 +12,20 @@ const PlaySection: React.FC<PlaySectionProps> = ({ version }) => {
const [isLaunching, setIsLaunching] = useState(false); const [isLaunching, setIsLaunching] = useState(false);
const [launchStatus, setLaunchStatus] = useState(""); const [launchStatus, setLaunchStatus] = useState("");
const handleLaunch = async () => { useEffect(() => {
setIsLaunching(true); const unlistenLaunchStatus = listen<string>("launch-status", (event) => {
setLaunchStatus("Preparing..."); setLaunchStatus(event.payload);
});
// Simulate launch steps const unlistenIsLaunching = listen<string>("is-launching", (event) => {
setTimeout(() => setLaunchStatus("Verifying assets..."), 500); setIsLaunching(event.payload === "true");
setTimeout(() => setLaunchStatus("Applying Saturn optimizations..."), 1200); });
const result = await launchGame(version.id); return () => {
unlistenLaunchStatus.then((f) => f());
if (result.success) { unlistenIsLaunching.then((f) => f());
setLaunchStatus("Game running");
// In a real app, we might minimize or close the launcher here
}
setTimeout(() => {
setIsLaunching(false);
setLaunchStatus("");
}, 3000);
}; };
}, []);
return ( return (
<div className="h-full relative"> <div className="h-full relative">
@@ -47,7 +42,7 @@ const PlaySection: React.FC<PlaySectionProps> = ({ version }) => {
<div className="absolute -inset-1 bg-linear-to-r from-blue-600 to-cyan-500 rounded-lg blur opacity-25 group-hover:opacity-50 transition duration-1000 group-hover:duration-200"></div> <div className="absolute -inset-1 bg-linear-to-r from-blue-600 to-cyan-500 rounded-lg blur opacity-25 group-hover:opacity-50 transition duration-1000 group-hover:duration-200"></div>
<button <button
onClick={handleLaunch} onClick={() => launchGame(version.id)}
disabled={isLaunching} disabled={isLaunching}
className="relative btn-primary px-16 py-4 text-xl flex items-center gap-3 min-w-60 justify-center" className="relative btn-primary px-16 py-4 text-xl flex items-center gap-3 min-w-60 justify-center"
> >