import { useEffect, useState, useCallback } from "react"; import { Button } from "@heroui/react"; import { Plus, Gamepad2, RefreshCw } from "lucide-react"; import { useInstanceStore } from "@/stores/instanceStore"; import { useConfigStore } from "@/stores/configStore"; import { Skeleton } from "@/components/ui/skeleton"; import { Surface } from "@/components/setting/Surface"; import { InstanceCard } from "./InstanceCard"; import { CreateDialog } from "./CreateDialog"; import type { InstanceRuntime } from "@/api/instance"; export function Gallery() { const { instances, loading, fetchInstances, create, launch } = useInstanceStore(); const gameConfig = useConfigStore((s) => s.config.game); const configInstances = useConfigStore((s) => s.config.instances); const setInstances = useConfigStore((s) => s.setInstances); const [createOpen, setCreateOpen] = useState(false); const [launching, setLaunching] = useState(null); const loadInstances = useCallback(async () => { await fetchInstances(gameConfig.gameDir); }, [fetchInstances, gameConfig.gameDir]); useEffect(() => { loadInstances(); }, [loadInstances]); const handleCreate = async (name: string, runtime: InstanceRuntime, displayName?: string) => { await create(name, gameConfig.gameDir, runtime, { description: displayName, }); // Sync to Koring.yml const loader = runtime.forge ? "forge" : runtime.fabricLoader ? "fabric" : runtime.quiltLoader ? "quilt" : runtime.neoForged ? "neoforged" : "vanilla"; const loaderVersion = runtime.forge || runtime.fabricLoader || runtime.quiltLoader || runtime.neoForged || ""; const updated = configInstances.filter((m) => m.name !== name); updated.push({ name, displayName: displayName || name, icon: "", gameVersion: runtime.minecraft, loader, loaderVersion, createdAt: Date.now(), lastPlayed: 0, playtime: 0, }); setInstances(updated); setCreateOpen(false); }; const handlePlay = async (name: string) => { setLaunching(name); try { await launch(name, gameConfig.gameDir); } catch { // Launch events handled via IPC listeners } // Update lastPlayed in config const idx = configInstances.findIndex((m) => m.name === name); if (idx >= 0) { const updated = [...configInstances]; updated[idx] = { ...updated[idx], lastPlayed: Date.now() }; setInstances(updated); } setLaunching(null); }; const handleSettings = (name: string) => { // TODO: Navigate to instance settings console.log("Settings for:", name); }; const getDisplayName = (name: string) => { return configInstances.find((m) => m.name === name)?.displayName; }; return (
{/* 头部 */}

实例管理

创建、管理和启动 Minecraft 实例

{/* 加载骨架 */} {loading && instances.length === 0 && (
{Array.from({ length: 6 }).map((_, i) => (
))}
)} {/* 空状态 */} {!loading && instances.length === 0 && (

还没有任何实例

点击"新建实例"创建你的第一个 Minecraft 游戏实例

)} {/* 实例网格 */} {instances.length > 0 && (
{instances.map((inst) => ( ))}
)} setCreateOpen(false)} onCreate={handleCreate} />
); }