aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/packages/ui-new/src/components/bottom-bar.tsx
diff options
context:
space:
mode:
author苏向夜 <fu050409@163.com>2026-02-24 22:41:36 +0800
committer苏向夜 <fu050409@163.com>2026-02-24 22:41:36 +0800
commitb275a3668b140d9ce4663de646519d2dbd4297e7 (patch)
tree13799773d7d6ef5ac566bbfc4e28ed81798b965b /packages/ui-new/src/components/bottom-bar.tsx
parent888f57b6f2ef3b81ba61f4009799f046739ba4dd (diff)
downloadDropOut-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.tsx157
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>
);
}