This commit is contained in:
eric
2026-03-29 01:17:00 -05:00
parent af927c6dca
commit 8bce529255
10 changed files with 775 additions and 300 deletions

View File

@@ -1,9 +1,13 @@
"use client";
import { Pause, Play, RefreshCw } from "lucide-react";
import { ExternalLink, Pause, Play, RefreshCw } from "lucide-react";
import { useCallback, useEffect, useRef, useState } from "react";
import { extractDouyinRoomHints } from "@/lib/youtubeConfigUtils";
import {
extractDouyinCurrentRoomFromLog,
extractDouyinLiveUrls,
extractDouyinRoomHints,
} from "@/lib/youtubeConfigUtils";
type TFn = (zh: string, en: string) => string;
@@ -64,6 +68,11 @@ export function LiveProcessLiveLogCard({
const prevOnlineRef = useRef(false);
const douyinHints = extractDouyinRoomHints(urlListText);
const onlineNow = /^(online|running)$/i.test(processStatus);
const roomFromLog = extractDouyinCurrentRoomFromLog(recentLog);
const fallbackUrl = extractDouyinLiveUrls(urlListText)[0] ?? "";
const primaryRoomId = roomFromLog || (fallbackUrl.match(/live\.douyin\.com\/([a-zA-Z0-9_-]+)/i)?.[1] ?? null);
const primaryUrl = primaryRoomId ? `https://live.douyin.com/${primaryRoomId}` : fallbackUrl || null;
const pull = useCallback(async () => {
if (!currentProc) return;
@@ -182,26 +191,50 @@ export function LiveProcessLiveLogCard({
<span className="font-mono text-zinc-300">{keySuffixUi || "—"}</span>
</div>
) : null}
{douyinHints.length > 0 ? (
<div className="text-xs">
<span className="text-zinc-500">{t("源站房间线索", "Douyin room hints")}</span>
<span className="ml-2 inline-flex flex-wrap gap-1">
{douyinHints.map((id, i) => (
<a
key={`${id}-${i}`}
href={`https://live.douyin.com/${id}`}
target="_blank"
rel="noreferrer"
className="text-violet-300 underline-offset-2 hover:underline"
>
{id}
</a>
))}
</span>
{primaryUrl ? (
<div className="rounded-lg border border-violet-500/20 bg-violet-500/[0.06] px-3 py-2.5">
<div className="flex flex-wrap items-center justify-between gap-2">
<span className="text-[11px] font-medium text-zinc-400">
{roomFromLog
? t("当前直播源站(日志)", "Current source (from log)")
: onlineNow
? t("配置中的源站地址", "Configured source URL")
: t("源站快捷入口", "Source quick link")}
</span>
<a
href={primaryUrl}
target="_blank"
rel="noreferrer"
className="inline-flex items-center gap-1.5 rounded-lg bg-violet-500/20 px-3 py-1.5 text-xs font-medium text-violet-100 ring-1 ring-violet-500/35 transition hover:bg-violet-500/30"
>
<ExternalLink className="h-3.5 w-3.5 shrink-0 opacity-90" />
{primaryRoomId || t("打开抖音直播页", "Open Douyin live")}
</a>
</div>
{douyinHints.length > 1 && roomFromLog ? (
<p className="mt-2 text-[10px] text-zinc-600">
{t("配置中还有", "Also in config:")}{" "}
{douyinHints
.filter((id) => id !== primaryRoomId)
.slice(0, 3)
.map((id) => (
<a
key={id}
href={`https://live.douyin.com/${id}`}
target="_blank"
rel="noreferrer"
className="ml-1 text-violet-400/90 underline-offset-2 hover:underline"
>
{id}
</a>
))}
{douyinHints.length > 4 ? "…" : null}
</p>
) : null}
</div>
) : (
<p className="text-[11px] text-zinc-600">
{t("(地址列表中未解析到抖音房间线索", "(No Douyin room id in URL list)")}
{t("日志与地址列表中暂无抖音房间)", "(No Douyin room in log or URL list)")}
</p>
)}
</div>