aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ui/src/stores/game.svelte.ts14
-rw-r--r--ui/src/stores/instances.svelte.ts109
-rw-r--r--ui/src/types/index.ts17
3 files changed, 137 insertions, 3 deletions
diff --git a/ui/src/stores/game.svelte.ts b/ui/src/stores/game.svelte.ts
index ca5dc2b..3efcf71 100644
--- a/ui/src/stores/game.svelte.ts
+++ b/ui/src/stores/game.svelte.ts
@@ -2,6 +2,7 @@ import { invoke } from "@tauri-apps/api/core";
import type { Version } from "../types";
import { uiState } from "./ui.svelte";
import { authState } from "./auth.svelte";
+import { instancesState } from "./instances.svelte";
export class GameState {
versions = $state<Version[]>([]);
@@ -34,10 +35,19 @@ export class GameState {
return;
}
+ if (!instancesState.activeInstanceId) {
+ alert("Please select an instance first!");
+ uiState.setView("instances");
+ return;
+ }
+
uiState.setStatus("Preparing to launch " + this.selectedVersion + "...");
- console.log("Invoking start_game for version:", this.selectedVersion);
+ console.log("Invoking start_game for version:", this.selectedVersion, "instance:", instancesState.activeInstanceId);
try {
- const msg = await invoke<string>("start_game", { versionId: this.selectedVersion });
+ const msg = await invoke<string>("start_game", {
+ instanceId: instancesState.activeInstanceId,
+ versionId: this.selectedVersion,
+ });
console.log("Response:", msg);
uiState.setStatus(msg);
} catch (e) {
diff --git a/ui/src/stores/instances.svelte.ts b/ui/src/stores/instances.svelte.ts
new file mode 100644
index 0000000..f4ac4e9
--- /dev/null
+++ b/ui/src/stores/instances.svelte.ts
@@ -0,0 +1,109 @@
+import { invoke } from "@tauri-apps/api/core";
+import type { Instance } from "../types";
+import { uiState } from "./ui.svelte";
+
+export class InstancesState {
+ instances = $state<Instance[]>([]);
+ activeInstanceId = $state<string | null>(null);
+ get activeInstance(): Instance | null {
+ if (!this.activeInstanceId) return null;
+ return this.instances.find((i) => i.id === this.activeInstanceId) || null;
+ }
+
+ async loadInstances() {
+ try {
+ this.instances = await invoke<Instance[]>("list_instances");
+ const active = await invoke<Instance | null>("get_active_instance");
+ if (active) {
+ this.activeInstanceId = active.id;
+ } else if (this.instances.length > 0) {
+ // If no active instance but instances exist, set the first one as active
+ await this.setActiveInstance(this.instances[0].id);
+ }
+ } catch (e) {
+ console.error("Failed to load instances:", e);
+ uiState.setStatus("Error loading instances: " + e);
+ }
+ }
+
+ async createInstance(name: string): Promise<Instance | null> {
+ try {
+ const instance = await invoke<Instance>("create_instance", { name });
+ await this.loadInstances();
+ uiState.setStatus(`Instance "${name}" created successfully`);
+ return instance;
+ } catch (e) {
+ console.error("Failed to create instance:", e);
+ uiState.setStatus("Error creating instance: " + e);
+ return null;
+ }
+ }
+
+ async deleteInstance(id: string) {
+ try {
+ await invoke("delete_instance", { instanceId: id });
+ await this.loadInstances();
+ // If deleted instance was active, set another as active
+ if (this.activeInstanceId === id) {
+ if (this.instances.length > 0) {
+ await this.setActiveInstance(this.instances[0].id);
+ } else {
+ this.activeInstanceId = null;
+ }
+ }
+ uiState.setStatus("Instance deleted successfully");
+ } catch (e) {
+ console.error("Failed to delete instance:", e);
+ uiState.setStatus("Error deleting instance: " + e);
+ }
+ }
+
+ async updateInstance(instance: Instance) {
+ try {
+ await invoke("update_instance", { instance });
+ await this.loadInstances();
+ uiState.setStatus("Instance updated successfully");
+ } catch (e) {
+ console.error("Failed to update instance:", e);
+ uiState.setStatus("Error updating instance: " + e);
+ }
+ }
+
+ async setActiveInstance(id: string) {
+ try {
+ await invoke("set_active_instance", { instanceId: id });
+ this.activeInstanceId = id;
+ uiState.setStatus("Active instance changed");
+ } catch (e) {
+ console.error("Failed to set active instance:", e);
+ uiState.setStatus("Error setting active instance: " + e);
+ }
+ }
+
+ async duplicateInstance(id: string, newName: string): Promise<Instance | null> {
+ try {
+ const instance = await invoke<Instance>("duplicate_instance", {
+ instanceId: id,
+ newName,
+ });
+ await this.loadInstances();
+ uiState.setStatus(`Instance duplicated as "${newName}"`);
+ return instance;
+ } catch (e) {
+ console.error("Failed to duplicate instance:", e);
+ uiState.setStatus("Error duplicating instance: " + e);
+ return null;
+ }
+ }
+
+ async getInstance(id: string): Promise<Instance | null> {
+ try {
+ return await invoke<Instance>("get_instance", { instanceId: id });
+ } catch (e) {
+ console.error("Failed to get instance:", e);
+ return null;
+ }
+ }
+}
+
+export const instancesState = new InstancesState();
diff --git a/ui/src/types/index.ts b/ui/src/types/index.ts
index 9a4da2b..a5b336e 100644
--- a/ui/src/types/index.ts
+++ b/ui/src/types/index.ts
@@ -1,4 +1,4 @@
-export type ViewType = "home" | "versions" | "settings" | "guide";
+export type ViewType = "home" | "versions" | "settings" | "guide" | "instances";
export interface Version {
id: string;
@@ -187,3 +187,18 @@ export interface InstalledForgeVersion {
// ==================== Mod Loader Type ====================
export type ModLoaderType = "vanilla" | "fabric" | "forge";
+
+// ==================== Instance Types ====================
+
+export interface Instance {
+ id: string;
+ name: string;
+ game_dir: string;
+ version_id?: string;
+ created_at: number;
+ last_played?: number;
+ icon_path?: string;
+ notes?: string;
+ mod_loader?: string;
+ mod_loader_version?: string;
+}