优化体验,修复 bug

This commit is contained in:
eafonyang
2026-06-15 18:39:20 +08:00
parent b421fe1ca3
commit 7eb7647484
6 changed files with 89 additions and 35 deletions
+5 -3
View File
@@ -365,12 +365,15 @@
"shareCopied": "Code copied",
"shareGenerating": "Generating…",
"shareCreateFail": "Failed to generate share code",
"shareActiveExists": "You already have an active share code. Please try again later.",
"shareInvalidParams": "Invalid request. Please check and try again.",
"shareSystemError": "System error. Please try again later.",
"shareExpireAt": "Expires at",
"importTab": "Import EQ",
"importCodeHint": "Enter or paste the 5-character share code",
"importQuery": "Query",
"importQuerying": "Querying…",
"importCodeNotFound": "Share code not found",
"importCodeNotFound": "Share code not found or expired",
"importEqName": "EQ Name",
"importButton": "Import",
"importSaving": "Importing…",
@@ -381,8 +384,7 @@
"mySharesEmpty": "No shared EQ yet",
"mySharesCode": "Code",
"mySharesName": "EQ Name",
"mySharesLoadFail": "Failed to load share list",
"importCodeNotFound": "Share code not found or expired"
"mySharesLoadFail": "Failed to load share list"
}
},
"dac": {
+3
View File
@@ -301,6 +301,9 @@
"shareCopied": "已複製分享碼",
"shareGenerating": "產生中…",
"shareCreateFail": "產生分享碼失敗",
"shareActiveExists": "已有未過期的分享碼,請稍後再試",
"shareInvalidParams": "請求參數無效,請檢查後重試",
"shareSystemError": "系統錯誤,請稍後重試",
"shareExpireAt": "有效期至",
"importTab": "匯入 EQ",
"importCodeHint": "輸入或貼上 5 位分享碼",
+3
View File
@@ -301,6 +301,9 @@
"shareCopied": "已复制分享码",
"shareGenerating": "生成中…",
"shareCreateFail": "生成分享码失败",
"shareActiveExists": "已有未过期的分享码,请稍后再试",
"shareInvalidParams": "请求参数无效,请检查后重试",
"shareSystemError": "系统错误,请稍后重试",
"shareExpireAt": "有效期至",
"importTab": "导入 EQ",
"importCodeHint": "输入或粘贴 5 位分享码",
+1 -11
View File
@@ -25,7 +25,6 @@ import {
type PeqChangePayload,
type PeqState,
buildPeqPresetBody,
acceptShareCode,
} from "@/lib/luxsinApi";
import {
getFilterType,
@@ -719,16 +718,6 @@ export default function EQPage() {
skipPeqAutoSyncRef.current = true;
try {
const mac = deviceState?.mac ?? "";
if (!isDemoMode && mac) {
const acceptRes = await acceptShareCode(mac, shareCode.trim());
if (acceptRes.code !== 200) {
toast.error(eqUi.importFail ?? eqUi.importCodeNotFound);
skipPeqAutoSyncRef.current = false;
return;
}
}
await upgradePeqChange(payload);
if (api && !isDemoMode) {
const latest = await fetchEqSyncPeq(api, "importSharedEq");
@@ -1850,6 +1839,7 @@ export default function EQPage() {
eqUi={eqUi}
peqCardLabels={peqCardLabels}
mac={deviceState?.mac ?? ""}
isDemoMode={isDemoMode}
onImportEq={handleImportSharedEq}
/>
+37 -21
View File
@@ -2,8 +2,9 @@ import { useState } from "react";
import { X, Copy, Loader2 } from "lucide-react";
import { cn } from "@/lib/utils";
import { toast } from "sonner";
import { createShareCode, listShareCodes, queryShareCode } from "@/lib/luxsinApi";
import { acceptShareCode, createShareCode, listShareCodes, queryShareCode } from "@/lib/luxsinApi";
import type { PeqEqUi } from "../constants";
import { resolveShareApiMessage } from "../shareMessages";
type PeqItem = {
name: string;
@@ -39,6 +40,7 @@ export function ShareDialog({
eqUi,
peqCardLabels,
mac,
isDemoMode,
onImportEq,
}: {
open: boolean;
@@ -48,6 +50,7 @@ export function ShareDialog({
eqUi: PeqEqUi;
peqCardLabels: PeqCardLabels;
mac: string;
isDemoMode: boolean;
onImportEq: (data: ImportedEqData, shareCode: string) => void | Promise<void>;
}) {
const [shareDialogTab, setShareDialogTab] = useState<"share" | "import" | "myShares">("share");
@@ -64,6 +67,26 @@ export function ShareDialog({
const [mySharesList, setMySharesList] = useState<Array<{ share_code: string; expire_at: string; eq_data: Record<string, unknown> }>>([]);
const [mySharesLoading, setMySharesLoading] = useState(false);
const handleImportClick = async () => {
if (importSaving || !importedEqData || !queriedShareCode) return;
const nextName = importPresetName.trim();
if (!nextName) return;
setImportSaving(true);
try {
if (!isDemoMode && mac) {
const acceptRes = await acceptShareCode(mac, queriedShareCode);
if (acceptRes.code !== 200) {
toast.error(resolveShareApiMessage("accept", acceptRes, eqUi));
return;
}
}
await onImportEq({ ...importedEqData, name: nextName }, queriedShareCode);
} finally {
setImportSaving(false);
}
};
if (!open) return null;
/* ── clipboard helper ── */
@@ -87,7 +110,9 @@ export function ShareDialog({
return (
<div
className="fixed inset-0 z-[120] flex items-center justify-center bg-black/65 px-4"
onClick={onClose}
onClick={() => {
if (!importSaving) onClose();
}}
>
<div
className="w-full max-w-[420px] rounded-[14px] p-5"
@@ -142,12 +167,12 @@ export function ShareDialog({
try {
const res = await listShareCodes(mac);
if (res.code !== 200) {
toast.error(eqUi.mySharesLoadFail);
toast.error(resolveShareApiMessage("list", res, eqUi));
return;
}
setMySharesList(res.share_codes ?? []);
} catch {
toast.error(eqUi.mySharesLoadFail);
toast.error(resolveShareApiMessage("list", { code: 500 }, eqUi));
} finally {
setMySharesLoading(false);
}
@@ -160,7 +185,8 @@ export function ShareDialog({
</div>
<button
type="button"
className="rounded-full p-1.5 text-white/45 transition-colors hover:bg-white/10 hover:text-white/80"
className="rounded-full p-1.5 text-white/45 transition-colors hover:bg-white/10 hover:text-white/80 disabled:opacity-40 disabled:pointer-events-none"
disabled={importSaving}
onClick={onClose}
>
<X size={20} />
@@ -236,13 +262,13 @@ export function ShareDialog({
};
const res = await createShareCode(mac, eqData);
if (res.code !== 200) {
toast.error(res.msg || eqUi.shareCreateFail);
toast.error(resolveShareApiMessage("create", res, eqUi));
return;
}
setShareCode(res.share_code ?? "");
setShareCodeExpireAt(res.expire_at ?? null);
} catch {
toast.error(eqUi.shareCreateFail);
toast.error(resolveShareApiMessage("create", { code: 500 }, eqUi));
} finally {
setShareGenerating(false);
}
@@ -391,12 +417,12 @@ export function ShareDialog({
try {
const res = await queryShareCode(code);
if (res.code !== 200) {
toast.error(eqUi.importCodeNotFound);
toast.error(resolveShareApiMessage("query", res, eqUi));
return;
}
const eq = res.eq_data;
if (!eq) {
toast.error(eqUi.importCodeNotFound);
toast.error(resolveShareApiMessage("query", { code: 0 }, eqUi));
return;
}
const fetchedName = (eq.name as string) || "";
@@ -413,7 +439,7 @@ export function ShareDialog({
setImportPresetName(fetchedName);
setQueriedShareCode(code);
} catch {
toast.error(eqUi.importCodeNotFound);
toast.error(resolveShareApiMessage("query", { code: 500 }, eqUi));
} finally {
setImportQuerying(false);
}
@@ -451,17 +477,7 @@ export function ShareDialog({
? "bg-[#00FFF6]/40 cursor-not-allowed"
: "bg-[#00FFF6] hover:brightness-95",
)}
onClick={() => {
if (importSaving || !importedEqData || !queriedShareCode) return;
const nextName = importPresetName.trim();
if (!nextName) return;
setImportSaving(true);
void Promise.resolve(
onImportEq({ ...importedEqData, name: nextName }, queriedShareCode),
).finally(() => {
setImportSaving(false);
});
}}
onClick={() => void handleImportClick()}
>
{importSaving ? (
<span className="flex items-center justify-center gap-1.5">
+40
View File
@@ -0,0 +1,40 @@
import type { PeqEqUi } from "./constants";
export type ShareApiAction = "create" | "query" | "accept" | "list";
export function resolveShareApiMessage(
action: ShareApiAction,
res: { code: number; msg?: string },
eqUi: PeqEqUi,
): string {
if (res.code === 200) return "";
if (action === "list") {
return eqUi.mySharesLoadFail ?? "Failed to load share list";
}
if (res.code === 0) {
if (action === "create") {
return eqUi.shareActiveExists ?? eqUi.shareCreateFail ?? "Failed to generate share code";
}
return eqUi.importCodeNotFound ?? "Share code not found or expired";
}
if (res.code === 400) {
return eqUi.shareInvalidParams ?? eqUi.shareCreateFail ?? "Invalid request";
}
if (res.code === 500) {
return eqUi.shareSystemError ?? eqUi.shareCreateFail ?? "System error";
}
if (action === "create") {
return eqUi.shareCreateFail ?? "Failed to generate share code";
}
if (action === "accept") {
return eqUi.importFail ?? eqUi.importCodeNotFound ?? "Failed to import EQ";
}
return eqUi.importCodeNotFound ?? "Share code not found or expired";
}