aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/packages/ui-new/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'packages/ui-new/src/components')
-rw-r--r--packages/ui-new/src/components/bottom-bar.tsx89
-rw-r--r--packages/ui-new/src/components/instance-creation-modal.tsx18
-rw-r--r--packages/ui-new/src/components/instance-editor-modal.tsx18
3 files changed, 76 insertions, 49 deletions
diff --git a/packages/ui-new/src/components/bottom-bar.tsx b/packages/ui-new/src/components/bottom-bar.tsx
index 2653880..32eb852 100644
--- a/packages/ui-new/src/components/bottom-bar.tsx
+++ b/packages/ui-new/src/components/bottom-bar.tsx
@@ -1,13 +1,22 @@
-import { invoke } from "@tauri-apps/api/core";
import { listen, type UnlistenFn } from "@tauri-apps/api/event";
-import { Check, ChevronDown, Play, User } from "lucide-react";
-import { useCallback, useEffect, useRef, useState } from "react";
+import { Play, User } from "lucide-react";
+import { useCallback, useEffect, useMemo, useState } from "react";
+import { toast } from "sonner";
+import { listInstalledVersions, startGame } from "@/client";
import { cn } from "@/lib/utils";
import { useAuthStore } from "@/models/auth";
+import { useInstancesStore } from "@/models/instances";
import { useGameStore } from "@/stores/game-store";
-import { useInstancesStore } from "@/stores/instances-store";
import { LoginModal } from "./login-modal";
import { Button } from "./ui/button";
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "./ui/select";
interface InstalledVersion {
id: string;
@@ -19,7 +28,7 @@ export function BottomBar() {
const gameStore = useGameStore();
const instancesStore = useInstancesStore();
- const [isVersionDropdownOpen, setIsVersionDropdownOpen] = useState(false);
+ const [selectedVersion, setSelectedVersion] = useState<string | null>(null);
const [installedVersions, setInstalledVersions] = useState<
InstalledVersion[]
>([]);
@@ -27,7 +36,7 @@ export function BottomBar() {
const [showLoginModal, setShowLoginModal] = useState(false);
const loadInstalledVersions = useCallback(async () => {
- if (!instancesStore.activeInstanceId) {
+ if (!instancesStore.activeInstance) {
setInstalledVersions([]);
setIsLoadingVersions(false);
return;
@@ -35,9 +44,8 @@ export function BottomBar() {
setIsLoadingVersions(true);
try {
- const versions = await invoke<InstalledVersion[]>(
- "list_installed_versions",
- { instanceId: instancesStore.activeInstanceId },
+ const versions = await listInstalledVersions(
+ instancesStore.activeInstance.id,
);
const installed = versions || [];
@@ -53,7 +61,7 @@ export function BottomBar() {
setIsLoadingVersions(false);
}
}, [
- instancesStore.activeInstanceId,
+ instancesStore.activeInstance,
gameStore.selectedVersion,
gameStore.setSelectedVersion,
]);
@@ -100,20 +108,23 @@ export function BottomBar() {
};
}, [loadInstalledVersions]);
- const selectVersion = (id: string) => {
- if (id !== "loading" && id !== "empty") {
- gameStore.setSelectedVersion(id);
- setIsVersionDropdownOpen(false);
+ const handleStartGame = async () => {
+ if (!selectedVersion) {
+ toast.info("Please select a version!");
+ return;
}
- };
- const handleStartGame = async () => {
+ if (!instancesStore.activeInstance) {
+ toast.info("Please select an instance first!");
+ return;
+ }
// await gameStore.startGame(
// authStore.currentAccount,
// authStore.openLoginModal,
// instancesStore.activeInstanceId,
// uiStore.setView,
// );
+ await startGame(instancesStore.activeInstance?.id, selectedVersion);
};
const getVersionTypeColor = (type: string) => {
@@ -131,14 +142,15 @@ export function BottomBar() {
}
};
- const versionOptions = isLoadingVersions
- ? [{ id: "loading", type: "loading", label: "Loading..." }]
- : installedVersions.length === 0
- ? [{ id: "empty", type: "empty", label: "No versions installed" }]
- : installedVersions.map((v) => ({
- ...v,
- label: `${v.id}${v.type !== "release" ? ` (${v.type})` : ""}`,
- }));
+ const versionOptions = useMemo(
+ () =>
+ installedVersions.map((v) => ({
+ label: `${v.id}${v.type !== "release" ? ` (${v.type})` : ""}`,
+ value: v.id,
+ type: v.type,
+ })),
+ [installedVersions],
+ );
return (
<div className="absolute bottom-0 left-0 right-0 bg-linear-to-t from-black/30 via-transparent to-transparent p-4 z-10">
@@ -153,6 +165,35 @@ export function BottomBar() {
{instancesStore.activeInstance?.name || "No instance selected"}
</span>
</div>
+
+ <Select
+ items={versionOptions}
+ onValueChange={setSelectedVersion}
+ disabled={isLoadingVersions}
+ >
+ <SelectTrigger className="max-w-48">
+ <SelectValue
+ placeholder={
+ isLoadingVersions
+ ? "Loading versions..."
+ : "Please select a version"
+ }
+ />
+ </SelectTrigger>
+ <SelectContent>
+ <SelectGroup>
+ {versionOptions.map((item) => (
+ <SelectItem
+ key={item.value}
+ value={item.value}
+ className={getVersionTypeColor(item.type)}
+ >
+ {item.label}
+ </SelectItem>
+ ))}
+ </SelectGroup>
+ </SelectContent>
+ </Select>
</div>
<div className="flex items-center gap-3">
diff --git a/packages/ui-new/src/components/instance-creation-modal.tsx b/packages/ui-new/src/components/instance-creation-modal.tsx
index bdc1a6f..8a2b1b4 100644
--- a/packages/ui-new/src/components/instance-creation-modal.tsx
+++ b/packages/ui-new/src/components/instance-creation-modal.tsx
@@ -13,8 +13,8 @@ import {
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { ScrollArea } from "@/components/ui/scroll-area";
+import { useInstancesStore } from "@/models/instances";
import { useGameStore } from "@/stores/game-store";
-import { useInstancesStore } from "@/stores/instances-store";
import type { Version } from "@/types/bindings/manifest";
import type { FabricLoaderEntry } from "../types/bindings/fabric";
import type { ForgeVersion as ForgeVersionEntry } from "../types/bindings/forge";
@@ -25,20 +25,6 @@ interface Props {
onOpenChange: (open: boolean) => void;
}
-/**
- * InstanceCreationModal
- * 3-step wizard:
- * 1) Name
- * 2) Select base Minecraft version
- * 3) Optional: choose mod loader (vanilla/fabric/forge) and loader version
- *
- * Behavior:
- * - On Create: invoke("create_instance", { name })
- * - If a base version selected: invoke("install_version", { instanceId, versionId })
- * - If Fabric selected: invoke("install_fabric", { instanceId, gameVersion, loaderVersion })
- * - If Forge selected: invoke("install_forge", { instanceId, gameVersion, forgeVersion })
- * - Reload instances via instancesStore.loadInstances()
- */
export function InstanceCreationModal({ open, onOpenChange }: Props) {
const gameStore = useGameStore();
const instancesStore = useInstancesStore();
@@ -242,7 +228,7 @@ export function InstanceCreationModal({ open, onOpenChange }: Props) {
}
// Refresh instances list
- await instancesStore.loadInstances();
+ await instancesStore.refresh();
toast.success("Instance created successfully");
onOpenChange(false);
diff --git a/packages/ui-new/src/components/instance-editor-modal.tsx b/packages/ui-new/src/components/instance-editor-modal.tsx
index 74e0873..f880c20 100644
--- a/packages/ui-new/src/components/instance-editor-modal.tsx
+++ b/packages/ui-new/src/components/instance-editor-modal.tsx
@@ -16,8 +16,8 @@ import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { toNumber } from "@/lib/tsrs-utils";
-import { useInstancesStore } from "@/stores/instances-store";
-import { useSettingsStore } from "@/stores/settings-store";
+import { useInstancesStore } from "@/models/instances";
+import { useSettingsStore } from "@/models/settings";
import type { FileInfo } from "../types/bindings/core";
import type { Instance } from "../types/bindings/instance";
@@ -29,7 +29,7 @@ type Props = {
export function InstanceEditorModal({ open, instance, onOpenChange }: Props) {
const instancesStore = useInstancesStore();
- const { settings } = useSettingsStore();
+ const { config } = useSettingsStore();
const [activeTab, setActiveTab] = useState<
"info" | "version" | "files" | "settings"
@@ -67,19 +67,19 @@ export function InstanceEditorModal({ open, instance, onOpenChange }: Props) {
setEditNotes(instance.notes ?? "");
setEditMemoryMin(
(instance.memoryOverride && toNumber(instance.memoryOverride.min)) ??
- settings.minMemory ??
+ config?.minMemory ??
512,
);
setEditMemoryMax(
(instance.memoryOverride && toNumber(instance.memoryOverride.max)) ??
- settings.maxMemory ??
+ config?.maxMemory ??
2048,
);
setEditJavaArgs(instance.jvmArgsOverride ?? "");
setFileList([]);
setSelectedFileFolder("mods");
}
- }, [open, instance, settings.minMemory, settings.maxMemory]);
+ }, [open, instance, config?.minMemory, config?.maxMemory]);
// load files when switching to files tab
const loadFileList = useCallback(
@@ -178,7 +178,7 @@ export function InstanceEditorModal({ open, instance, onOpenChange }: Props) {
jvmArgsOverride: editJavaArgs.trim() ? editJavaArgs.trim() : null,
};
- await instancesStore.updateInstance(updatedInstance as Instance);
+ await instancesStore.update(updatedInstance as Instance);
toast.success("Instance saved");
onOpenChange(false);
} catch (err) {
@@ -471,7 +471,7 @@ export function InstanceEditorModal({ open, instance, onOpenChange }: Props) {
disabled={saving}
/>
<p className="text-xs text-zinc-400 mt-1">
- Default: {settings.minMemory} MB
+ Default: {config?.minMemory} MB
</p>
</div>
@@ -490,7 +490,7 @@ export function InstanceEditorModal({ open, instance, onOpenChange }: Props) {
disabled={saving}
/>
<p className="text-xs text-zinc-400 mt-1">
- Default: {settings.maxMemory} MB
+ Default: {config?.maxMemory} MB
</p>
</div>