Enhance ConnectionPlaceholder component to handle missing device IP with localized messages; update DeviceContext to manage IP state; improve CSS for touch actions in various components; update locale files for English and Chinese with new connection prompts.

This commit is contained in:
yangy
2026-05-22 17:24:50 +08:00
parent 32f15217ad
commit 11821730ec
9 changed files with 89 additions and 22 deletions
@@ -1,31 +1,61 @@
import { useMemo } from "react";
import { useDevice } from "@/contexts/DeviceContext";
import { Loader2, Wifi } from "lucide-react";
import BottomNav from "@/components/BottomNav";
import localeZh from "@/locales/data-zh.json";
import localeZhHK from "@/locales/data-zh-HK.json";
import localeEn from "@/locales/data-en.json";
type ConnectLocale = (typeof localeZh)["connect"];
function pickConnectLocale(): ConnectLocale {
const params = new URLSearchParams(window.location.search);
const lang = params.get("lang");
if (lang === "0") return localeEn.connect;
if (lang === "1") return localeZhHK.connect;
if (lang === "2") return localeZh.connect;
const nav = navigator.language.toLowerCase();
if (nav.startsWith("zh-hk") || nav.startsWith("zh-tw")) return localeZhHK.connect;
if (nav.startsWith("zh")) return localeZh.connect;
return localeEn.connect;
}
function fmt(template: string, vars: Record<string, string>): string {
let s = template;
for (const [k, v] of Object.entries(vars)) {
s = s.split(`{${k}}`).join(v);
}
return s;
}
/** 自动连接设备时的占位(替代原 ConnectScreen */
export default function ConnectionPlaceholder() {
const { ip, isConnecting, error } = useDevice();
const { ip, isConnecting, error, ipMissing } = useDevice();
const text = useMemo(pickConnectLocale, []);
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 ? (
{ipMissing ? (
<>
<p className="text-[15px] text-white/80 mb-2">{text.ipMissingTitle}</p>
<p className="text-[13px] text-white/45 text-center max-w-xs">{text.ipMissingDesc}</p>
<p className="text-[13px] text-[#00FFF6]/80 mt-3 font-mono">?ip=10.0.0.119</p>
</>
) : 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/70">{fmt(text.connecting, { ip })}</p>
</>
) : (
<>
<p className="text-[15px] text-white/80 mb-2">Connection failed</p>
<p className="text-[15px] text-white/80 mb-2">{text.failedTitle}</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>
{error ?? text.failedDesc}
</p>
<p className="text-[12px] text-white/30 mt-3 text-center max-w-xs">{text.failedHint}</p>
</>
)}
<BottomNav />
+1 -1
View File
@@ -92,7 +92,7 @@ export default function DesktopAIShell({ children }: { children: ReactNode }) {
"min-w-0",
showSplit
? "h-full min-h-0 overflow-y-auto overflow-x-hidden"
: "min-h-dvh overflow-x-hidden",
: "min-h-dvh max-h-dvh overflow-x-hidden overflow-y-auto overscroll-y-contain [touch-action:pan-y]",
)}
style={
showSplit