's'
This commit is contained in:
@@ -74,6 +74,13 @@ type HubDashboard = {
|
||||
platform?: string;
|
||||
ips?: string[];
|
||||
quick_links?: Record<string, string>;
|
||||
neko_login?: {
|
||||
user_login?: string;
|
||||
user_password?: string;
|
||||
admin_login?: string;
|
||||
admin_password?: string;
|
||||
note_zh?: string;
|
||||
};
|
||||
};
|
||||
services?: Array<{
|
||||
service_id: string;
|
||||
@@ -121,6 +128,11 @@ type HubDashboard = {
|
||||
http?: { ok?: boolean; http_code?: number; reachable?: boolean; latency_ms?: number; error?: string };
|
||||
http_ui?: { ok?: boolean; http_code?: number; reachable?: boolean; latency_ms?: number; error?: string };
|
||||
};
|
||||
neko?: {
|
||||
port?: number;
|
||||
tcp?: { ok?: boolean; reachable?: boolean; latency_ms?: number; error?: string };
|
||||
http?: { ok?: boolean; http_code?: number; reachable?: boolean; latency_ms?: number; error?: string };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -802,6 +814,42 @@ export default function LiveControlApp() {
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{dash?.stack?.neko_login ? (
|
||||
<div className="rounded-2xl border border-fuchsia-500/25 bg-gradient-to-r from-fuchsia-500/[0.08] to-violet-500/[0.06] p-5">
|
||||
<h3 className="text-sm font-semibold text-white">Neko {t("登录", "sign-in")}</h3>
|
||||
<p className="mt-1 text-[11px] text-zinc-500">
|
||||
{dash.stack.neko_login.note_zh ||
|
||||
t("Neko Chromium :9200 使用下列账号策略。", "Neko Chromium :9200 uses the policy below.")}
|
||||
</p>
|
||||
<p className="mt-2 text-[11px] text-amber-200/85">
|
||||
{t(
|
||||
"重要:两栏分开填——昵称随意,密码必须是环境变量里的口令(默认 12345678)。用错密码会像一直加载;勿把「用户名/密码」写在一行。",
|
||||
"Use two fields: display name is free-form; password must match NEKO_* (default 12345678). Wrong password looks like infinite loading.",
|
||||
)}
|
||||
</p>
|
||||
<div className="mt-4 grid gap-3 sm:grid-cols-2 font-mono text-sm">
|
||||
<div className="rounded-xl border border-white/10 bg-black/40 px-4 py-3">
|
||||
<p className="text-[10px] uppercase text-zinc-500">{t("用户", "User")}</p>
|
||||
<p className="mt-1 text-fuchsia-200">{dash.stack.neko_login.user_login ?? "live"}</p>
|
||||
<p className="mt-2 text-[10px] uppercase text-zinc-500">{t("口令", "Password")}</p>
|
||||
<p className="mt-0.5 text-fuchsia-100">{dash.stack.neko_login.user_password ?? "—"}</p>
|
||||
</div>
|
||||
<div className="rounded-xl border border-white/10 bg-black/40 px-4 py-3">
|
||||
<p className="text-[10px] uppercase text-zinc-500">{t("管理员", "Admin")}</p>
|
||||
<p className="mt-1 text-violet-200">{dash.stack.neko_login.admin_login ?? "admin"}</p>
|
||||
<p className="mt-2 text-[10px] uppercase text-zinc-500">{t("口令", "Password")}</p>
|
||||
<p className="mt-0.5 text-violet-100">{dash.stack.neko_login.admin_password ?? "—"}</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mt-3 text-[10px] text-zinc-600">
|
||||
{t(
|
||||
"Google 无官方 ARM 桌面 Chrome 品牌包;此处为 Neko 自带的 Chromium 桌面(与 Chrome 商标不同)。本栈未启用 Firefox 版 Neko。",
|
||||
"No official ARM desktop Chrome branding here; this is Neko’s bundled Chromium desktop. This stack does not use the Neko Firefox image.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{dash?.network?.interfaces?.length ? (
|
||||
<div className="rounded-2xl border border-cyan-500/15 bg-gradient-to-br from-cyan-500/[0.07] to-transparent p-5">
|
||||
<h3 className="flex items-center gap-2 text-sm font-semibold text-white">
|
||||
@@ -962,6 +1010,38 @@ export default function LiveControlApp() {
|
||||
);
|
||||
})()
|
||||
) : null}
|
||||
{dash.probes.neko ? (
|
||||
(() => {
|
||||
const p = dash.probes?.neko;
|
||||
const tcpOk = p?.tcp?.reachable;
|
||||
const http = p?.http;
|
||||
return (
|
||||
<div className="rounded-2xl border border-white/[0.07] bg-zinc-950/40 p-4 backdrop-blur-sm">
|
||||
<p className="text-xs font-semibold text-white">Neko Chromium</p>
|
||||
<p className="mt-1 text-[11px] text-zinc-500">
|
||||
{t(
|
||||
"Docker 内 Chromium(非 Chrome 品牌);arm64/x86 同一镜像。",
|
||||
"Chromium in Docker (not Chrome branding); multi-arch.",
|
||||
)}
|
||||
</p>
|
||||
<p className="mt-2 font-mono text-[11px] text-zinc-500">
|
||||
:{p?.port ?? "—"} · TCP {tcpOk ? "OK" : "—"} · HTTP {http?.http_code ?? "—"}
|
||||
</p>
|
||||
<p className="mt-1 text-[11px] text-zinc-500">
|
||||
{t("延迟", "RTT")}{" "}
|
||||
{http?.latency_ms != null
|
||||
? `${http.latency_ms} ms`
|
||||
: p?.tcp?.latency_ms != null
|
||||
? `${p.tcp.latency_ms} ms`
|
||||
: "—"}
|
||||
</p>
|
||||
{!http?.reachable && http?.error ? (
|
||||
<p className="mt-1 line-clamp-2 text-[10px] text-amber-200/80">{http.error}</p>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
})()
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
@@ -1149,7 +1229,7 @@ export default function LiveControlApp() {
|
||||
<p className={`mt-2 text-xs ${portalTheme === "light" ? "text-slate-600" : "text-zinc-400"}`}>
|
||||
{t(
|
||||
"透明代理与规则分流直接在本页完成,无需跳转;流媒体与其它系统服务请在「服务」页管理。",
|
||||
"Proxy rules and YAML editing are embedded here. Use Services for SRS, Chromium, etc.",
|
||||
"Proxy rules and YAML editing are embedded here. Use Services for SRS/Neko/Chromium, etc.",
|
||||
)}
|
||||
</p>
|
||||
<div className="mt-6 flex flex-col items-center gap-4 sm:flex-row sm:justify-center">
|
||||
@@ -1214,7 +1294,7 @@ export default function LiveControlApp() {
|
||||
</label>
|
||||
<label className="flex cursor-pointer items-center justify-between gap-4 border-t border-white/[0.06] pt-4">
|
||||
<div>
|
||||
<p className="text-sm font-medium text-white">{t("总览显示 SRS 探针", "Show SRS stream probe")}</p>
|
||||
<p className="text-sm font-medium text-white">{t("总览显示 SRS / Neko 探针", "Show SRS/Neko probes")}</p>
|
||||
<p className="text-[11px] text-zinc-500">{t("关闭可精简首页", "Hide stream probe cards")}</p>
|
||||
</div>
|
||||
<input
|
||||
|
||||
Reference in New Issue
Block a user