From 66668d85d603c5841d755a6023aa1925559fc6d4 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Wed, 25 Feb 2026 01:32:51 +0800 Subject: chore(workspace): replace legacy codes --- packages/ui/src/pages/versions-view.tsx.bk | 662 +++++++++++++++++++++++++++++ 1 file changed, 662 insertions(+) create mode 100644 packages/ui/src/pages/versions-view.tsx.bk (limited to 'packages/ui/src/pages/versions-view.tsx.bk') diff --git a/packages/ui/src/pages/versions-view.tsx.bk b/packages/ui/src/pages/versions-view.tsx.bk new file mode 100644 index 0000000..d54596d --- /dev/null +++ b/packages/ui/src/pages/versions-view.tsx.bk @@ -0,0 +1,662 @@ +import { invoke } from "@tauri-apps/api/core"; +import { listen, type UnlistenFn } from "@tauri-apps/api/event"; +import { Coffee, Loader2, Search, Trash2 } from "lucide-react"; +import { useCallback, useEffect, useState } from "react"; +import { toast } from "sonner"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { useInstancesStore } from "../models/instances"; +import { useGameStore } from "../stores/game-store"; +import type { Version } from "../types/bindings/manifest"; + +interface InstalledModdedVersion { + id: string; + javaVersion?: number; +} + +type TypeFilter = "all" | "release" | "snapshot" | "installed"; + +export function VersionsView() { + const { versions, selectedVersion, loadVersions, setSelectedVersion } = + useGameStore(); + const { activeInstance } = useInstancesStore(); + + const [searchQuery, setSearchQuery] = useState(""); + const [typeFilter, setTypeFilter] = useState("all"); + const [installedModdedVersions, setInstalledModdedVersions] = useState< + InstalledModdedVersion[] + >([]); + const [, setIsLoadingModded] = useState(false); + const [showDeleteDialog, setShowDeleteDialog] = useState(false); + const [versionToDelete, setVersionToDelete] = useState(null); + const [isDeleting, setIsDeleting] = useState(false); + const [selectedVersionMetadata, setSelectedVersionMetadata] = useState<{ + id: string; + javaVersion?: number; + isInstalled: boolean; + } | null>(null); + const [isLoadingMetadata, setIsLoadingMetadata] = useState(false); + const [showModLoaderSelector, setShowModLoaderSelector] = useState(false); + + const normalizedQuery = searchQuery.trim().toLowerCase().replace(/。/g, "."); + + // Load installed modded versions with Java version info + const loadInstalledModdedVersions = useCallback(async () => { + if (!activeInstance) { + setInstalledModdedVersions([]); + setIsLoadingModded(false); + return; + } + + setIsLoadingModded(true); + try { + const allInstalled = await invoke>( + "list_installed_versions", + { instanceId: activeInstanceId }, + ); + + const moddedIds = allInstalled + .filter((v) => v.type === "fabric" || v.type === "forge") + .map((v) => v.id); + + const versionsWithJava = await Promise.all( + moddedIds.map(async (id) => { + try { + const javaVersion = await invoke( + "get_version_java_version", + { + instanceId: activeInstanceId, + versionId: id, + }, + ); + return { + id, + javaVersion: javaVersion ?? undefined, + }; + } catch (e) { + console.error(`Failed to get Java version for ${id}:`, e); + return { id, javaVersion: undefined }; + } + }), + ); + + setInstalledModdedVersions(versionsWithJava); + } catch (e) { + console.error("Failed to load installed modded versions:", e); + toast.error("Error loading modded versions"); + } finally { + setIsLoadingModded(false); + } + }, [activeInstanceId]); + + // Combined versions list (vanilla + modded) + const allVersions = (() => { + const moddedVersions: Version[] = installedModdedVersions.map((v) => { + const versionType = v.id.startsWith("fabric-loader-") + ? "fabric" + : v.id.includes("-forge-") + ? "forge" + : "fabric"; + return { + id: v.id, + type: versionType, + url: "", + time: "", + releaseTime: new Date().toISOString(), + javaVersion: BigInt(v.javaVersion ?? 0), + isInstalled: true, + }; + }); + return [...moddedVersions, ...versions]; + })(); + + // Filter versions based on search and type filter + const filteredVersions = allVersions.filter((version) => { + if (typeFilter === "release" && version.type !== "release") return false; + if (typeFilter === "snapshot" && version.type !== "snapshot") return false; + if (typeFilter === "installed" && !version.isInstalled) return false; + + if ( + normalizedQuery && + !version.id.toLowerCase().includes(normalizedQuery) + ) { + return false; + } + + return true; + }); + + // Get version badge styling + const getVersionBadge = (type: string) => { + switch (type) { + case "release": + return { + text: "Release", + variant: "default" as const, + className: "bg-emerald-500 hover:bg-emerald-600", + }; + case "snapshot": + return { + text: "Snapshot", + variant: "secondary" as const, + className: "bg-amber-500 hover:bg-amber-600", + }; + case "fabric": + return { + text: "Fabric", + variant: "outline" as const, + className: "border-indigo-500 text-indigo-700 dark:text-indigo-300", + }; + case "forge": + return { + text: "Forge", + variant: "outline" as const, + className: "border-orange-500 text-orange-700 dark:text-orange-300", + }; + case "modpack": + return { + text: "Modpack", + variant: "outline" as const, + className: "border-purple-500 text-purple-700 dark:text-purple-300", + }; + default: + return { + text: type, + variant: "outline" as const, + className: "border-gray-500 text-gray-700 dark:text-gray-300", + }; + } + }; + + // Load version metadata + const loadVersionMetadata = useCallback( + async (versionId: string) => { + if (!versionId || !activeInstanceId) { + setSelectedVersionMetadata(null); + return; + } + + setIsLoadingMetadata(true); + try { + const metadata = await invoke<{ + id: string; + javaVersion?: number; + isInstalled: boolean; + }>("get_version_metadata", { + instanceId: activeInstanceId, + versionId, + }); + setSelectedVersionMetadata(metadata); + } catch (e) { + console.error("Failed to load version metadata:", e); + setSelectedVersionMetadata(null); + } finally { + setIsLoadingMetadata(false); + } + }, + [activeInstanceId], + ); + + // Get base version for mod loader selector + const selectedBaseVersion = (() => { + if (!selectedVersion) return ""; + + if (selectedVersion.startsWith("fabric-loader-")) { + const parts = selectedVersion.split("-"); + return parts[parts.length - 1]; + } + if (selectedVersion.includes("-forge-")) { + return selectedVersion.split("-forge-")[0]; + } + + const version = versions.find((v) => v.id === selectedVersion); + return version ? selectedVersion : ""; + })(); + + // Handle version deletion + const handleDeleteVersion = async () => { + if (!versionToDelete || !activeInstanceId) return; + + setIsDeleting(true); + try { + await invoke("delete_version", { + instanceId: activeInstanceId, + versionId: versionToDelete, + }); + + if (selectedVersion === versionToDelete) { + setSelectedVersion(""); + } + + setShowDeleteDialog(false); + setVersionToDelete(null); + toast.success("Version deleted successfully"); + + await loadVersions(activeInstanceId); + await loadInstalledModdedVersions(); + } catch (e) { + console.error("Failed to delete version:", e); + toast.error(`Failed to delete version: ${e}`); + } finally { + setIsDeleting(false); + } + }; + + // Show delete confirmation dialog + const showDeleteConfirmation = (versionId: string, e: React.MouseEvent) => { + e.stopPropagation(); + setVersionToDelete(versionId); + setShowDeleteDialog(true); + }; + + // Setup event listeners for version updates + useEffect(() => { + let unlisteners: UnlistenFn[] = []; + + const setupEventListeners = async () => { + try { + const versionDeletedUnlisten = await listen( + "version-deleted", + async () => { + await loadVersions(activeInstanceId ?? undefined); + await loadInstalledModdedVersions(); + }, + ); + + const downloadCompleteUnlisten = await listen( + "download-complete", + async () => { + await loadVersions(activeInstanceId ?? undefined); + await loadInstalledModdedVersions(); + }, + ); + + const versionInstalledUnlisten = await listen( + "version-installed", + async () => { + await loadVersions(activeInstanceId ?? undefined); + await loadInstalledModdedVersions(); + }, + ); + + const fabricInstalledUnlisten = await listen( + "fabric-installed", + async () => { + await loadVersions(activeInstanceId ?? undefined); + await loadInstalledModdedVersions(); + }, + ); + + const forgeInstalledUnlisten = await listen( + "forge-installed", + async () => { + await loadVersions(activeInstanceId ?? undefined); + await loadInstalledModdedVersions(); + }, + ); + + unlisteners = [ + versionDeletedUnlisten, + downloadCompleteUnlisten, + versionInstalledUnlisten, + fabricInstalledUnlisten, + forgeInstalledUnlisten, + ]; + } catch (e) { + console.error("Failed to setup event listeners:", e); + } + }; + + setupEventListeners(); + loadInstalledModdedVersions(); + + return () => { + unlisteners.forEach((unlisten) => { + unlisten(); + }); + }; + }, [activeInstanceId, loadVersions, loadInstalledModdedVersions]); + + // Load metadata when selected version changes + useEffect(() => { + if (selectedVersion) { + loadVersionMetadata(selectedVersion); + } else { + setSelectedVersionMetadata(null); + } + }, [selectedVersion, loadVersionMetadata]); + + return ( +
+
+

+ Version Manager +

+
+ Select a version to play or modify +
+
+ +
+ {/* Left: Version List */} +
+ {/* Search and Filters */} +
+
+ + setSearchQuery(e.target.value)} + /> +
+
+ + {/* Type Filter Tabs */} + setTypeFilter(v as TypeFilter)} + className="w-full" + > + + All + Release + Snapshot + Installed + + + + {/* Version List */} + + {versions.length === 0 ? ( +
+ Loading versions... +
+ ) : filteredVersions.length === 0 ? ( +
+ 👻 + No matching versions found +
+ ) : ( +
+ {filteredVersions.map((version) => { + const badge = getVersionBadge(version.type); + const isSelected = selectedVersion === version.id; + + return ( + setSelectedVersion(version.id)} + > + {isSelected && ( +
+ )} + + +
+
+ + {badge.text} + +
+
+ {version.id} +
+
+ {version.releaseTime && + version.type !== "fabric" && + version.type !== "forge" && ( +
+ {new Date( + version.releaseTime, + ).toLocaleDateString()} +
+ )} + {version.javaVersion && ( +
+ + + Java {version.javaVersion} + +
+ )} +
+
+
+ +
+ {version.isInstalled && ( + + )} +
+
+
+ + ); + })} +
+ )} + +
+ + {/* Right: Version Details */} +
+ + + Version Details + + + {selectedVersion ? ( + <> +
+
+ Selected Version +
+
+ {selectedVersion} +
+
+ + {isLoadingMetadata ? ( +
+ + Loading metadata... +
+ ) : selectedVersionMetadata ? ( +
+
+
+ Installation Status +
+ + {selectedVersionMetadata.isInstalled + ? "Installed" + : "Not Installed"} + +
+ + {selectedVersionMetadata.javaVersion && ( +
+
+ Java Version +
+
+ + + Java {selectedVersionMetadata.javaVersion} + +
+
+ )} + + {!selectedVersionMetadata.isInstalled && ( + + )} +
+ ) : null} + + ) : ( +
+ Select a version to view details +
+ )} +
+
+ + {/* Mod Loader Installation */} + {showModLoaderSelector && selectedBaseVersion && ( + + + Install Mod Loader + + +
+ Install {selectedBaseVersion} with Fabric or Forge +
+
+ + +
+ +
+
+ )} +
+
+ + {/* Delete Confirmation Dialog */} + + + + Delete Version + + Are you sure you want to delete version "{versionToDelete}"? This + action cannot be undone. + + + + + + + + +
+ ); +} -- cgit v1.2.3-70-g09d2