Stateful launch
This commit is contained in:
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user