From 5d403b86833c23ff7974daa829a9cbb2f837f4ec Mon Sep 17 00:00:00 2001 From: HsiangNianian Date: Sun, 18 Jan 2026 14:36:52 +0800 Subject: feat(frontend): add instance creation wizard - Create multi-step InstanceCreationModal with version and mod loader selection - Step 1: Instance name input - Step 2: Minecraft version selection with search and filtering - Step 3: Mod loader choice (vanilla/Fabric/Forge) with version selection - Automatically installs vanilla version + mod loader during creation - Wire new modal to InstancesView, replace old simple creation dialog - Remove unused confirmCreate function This wizard integrates version management into instance creation workflow, streamlining the user experience by combining instance setup and version installation into a single guided process. --- ui/src/components/InstancesView.svelte | 43 ++-------------------------------- 1 file changed, 2 insertions(+), 41 deletions(-) (limited to 'ui/src/components/InstancesView.svelte') diff --git a/ui/src/components/InstancesView.svelte b/ui/src/components/InstancesView.svelte index a4881e6..e42f813 100644 --- a/ui/src/components/InstancesView.svelte +++ b/ui/src/components/InstancesView.svelte @@ -3,6 +3,7 @@ import { instancesState } from "../stores/instances.svelte"; import { Plus, Trash2, Edit2, Copy, Check, X } from "lucide-svelte"; import type { Instance } from "../types"; + import InstanceCreationModal from "./InstanceCreationModal.svelte"; let showCreateModal = $state(false); let showEditModal = $state(false); @@ -17,7 +18,6 @@ }); function handleCreate() { - newInstanceName = ""; showCreateModal = true; } @@ -38,13 +38,6 @@ showDuplicateModal = true; } - async function confirmCreate() { - if (!newInstanceName.trim()) return; - await instancesState.createInstance(newInstanceName.trim()); - showCreateModal = false; - newInstanceName = ""; - } - async function confirmEdit() { if (!selectedInstance || !newInstanceName.trim()) return; await instancesState.updateInstance({ @@ -195,39 +188,7 @@ -{#if showCreateModal} -
-
-

Create Instance

- e.key === "Enter" && confirmCreate()} - autofocus - /> -
- - -
-
-
-{/if} + (showCreateModal = false)} /> {#if showEditModal && selectedInstance} -- cgit v1.2.3-70-g09d2 From d4ea239d4477e9427b52994ea25d54941dfdba3f Mon Sep 17 00:00:00 2001 From: HsiangNianian Date: Sun, 18 Jan 2026 14:53:44 +0800 Subject: feat(frontend): add instance editor modal with tabbed interface - Create InstanceEditorModal.svelte with 4 tabs: * Info: Instance name, notes, metadata (created date, last played) * Version: Mod loader switcher and version display * Files: File browser for mods/resourcepacks/shaderpacks/saves/screenshots * Settings: Memory override and JVM arguments customization - Wire InstanceEditorModal to InstancesView with Edit button - Add FileInfo type definition to types/index.ts - Fix accessibility issues: proper button roles, keyboard events - All TypeScript and Svelte compilation errors resolved - Enable comprehensive per-instance configuration management --- ui/src/components/InstanceEditorModal.svelte | 439 +++++++++++++++++++++++++++ ui/src/components/InstancesView.svelte | 67 ++-- ui/src/types/index.ts | 8 + 3 files changed, 464 insertions(+), 50 deletions(-) create mode 100644 ui/src/components/InstanceEditorModal.svelte (limited to 'ui/src/components/InstancesView.svelte') diff --git a/ui/src/components/InstanceEditorModal.svelte b/ui/src/components/InstanceEditorModal.svelte new file mode 100644 index 0000000..0856d93 --- /dev/null +++ b/ui/src/components/InstanceEditorModal.svelte @@ -0,0 +1,439 @@ + + +{#if isOpen && instance} + +{/if} diff --git a/ui/src/components/InstancesView.svelte b/ui/src/components/InstancesView.svelte index e42f813..5334f9e 100644 --- a/ui/src/components/InstancesView.svelte +++ b/ui/src/components/InstancesView.svelte @@ -4,12 +4,14 @@ import { Plus, Trash2, Edit2, Copy, Check, X } from "lucide-svelte"; import type { Instance } from "../types"; import InstanceCreationModal from "./InstanceCreationModal.svelte"; + import InstanceEditorModal from "./InstanceEditorModal.svelte"; let showCreateModal = $state(false); let showEditModal = $state(false); let showDeleteConfirm = $state(false); let showDuplicateModal = $state(false); let selectedInstance: Instance | null = $state(null); + let editingInstance: Instance | null = $state(null); let newInstanceName = $state(""); let duplicateName = $state(""); @@ -22,9 +24,7 @@ } function handleEdit(instance: Instance) { - selectedInstance = instance; - newInstanceName = instance.name; - showEditModal = true; + editingInstance = instance; } function handleDelete(instance: Instance) { @@ -38,17 +38,6 @@ showDuplicateModal = true; } - async function confirmEdit() { - if (!selectedInstance || !newInstanceName.trim()) return; - await instancesState.updateInstance({ - ...selectedInstance, - name: newInstanceName.trim(), - }); - showEditModal = false; - selectedInstance = null; - newInstanceName = ""; - } - async function confirmDelete() { if (!selectedInstance) return; await instancesState.deleteInstance(selectedInstance.id); @@ -104,10 +93,13 @@
{#each instancesState.instances as instance (instance.id)}
instancesState.setActiveInstance(instance.id)} + onkeydown={(e) => e.key === "Enter" && instancesState.setActiveInstance(instance.id)} > {#if instancesState.activeInstanceId === instance.id}
@@ -121,6 +113,7 @@
- -
-
-
-{/if} + + { + editingInstance = null; + }} +/> {#if showDeleteConfirm && selectedInstance} @@ -266,7 +234,6 @@ placeholder="New instance name" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white mb-4" onkeydown={(e) => e.key === "Enter" && confirmDuplicate()} - autofocus />