Initial commit: 提交控制器版本2核心代码
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
/* ============================================================
|
||||
SYSTEM PAGE — Settings
|
||||
Design: Reference luxsin_x8_设置.png
|
||||
Sections:
|
||||
- 显示: 屏幕亮度, 自动锁屏, 旋钮亮度, 旋钮熄屏呼吸灯
|
||||
- 通用: 语言, 自动返回首页, 休眠
|
||||
- 声音: 开机提示音
|
||||
- 关于: 设备名, 固件版本, MAC
|
||||
All list rows with options → navigate to /select page
|
||||
============================================================ */
|
||||
import { useDevice } from "@/contexts/DeviceContext";
|
||||
import { ChevronLeft, ChevronRight } from "lucide-react";
|
||||
import { useLocation } from "wouter";
|
||||
import { useEffect } from "react";
|
||||
import BottomNav from "@/components/BottomNav";
|
||||
import { navigateToSelect } from "./SelectPage";
|
||||
|
||||
function IOSToggle({ checked, onChange }: { checked: boolean; onChange: (v: boolean) => void }) {
|
||||
return (
|
||||
<label className="ios-toggle" onClick={(e) => e.stopPropagation()}>
|
||||
<input type="checkbox" checked={checked} onChange={(e) => onChange(e.target.checked)} />
|
||||
<span className="ios-toggle-track"><span className="ios-toggle-thumb" /></span>
|
||||
</label>
|
||||
);
|
||||
}
|
||||
|
||||
function SectionHeader({ title }: { title: string }) {
|
||||
return (
|
||||
<div className="px-1 pt-5 pb-2">
|
||||
<span className="text-[14px] font-semibold" style={{ color: "#00FFF6" }}>{title}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ListRow({ label, description, value, onClick, toggle, checked, onToggle }: {
|
||||
label: string; description?: string; value?: string;
|
||||
onClick?: () => void; toggle?: boolean; checked?: boolean; onToggle?: (v: boolean) => void;
|
||||
}) {
|
||||
if (toggle) {
|
||||
return (
|
||||
<div className="ios-list-row">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="text-[16px] text-white">{label}</div>
|
||||
{description && <div className="text-[12px] text-white/35 mt-0.5">{description}</div>}
|
||||
</div>
|
||||
<IOSToggle checked={!!checked} onChange={onToggle ?? (() => {})} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<button className="ios-list-row w-full text-left active:bg-white/5 transition-colors" onClick={onClick}>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="text-[16px] text-white">{label}</div>
|
||||
{description && <div className="text-[12px] text-white/35 mt-0.5">{description}</div>}
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
{value && <span className="ios-row-value">{value}</span>}
|
||||
<ChevronRight size={16} className="ios-chevron ml-1" />
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
const SCREEN_LIGHT_OPTIONS = ["亮", "中等", "暗"];
|
||||
const KNOB_LIGHT_OPTIONS = ["关闭", "亮", "中等", "暗"];
|
||||
const SCREEN_OFF_OPTIONS = ["常亮", "30秒", "1分钟", "3分钟", "5分钟"];
|
||||
const SLEEP_OPTIONS = ["关闭", "1分钟", "5分钟", "10分钟"];
|
||||
const AUTO_HOME_OPTIONS = ["关闭", "20秒", "40秒", "60秒"];
|
||||
const LANG_OPTIONS = ["English", "繁體中文", "简体中文"];
|
||||
|
||||
export default function SystemPage() {
|
||||
const [, setLocation] = useLocation();
|
||||
const { deviceState, updateSetting, disconnect, refresh, isConnected, api } = useDevice();
|
||||
const ds = deviceState;
|
||||
|
||||
// 页面加载且已连接时刷新数据
|
||||
useEffect(() => {
|
||||
if (isConnected || api) {
|
||||
refresh();
|
||||
}
|
||||
}, [isConnected, api]);
|
||||
|
||||
const screenLightIdx = ds?.screenLight ?? 1;
|
||||
const buttonLightIdx = ds?.buttonLight ?? 1;
|
||||
const screenOffIdx = ds?.screenOff ?? 2;
|
||||
const sleepIdx = ds?.sleep ?? 0;
|
||||
const autoHomeIdx = ds?.autoHome ?? 1;
|
||||
const langIdx = ds?.language ?? 2;
|
||||
const knobBreathLightOn = (ds?.knob_breathlight ?? 1) === 0;
|
||||
|
||||
const goSelect = (title: string, options: string[], selected: number, key: string) => {
|
||||
navigateToSelect(title, options, selected, "/system", key);
|
||||
setLocation("/select");
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-black">
|
||||
<div className="page-header">
|
||||
<button onClick={() => setLocation("/")} className="mr-4 text-white/60 active:text-white transition-colors">
|
||||
<ChevronLeft size={24} />
|
||||
</button>
|
||||
<h1 className="flex-1 text-center text-[17px] font-semibold text-white">设置</h1>
|
||||
<div className="w-8" />
|
||||
</div>
|
||||
|
||||
<div className="px-4 pb-32">
|
||||
{/* ── 显示 ── */}
|
||||
<SectionHeader title="显示" />
|
||||
<div className="ios-list-group">
|
||||
<ListRow label="屏幕亮度" description="调节屏幕的整体亮度"
|
||||
value={SCREEN_LIGHT_OPTIONS[screenLightIdx]}
|
||||
onClick={() => goSelect("屏幕亮度", SCREEN_LIGHT_OPTIONS, screenLightIdx, "screenLight")} />
|
||||
<ListRow label="自动锁屏" description="设备无操作后自动关闭屏幕的时间"
|
||||
value={SCREEN_OFF_OPTIONS[screenOffIdx]}
|
||||
onClick={() => goSelect("自动锁屏", SCREEN_OFF_OPTIONS, screenOffIdx, "screenOff")} />
|
||||
<ListRow label="旋钮亮度" description="调节旋钮指示灯的亮度"
|
||||
value={KNOB_LIGHT_OPTIONS[buttonLightIdx]}
|
||||
onClick={() => goSelect("旋钮亮度", KNOB_LIGHT_OPTIONS, buttonLightIdx, "buttonLight")} />
|
||||
<ListRow label="旋钮熄屏呼吸灯" description="锁屏后旋钮是否显示呼吸灯效果"
|
||||
toggle checked={knobBreathLightOn}
|
||||
onToggle={(v) => updateSetting({ knob_breathlight: v ? 0 : 1 })} />
|
||||
</div>
|
||||
|
||||
{/* ── 通用 ── */}
|
||||
<SectionHeader title="通用" />
|
||||
<div className="ios-list-group">
|
||||
<ListRow label="语言" description="设置系统显示语言"
|
||||
value={LANG_OPTIONS[langIdx]}
|
||||
onClick={() => goSelect("选择语言", LANG_OPTIONS, langIdx, "language")} />
|
||||
<ListRow label="自动返回首页" description="闲置一段时间后自动回到主界面"
|
||||
value={AUTO_HOME_OPTIONS[autoHomeIdx]}
|
||||
onClick={() => goSelect("自动返回首页", AUTO_HOME_OPTIONS, autoHomeIdx, "autoHome")} />
|
||||
<ListRow label="休眠" description="设置设备进入低功耗模式的时间"
|
||||
value={SLEEP_OPTIONS[sleepIdx]}
|
||||
onClick={() => goSelect("休眠时间", SLEEP_OPTIONS, sleepIdx, "sleep")} />
|
||||
</div>
|
||||
|
||||
{/* ── 关于 ── */}
|
||||
<SectionHeader title="关于" />
|
||||
<div className="ios-list-group">
|
||||
<div className="ios-list-row">
|
||||
<span className="flex-1 text-[16px] text-white">设备名称</span>
|
||||
<span className="ios-row-value">{ds?.device ?? "Luxsin X9"}</span>
|
||||
</div>
|
||||
<div className="ios-list-row">
|
||||
<span className="flex-1 text-[16px] text-white">固件版本</span>
|
||||
<span className="ios-row-value">{ds?.version ?? "—"}</span>
|
||||
</div>
|
||||
<div className="ios-list-row">
|
||||
<span className="flex-1 text-[16px] text-white">MAC 地址</span>
|
||||
<span className="ios-row-value text-[12px]">{ds?.mac ?? "—"}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── 断开连接 ── */}
|
||||
<div className="mt-6 mb-4">
|
||||
<button
|
||||
className="w-full py-4 rounded-[14px] text-[16px] font-medium transition-all duration-150 active:scale-[0.98]"
|
||||
style={{ background: "rgba(239,68,68,0.1)", border: "1px solid rgba(239,68,68,0.2)", color: "#ef4444" }}
|
||||
onClick={() => { disconnect(); setLocation("/"); }}>
|
||||
断开连接
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BottomNav />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user