Refactor build and start scripts in package.json; add plugin to exclude debug files from production build in vite.config.ts; remove ConnectScreen component and replace with ConnectionPlaceholder in multiple pages; update DeviceContext to auto-connect using device IP from URL; enhance locale files with new device IP labels.
This commit is contained in:
@@ -1,102 +0,0 @@
|
||||
/* ============================================================
|
||||
CONNECT SCREEN — Luxsin X9 Controller
|
||||
Design: Pure black iOS App style, glass card, #00FFF6 accent
|
||||
============================================================ */
|
||||
import { useDevice } from "@/contexts/DeviceContext";
|
||||
import { Loader2, Wifi } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function ConnectScreen() {
|
||||
const { ip, setIp, connect, isConnecting, error, setDemoMode, isDemoMode } = useDevice();
|
||||
const [inputIp, setInputIp] = useState(ip);
|
||||
|
||||
const handleConnect = async () => {
|
||||
const targetIp = inputIp.trim();
|
||||
if (!targetIp) return;
|
||||
setIp(targetIp);
|
||||
setDemoMode(false);
|
||||
await connect(false, targetIp);
|
||||
};
|
||||
|
||||
const handleDemo = async () => {
|
||||
setDemoMode(true);
|
||||
await connect(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-black flex flex-col items-center justify-center px-6">
|
||||
{/* Logo / Brand */}
|
||||
<div className="mb-10 flex flex-col items-center">
|
||||
<div
|
||||
className="mb-4 flex size-[5.5rem] shrink-0 items-center justify-center rounded-[17px] border border-white/15 bg-white/[0.02]"
|
||||
>
|
||||
<img
|
||||
src={`${import.meta.env.BASE_URL}logo.png`}
|
||||
alt="Luxsin"
|
||||
className="h-auto max-h-[3.75rem] w-auto max-w-[3.75rem] object-contain"
|
||||
/>
|
||||
</div>
|
||||
<h1 className="text-[16px] font-semibold tracking-tight text-white/70">
|
||||
Luxsin X8 Controller
|
||||
</h1>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Connection card */}
|
||||
<div className="w-full max-w-sm rounded-[20px] p-6 space-y-4"
|
||||
style={{
|
||||
background: "rgba(28,28,30,0.95)",
|
||||
border: "1px solid rgba(255,255,255,0.07)",
|
||||
backdropFilter: "blur(20px)",
|
||||
}}>
|
||||
<div>
|
||||
<label className="text-[13px] text-white/40 mb-2 block tracking-wide uppercase" style={{ letterSpacing: "0.06em" }}>
|
||||
设备 IP 地址
|
||||
</label>
|
||||
<div className="relative">
|
||||
<Wifi size={14} className="absolute left-3.5 top-1/2 -translate-y-1/2 text-white/25" />
|
||||
<input
|
||||
type="text"
|
||||
value={inputIp}
|
||||
onChange={(e) => setInputIp(e.target.value)}
|
||||
placeholder="192.168.2.30"
|
||||
className="w-full pl-9 pr-4 py-3.5 rounded-[12px] text-[15px] text-white outline-none transition-all"
|
||||
style={{
|
||||
background: "rgba(44,44,46,0.8)",
|
||||
border: "1px solid rgba(255,255,255,0.08)",
|
||||
fontFamily: "inherit",
|
||||
}}
|
||||
onFocus={(e) => { e.target.style.borderColor = "rgba(0,255,246,0.4)"; e.target.style.boxShadow = "0 0 0 3px rgba(0,255,246,0.06)"; }}
|
||||
onBlur={(e) => { e.target.style.borderColor = "rgba(255,255,255,0.08)"; e.target.style.boxShadow = "none"; }}
|
||||
onKeyDown={(e) => e.key === "Enter" && handleConnect()}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-[12px] text-white/25 mt-1.5">请确保与设备处于同一局域网</p>
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
<div className="px-3.5 py-2.5 rounded-[10px] text-[13px]"
|
||||
style={{ background: "rgba(239,68,68,0.08)", color: "#f87171", border: "1px solid rgba(239,68,68,0.15)" }}>
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={handleConnect}
|
||||
disabled={isConnecting || !inputIp}
|
||||
className="w-full py-3.5 rounded-[12px] text-[16px] font-semibold text-black transition-all duration-150 active:scale-[0.98] disabled:opacity-40 flex items-center justify-center gap-2"
|
||||
style={{
|
||||
background: "#00FFF6",
|
||||
boxShadow: isConnecting ? "none" : "0 0 24px rgba(0,255,246,0.25)",
|
||||
}}>
|
||||
{isConnecting && !isDemoMode ? (
|
||||
<><Loader2 size={17} className="animate-spin" /> 连接中...</>
|
||||
) : (
|
||||
<><Wifi size={17} /> 连接设备</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { useDevice } from "@/contexts/DeviceContext";
|
||||
import { Loader2, Wifi } from "lucide-react";
|
||||
import BottomNav from "@/components/BottomNav";
|
||||
|
||||
/** 自动连接设备时的占位(替代原 ConnectScreen) */
|
||||
export default function ConnectionPlaceholder() {
|
||||
const { ip, isConnecting, error } = useDevice();
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-black flex flex-col items-center justify-center px-6 pb-24">
|
||||
<div className="mb-6 flex size-[4.5rem] items-center justify-center rounded-[16px] border border-white/15">
|
||||
<Wifi size={28} className="text-[#00FFF6]/80" />
|
||||
</div>
|
||||
{isConnecting ? (
|
||||
<>
|
||||
<Loader2 size={28} className="animate-spin text-[#00FFF6] mb-3" />
|
||||
<p className="text-[15px] text-white/70">Connecting to {ip}…</p>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p className="text-[15px] text-white/80 mb-2">Connection failed</p>
|
||||
<p className="text-[13px] text-white/45 text-center max-w-xs">
|
||||
{error ?? "Check the device IP and your network connection."}
|
||||
</p>
|
||||
<p className="text-[12px] text-white/30 mt-3">
|
||||
Specify the device in the URL, e.g.{" "}
|
||||
<span className="text-white/50">?ip=10.0.0.119</span>
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
<BottomNav />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user