diff options
| author | 2026-02-24 22:41:36 +0800 | |
|---|---|---|
| committer | 2026-02-24 22:41:36 +0800 | |
| commit | b275a3668b140d9ce4663de646519d2dbd4297e7 (patch) | |
| tree | 13799773d7d6ef5ac566bbfc4e28ed81798b965b /packages/ui-new/src/components/bottom-bar.tsx | |
| parent | 888f57b6f2ef3b81ba61f4009799f046739ba4dd (diff) | |
| download | DropOut-b275a3668b140d9ce4663de646519d2dbd4297e7.tar.gz DropOut-b275a3668b140d9ce4663de646519d2dbd4297e7.zip | |
refactor: rewrite login and settings pages
Diffstat (limited to 'packages/ui-new/src/components/bottom-bar.tsx')
| -rw-r--r-- | packages/ui-new/src/components/bottom-bar.tsx | 157 |
1 files changed, 39 insertions, 118 deletions
diff --git a/packages/ui-new/src/components/bottom-bar.tsx b/packages/ui-new/src/components/bottom-bar.tsx index a0c2c00..2653880 100644 --- a/packages/ui-new/src/components/bottom-bar.tsx +++ b/packages/ui-new/src/components/bottom-bar.tsx @@ -1,11 +1,13 @@ import { invoke } from "@tauri-apps/api/core"; import { listen, type UnlistenFn } from "@tauri-apps/api/event"; -import { Check, ChevronDown, Play, Terminal, User } from "lucide-react"; +import { Check, ChevronDown, Play, User } from "lucide-react"; import { useCallback, useEffect, useRef, useState } from "react"; -import { useAuthStore } from "@/stores/auth-store"; +import { cn } from "@/lib/utils"; +import { useAuthStore } from "@/models/auth"; import { useGameStore } from "@/stores/game-store"; import { useInstancesStore } from "@/stores/instances-store"; -import { useUIStore } from "@/stores/ui-store"; +import { LoginModal } from "./login-modal"; +import { Button } from "./ui/button"; interface InstalledVersion { id: string; @@ -16,15 +18,13 @@ export function BottomBar() { const authStore = useAuthStore(); const gameStore = useGameStore(); const instancesStore = useInstancesStore(); - const uiStore = useUIStore(); const [isVersionDropdownOpen, setIsVersionDropdownOpen] = useState(false); const [installedVersions, setInstalledVersions] = useState< InstalledVersion[] >([]); const [isLoadingVersions, setIsLoadingVersions] = useState(true); - - const dropdownRef = useRef<HTMLDivElement>(null); + const [showLoginModal, setShowLoginModal] = useState(false); const loadInstalledVersions = useCallback(async () => { if (!instancesStore.activeInstanceId) { @@ -61,17 +61,6 @@ export function BottomBar() { useEffect(() => { loadInstalledVersions(); - const handleClickOutside = (event: MouseEvent) => { - if ( - dropdownRef.current && - !dropdownRef.current.contains(event.target as Node) - ) { - setIsVersionDropdownOpen(false); - } - }; - - document.addEventListener("mousedown", handleClickOutside); - // Listen for backend events that should refresh installed versions. let unlistenDownload: UnlistenFn | null = null; let unlistenVersionDeleted: UnlistenFn | null = null; @@ -98,7 +87,6 @@ export function BottomBar() { })(); return () => { - document.removeEventListener("mousedown", handleClickOutside); try { if (unlistenDownload) unlistenDownload(); } catch { @@ -120,12 +108,12 @@ export function BottomBar() { }; const handleStartGame = async () => { - await gameStore.startGame( - authStore.currentAccount, - authStore.openLoginModal, - instancesStore.activeInstanceId, - uiStore.setView, - ); + // await gameStore.startGame( + // authStore.currentAccount, + // authStore.openLoginModal, + // instancesStore.activeInstanceId, + // uiStore.setView, + // ); }; const getVersionTypeColor = (type: string) => { @@ -155,8 +143,7 @@ export function BottomBar() { 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"> <div className="max-w-7xl mx-auto"> - <div className="flex items-center justify-between bg-white/5 dark:bg-black/20 backdrop-blur-xl rounded-xl border border-white/10 dark:border-white/5 p-3 shadow-lg"> - {/* Left: Instance Info */} + <div className="flex items-center justify-between bg-white/5 dark:bg-black/20 backdrop-blur-xl border border-white/10 dark:border-white/5 p-3 shadow-lg"> <div className="flex items-center gap-4"> <div className="flex flex-col"> <span className="text-xs font-mono text-zinc-400 uppercase tracking-wider"> @@ -166,104 +153,38 @@ export function BottomBar() { {instancesStore.activeInstance?.name || "No instance selected"} </span> </div> - - {/* Version Selector */} - <div className="relative" ref={dropdownRef}> - <button - type="button" - onClick={() => setIsVersionDropdownOpen(!isVersionDropdownOpen)} - className="flex items-center gap-2 px-4 py-2 bg-black/20 dark:bg-white/5 hover:bg-black/30 dark:hover:bg-white/10 rounded-lg border border-white/10 transition-colors" - > - <span className="text-sm text-white"> - {gameStore.selectedVersion || "Select Version"} - </span> - <ChevronDown - size={16} - className={`text-zinc-400 transition-transform ${ - isVersionDropdownOpen ? "rotate-180" : "" - }`} - /> - </button> - - {/* Dropdown */} - {isVersionDropdownOpen && ( - <div className="absolute bottom-full mb-2 w-64 bg-zinc-900 border border-zinc-700 rounded-lg shadow-2xl overflow-hidden z-50 animate-in fade-in slide-in-from-bottom-2"> - <div className="p-2"> - {versionOptions.map((option) => ( - <button - type="button" - key={option.id} - onClick={() => selectVersion(option.id)} - disabled={ - option.id === "loading" || option.id === "empty" - } - className={`flex items-center justify-between w-full px-3 py-2 text-left rounded-md transition-colors ${ - gameStore.selectedVersion === option.id - ? "bg-indigo-500/20 text-indigo-300" - : "hover:bg-white/5 text-zinc-300" - } ${ - option.id === "loading" || option.id === "empty" - ? "opacity-50 cursor-not-allowed" - : "" - }`} - > - <div className="flex items-center gap-2"> - <div - className={`w-2 h-2 rounded-full ${getVersionTypeColor( - option.type, - )}`} - ></div> - <span className="text-sm font-medium"> - {option.label} - </span> - </div> - {gameStore.selectedVersion === option.id && ( - <Check size={14} className="text-indigo-400" /> - )} - </button> - ))} - </div> - </div> - )} - </div> </div> - {/* Right: Action Buttons */} <div className="flex items-center gap-3"> - {/* Console Toggle */} - <button - type="button" - onClick={() => uiStore.toggleConsole()} - className="flex items-center gap-2 px-3 py-2 bg-zinc-800 hover:bg-zinc-700 text-zinc-300 hover:text-white rounded-lg transition-colors" - > - <Terminal size={16} /> - <span className="text-sm font-medium">Console</span> - </button> - - {/* User Login/Info */} - <button - type="button" - onClick={() => authStore.openLoginModal()} - className="flex items-center gap-2 px-4 py-2 bg-indigo-600 hover:bg-indigo-500 text-white rounded-lg transition-colors" - > - <User size={16} /> - <span className="text-sm font-medium"> - {authStore.currentAccount?.username || "Login"} - </span> - </button> - - {/* Start Game */} - <button - type="button" - onClick={handleStartGame} - className="flex items-center gap-2 px-5 py-2.5 bg-emerald-600 hover:bg-emerald-500 text-white rounded-lg transition-colors shadow-lg shadow-emerald-500/20" - > - <Play size={16} /> - <span className="text-sm font-medium">Start</span> - </button> + {authStore.account ? ( + <Button + className={cn( + "px-4 py-2 shadow-xl", + "bg-emerald-600! hover:bg-emerald-500!", + )} + size="lg" + onClick={handleStartGame} + > + <Play /> + Start + </Button> + ) : ( + <Button + className="px-4 py-2" + size="lg" + onClick={() => setShowLoginModal(true)} + > + <User /> Login + </Button> + )} </div> </div> </div> + + <LoginModal + open={showLoginModal} + onOpenChange={() => setShowLoginModal(false)} + /> </div> ); } |