Refactor ConnectScreen to use logo image instead of SVG, enhance EQPage with batch editing functionality for PEQ settings, and implement power off confirmation dialog in Home component. Update localization files for new power off features.

This commit is contained in:
yangy
2026-04-21 14:31:31 +08:00
parent 0aa856ed84
commit cf970a6a7f
9 changed files with 300 additions and 32 deletions
+73 -5
View File
@@ -12,6 +12,16 @@
import { useDevice } from "@/contexts/DeviceContext";
import ConnectScreen from "@/components/ConnectScreen";
import BottomNav from "@/components/BottomNav";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { INPUT_LABELS, OUTPUT_LABELS } from "@/lib/luxsinApi";
import { cn } from "@/lib/utils";
import {
@@ -27,12 +37,14 @@ import {
Bluetooth,
} from "lucide-react";
import { useLocation } from "wouter";
import { useRef, useState, useEffect, useCallback } from "react";
import { useRef, useState, useEffect, useCallback, useMemo } from "react";
import { toast } from "sonner";
import localeZh from "@/locales/data-zh.json";
import localeZhHK from "@/locales/data-zh-HK.json";
import localeEn from "@/locales/data-en.json";
type HomeLocale = NonNullable<(typeof localeZh)["home"]>;
// ── Volume in dB (0-200 → -100dB to 0dB) ──
function volToDB(v: number) {
if (v === 0) return "-∞";
@@ -86,8 +98,17 @@ function ListRow({
}
export default function Home() {
const { isConnected, deviceState, setVolume, updateSetting } = useDevice();
const { isConnected, deviceState, setVolume, updateSetting, api, disconnect, isDemoMode } = useDevice();
const [, setLocation] = useLocation();
const powerActionRef = useRef(false);
const [powerConfirmOpen, setPowerConfirmOpen] = useState(false);
const homeText = useMemo((): HomeLocale => {
if (!deviceState) return {} as HomeLocale;
const loc =
deviceState.language === 0 ? localeEn : deviceState.language === 1 ? localeZhHK : localeZh;
return (loc.home ?? {}) as HomeLocale;
}, [deviceState]);
const [localVol, setLocalVol] = useState(deviceState?.volume ?? 100);
const isDragging = useRef(false);
@@ -112,11 +133,32 @@ export default function Home() {
setVolume(v);
}, [setVolume]);
const handlePowerOff = useCallback(async () => {
if (powerActionRef.current) return;
powerActionRef.current = true;
try {
if (isDemoMode) {
toast.info(homeText.powerOffToastDemo ?? "演示模式:已断开与设备的连接");
disconnect();
return;
}
if (api) {
try {
await api.powerOff();
} catch {
// 设备可能已掉线或未返回响应,仍断开本地会话
}
}
disconnect();
toast.success(homeText.powerOffToastSent ?? "已发送关机指令");
} finally {
powerActionRef.current = false;
}
}, [api, disconnect, isDemoMode, homeText]);
if (!isConnected) return <ConnectScreen />;
const ds = deviceState!;
const localeData = ds.language === 0 ? localeEn : ds.language === 1 ? localeZhHK : localeZh;
const homeText = localeData.home ?? {};
const inputLabel = INPUT_LABELS[ds.input] ?? "USB-C";
const outputLabel = OUTPUT_LABELS[ds.output] ?? "Headset";
const effectOn = ds.audio_enable === 1;
@@ -381,8 +423,9 @@ export default function Home() {
{/* Power */}
<div className="flex flex-col items-center gap-2">
<button
type="button"
className="icon-circle-btn"
onClick={() => toast.info("远程待机功能即将推出")}
onClick={() => setPowerConfirmOpen(true)}
>
<Power size={22} className="text-white/60" />
</button>
@@ -460,6 +503,31 @@ export default function Home() {
</div>
</div>
<AlertDialog open={powerConfirmOpen} onOpenChange={setPowerConfirmOpen}>
<AlertDialogContent className="border-white/10 bg-zinc-900 text-white sm:max-w-md">
<AlertDialogHeader>
<AlertDialogTitle className="text-white">
{homeText.powerOffConfirmTitle ?? "确认关闭电源?"}
</AlertDialogTitle>
<AlertDialogDescription className="text-white/60">
{homeText.powerOffConfirmDesc ??
"设备将关机并断开与本应用的连接,是否继续?"}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel className="border-white/20 bg-transparent text-white hover:bg-white/10">
{homeText.powerOffConfirmCancel ?? "取消"}
</AlertDialogCancel>
<AlertDialogAction
className="bg-red-600 text-white hover:bg-red-700 focus-visible:ring-red-600"
onClick={() => void handlePowerOff()}
>
{homeText.powerOffConfirmOk ?? "关闭电源"}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
{/* Bottom nav */}
<BottomNav />
</div>