125 lines
5.5 KiB
TypeScript
125 lines
5.5 KiB
TypeScript
"use client";
|
||
|
||
import { ExternalLink, FolderOpen } from "lucide-react";
|
||
|
||
import { normalizeBrowserReachableHttpUrl } from "@/lib/panelUrls";
|
||
|
||
type TFn = (zh: string, en: string) => string;
|
||
type PortalTheme = "dark" | "light";
|
||
|
||
type Props = {
|
||
t: TFn;
|
||
portalTheme: PortalTheme;
|
||
filebrowserUrl: string;
|
||
};
|
||
|
||
export function LiveFilebrowserPanel({ t, portalTheme, filebrowserUrl }: Props) {
|
||
const url = filebrowserUrl ? normalizeBrowserReachableHttpUrl(filebrowserUrl) : "";
|
||
|
||
return (
|
||
<div className="mx-auto max-w-5xl space-y-6">
|
||
<div
|
||
className={`rounded-2xl border p-6 shadow-xl ${
|
||
portalTheme === "light"
|
||
? "border-slate-200/90 bg-gradient-to-br from-amber-50/90 via-white to-slate-50"
|
||
: "border-amber-500/25 bg-gradient-to-br from-amber-500/[0.12] via-zinc-950/80 to-violet-500/10"
|
||
}`}
|
||
>
|
||
<div className="flex items-start gap-3">
|
||
<div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-xl bg-gradient-to-br from-amber-500/35 to-violet-600/25 ring-1 ring-white/10">
|
||
<FolderOpen className="h-5 w-5 text-amber-200" />
|
||
</div>
|
||
<div>
|
||
<h2
|
||
className={`text-lg font-semibold tracking-tight ${portalTheme === "light" ? "text-slate-900" : "text-white"}`}
|
||
>
|
||
{t("文件(File Browser)", "Files (File Browser)")}
|
||
</h2>
|
||
<p className={`mt-1 text-xs ${portalTheme === "light" ? "text-slate-600" : "text-zinc-500"}`}>
|
||
{t(
|
||
"与 Docker 部署的 File Browser 分离:此处仅嵌入面板并说明 API,便于你自建「选本地视频 → 配合 TikTok HDMI 测试」等前端逻辑。",
|
||
"Separate from File Browser itself: embed + API notes so you can build “pick local video → TikTok HDMI test” flows.",
|
||
)}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div
|
||
className={`rounded-2xl border p-5 ${
|
||
portalTheme === "light" ? "border-slate-200/90 bg-white/90" : "border-white/[0.08] bg-zinc-950/50"
|
||
}`}
|
||
>
|
||
<p className={`text-sm font-medium ${portalTheme === "light" ? "text-slate-800" : "text-white"}`}>
|
||
{t("内置 UI(iframe)", "Built-in UI (iframe)")}
|
||
</p>
|
||
<p className={`mt-1 text-xs ${portalTheme === "light" ? "text-slate-600" : "text-zinc-500"}`}>
|
||
{t(
|
||
"若服务未启动或端口不通,请先在「服务」页启动 filebrowser 容器。",
|
||
"Start the filebrowser service from Services if the frame is blank.",
|
||
)}
|
||
</p>
|
||
{url ? (
|
||
<div
|
||
className={`mt-4 overflow-hidden rounded-xl border ${
|
||
portalTheme === "light" ? "border-slate-200 bg-slate-50" : "border-white/10 bg-black/40"
|
||
}`}
|
||
>
|
||
<div className="flex items-center justify-between gap-2 border-b border-white/5 px-3 py-2">
|
||
<span className="truncate font-mono text-[11px] text-zinc-500">{url}</span>
|
||
<a
|
||
href={url}
|
||
target="_blank"
|
||
rel="noreferrer"
|
||
className={`inline-flex shrink-0 items-center gap-1 rounded-lg px-2 py-1 text-[11px] font-medium ${
|
||
portalTheme === "light"
|
||
? "bg-violet-100 text-violet-800"
|
||
: "bg-violet-500/20 text-violet-200"
|
||
}`}
|
||
>
|
||
<ExternalLink className="h-3 w-3" />
|
||
{t("新窗口", "New tab")}
|
||
</a>
|
||
</div>
|
||
<iframe title="File Browser" src={url} className="h-[min(72vh,40rem)] w-full bg-black/20" />
|
||
</div>
|
||
) : (
|
||
<p className={`mt-4 text-sm ${portalTheme === "light" ? "text-amber-800" : "text-amber-200/90"}`}>
|
||
{t("未从总览获取到 filebrowser 链接;请确认 stack 配置与 hub 仪表盘。", "No filebrowser URL from dashboard.")}
|
||
</p>
|
||
)}
|
||
</div>
|
||
|
||
<div
|
||
className={`rounded-2xl border p-5 ${
|
||
portalTheme === "light" ? "border-slate-200/90 bg-white/90" : "border-white/[0.08] bg-zinc-950/50"
|
||
}`}
|
||
>
|
||
<h3 className={`text-sm font-semibold ${portalTheme === "light" ? "text-slate-900" : "text-white"}`}>
|
||
{t("REST API(自定义前端)", "REST API (custom UI)")}
|
||
</h3>
|
||
<ul className={`mt-3 space-y-2 text-xs ${portalTheme === "light" ? "text-slate-600" : "text-zinc-400"}`}>
|
||
<li>
|
||
{t(
|
||
"登录:POST /api/login,Body 为 JSON:username / password(与 File Browser 账户一致),返回 Set-Cookie 或 token(视版本而定)。",
|
||
"Login: POST /api/login with JSON username/password; follow cookie/token per your File Browser version.",
|
||
)}
|
||
</li>
|
||
<li>
|
||
{t(
|
||
"列目录:GET /api/resources(常需携带 Cookie)。具体字段以你部署的版本文档为准。",
|
||
"List: GET /api/resources (often cookie-authenticated). See your image version docs.",
|
||
)}
|
||
</li>
|
||
<li>
|
||
{t(
|
||
"与 TikTok HDMI 页配合:在自定义脚本里拉取文件路径后,可写独立 ffmpeg 推流;控制台会在启动 TikTok / obs*.sh 时自动互斥其它 HDMI 链路进程。",
|
||
"With TikTok HDMI: your script can feed ffmpeg paths; the hub stops other TikTok/OBS HDMI sinks when you start one.",
|
||
)}
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|