import { listen, type UnlistenFn } from "@tauri-apps/api/event"; 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 { LoginModal } from "./login-modal"; import { Button } from "./ui/button"; import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue, } from "./ui/select"; interface InstalledVersion { id: string; type: string; } export function BottomBar() { const authStore = useAuthStore(); const gameStore = useGameStore(); const instancesStore = useInstancesStore(); const [selectedVersion, setSelectedVersion] = useState(null); const [installedVersions, setInstalledVersions] = useState< InstalledVersion[] >([]); const [isLoadingVersions, setIsLoadingVersions] = useState(true); const [showLoginModal, setShowLoginModal] = useState(false); const loadInstalledVersions = useCallback(async () => { if (!instancesStore.activeInstance) { setInstalledVersions([]); setIsLoadingVersions(false); return; } setIsLoadingVersions(true); try { const versions = await listInstalledVersions( instancesStore.activeInstance.id, ); const installed = versions || []; setInstalledVersions(installed); // If no version is selected but we have installed versions, select the first one if (!gameStore.selectedVersion && installed.length > 0) { gameStore.setSelectedVersion(installed[0].id); } } catch (error) { console.error("Failed to load installed versions:", error); } finally { setIsLoadingVersions(false); } }, [ instancesStore.activeInstance, gameStore.selectedVersion, gameStore.setSelectedVersion, ]); useEffect(() => { loadInstalledVersions(); // Listen for backend events that should refresh installed versions. let unlistenDownload: UnlistenFn | null = null; let unlistenVersionDeleted: UnlistenFn | null = null; (async () => { try { unlistenDownload = await listen("download-complete", () => { loadInstalledVersions(); }); } catch (err) { // best-effort: do not break UI if listening fails // eslint-disable-next-line no-console console.warn("Failed to attach download-complete listener:", err); } try { unlistenVersionDeleted = await listen("version-deleted", () => { loadInstalledVersions(); }); } catch (err) { // eslint-disable-next-line no-console console.warn("Failed to attach version-deleted listener:", err); } })(); return () => { try { if (unlistenDownload) unlistenDownload(); } catch { // ignore } try { if (unlistenVersionDeleted) unlistenVersionDeleted(); } catch { // ignore } }; }, [loadInstalledVersions]); const handleStartGame = async () => { if (!selectedVersion) { toast.info("Please select a version!"); return; } 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) => { switch (type) { case "release": return "bg-emerald-500"; case "snapshot": return "bg-amber-500"; case "old_beta": return "bg-rose-500"; case "old_alpha": return "bg-violet-500"; default: return "bg-gray-500"; } }; const versionOptions = useMemo( () => installedVersions.map((v) => ({ label: `${v.id}${v.type !== "release" ? ` (${v.type})` : ""}`, value: v.id, type: v.type, })), [installedVersions], ); return (
Active Instance {instancesStore.activeInstance?.name || "No instance selected"}
{authStore.account ? ( ) : ( )}
setShowLoginModal(false)} />
); }