s
This commit is contained in:
@@ -224,6 +224,8 @@ export default function LiveControlApp() {
|
||||
const [showStreamProbes, setShowStreamProbes] = useState(true);
|
||||
const dashboardInFlightRef = useRef<Promise<void> | null>(null);
|
||||
const processMonitorInFlightRef = useRef<Promise<void> | null>(null);
|
||||
const currentProcRef = useRef(currentProc);
|
||||
const urlConfigRequestSeqRef = useRef(0);
|
||||
|
||||
const t = useCallback((zh: string, en: string) => tr(lang, zh, en), [lang]);
|
||||
|
||||
@@ -345,13 +347,20 @@ export default function LiveControlApp() {
|
||||
return () => clearInterval(id);
|
||||
}, [autoRefreshEnabled, refreshProcessMonitor, view]);
|
||||
|
||||
useEffect(() => {
|
||||
currentProcRef.current = currentProc;
|
||||
}, [currentProc]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentProc || view !== "live_youtube") return;
|
||||
void (async () => {
|
||||
const targetProc = currentProcRef.current.trim();
|
||||
const requestId = ++urlConfigRequestSeqRef.current;
|
||||
try {
|
||||
const data = await fetchJson<{ content?: string }>(
|
||||
`/get_url_config?process=${encodeURIComponent(currentProc)}`,
|
||||
`/get_url_config?process=${encodeURIComponent(targetProc)}`,
|
||||
);
|
||||
if (requestId !== urlConfigRequestSeqRef.current || targetProc !== currentProcRef.current.trim()) return;
|
||||
setUrlConfig(data.content || "");
|
||||
} catch {
|
||||
/* 保留当前草稿,避免临时读取失败把编辑器清空 */
|
||||
|
||||
@@ -51,6 +51,7 @@ type Props = {
|
||||
keySuffixUi: string;
|
||||
showKeyRow?: boolean;
|
||||
pollMs?: number;
|
||||
refreshToken?: number;
|
||||
};
|
||||
|
||||
function businessLine(t: TFn, raw: string | undefined, note: string | undefined): string {
|
||||
@@ -75,6 +76,7 @@ export function LiveProcessLiveLogCard({
|
||||
keySuffixUi,
|
||||
showKeyRow = true,
|
||||
pollMs = 1000,
|
||||
refreshToken = 0,
|
||||
}: Props) {
|
||||
const [processStatus, setProcessStatus] = useState<string>("");
|
||||
const [recentLog, setRecentLog] = useState("");
|
||||
@@ -91,6 +93,8 @@ export function LiveProcessLiveLogCard({
|
||||
const prevOnlineRef = useRef(false);
|
||||
const pullInFlightRef = useRef(false);
|
||||
const pullQueuedRef = useRef(false);
|
||||
const currentProcRef = useRef(currentProc);
|
||||
const requestSeqRef = useRef(0);
|
||||
|
||||
const douyinHints = extractDouyinRoomHints(urlListText);
|
||||
const onlineNow = /^(online|running)$/i.test(processStatus);
|
||||
@@ -100,16 +104,19 @@ export function LiveProcessLiveLogCard({
|
||||
const primaryUrl = primaryRoomId ? `https://live.douyin.com/${primaryRoomId}` : fallbackUrl || null;
|
||||
|
||||
const pull = useCallback(async () => {
|
||||
if (!currentProc) return;
|
||||
const targetProc = currentProcRef.current.trim();
|
||||
if (!targetProc) return;
|
||||
if (pullInFlightRef.current) {
|
||||
pullQueuedRef.current = true;
|
||||
return;
|
||||
}
|
||||
pullInFlightRef.current = true;
|
||||
const requestId = ++requestSeqRef.current;
|
||||
try {
|
||||
const data = await fetchJson<StatusPayload>(
|
||||
`/status?process=${encodeURIComponent(currentProc)}`,
|
||||
`/status?process=${encodeURIComponent(targetProc)}`,
|
||||
);
|
||||
if (requestId !== requestSeqRef.current || targetProc !== currentProcRef.current.trim()) return;
|
||||
const ps = data.process_status || "unknown";
|
||||
setProcessStatus(ps);
|
||||
setRecentLog(data.recent_log || "");
|
||||
@@ -127,6 +134,7 @@ export function LiveProcessLiveLogCard({
|
||||
}
|
||||
prevOnlineRef.current = online;
|
||||
} catch {
|
||||
if (requestId !== requestSeqRef.current || targetProc !== currentProcRef.current.trim()) return;
|
||||
setProcessStatus("error");
|
||||
setBusinessStatus("error");
|
||||
setBusinessNote("");
|
||||
@@ -139,11 +147,40 @@ export function LiveProcessLiveLogCard({
|
||||
window.setTimeout(() => void pull(), 0);
|
||||
}
|
||||
}
|
||||
}, [currentProc, fetchJson]);
|
||||
}, [fetchJson]);
|
||||
|
||||
useEffect(() => {
|
||||
currentProcRef.current = currentProc;
|
||||
requestSeqRef.current += 1;
|
||||
pullQueuedRef.current = false;
|
||||
if (!currentProc) {
|
||||
setProcessStatus("");
|
||||
setRecentLog("");
|
||||
setRecentError("");
|
||||
setBusinessStatus("");
|
||||
setBusinessNote("");
|
||||
setFfmpegPids([]);
|
||||
setLogAgeSeconds(null);
|
||||
setLiveSince(null);
|
||||
prevOnlineRef.current = false;
|
||||
return;
|
||||
}
|
||||
setProcessStatus("");
|
||||
setRecentLog("");
|
||||
setRecentError("");
|
||||
setBusinessStatus("");
|
||||
setBusinessNote("");
|
||||
setFfmpegPids([]);
|
||||
setLogAgeSeconds(null);
|
||||
setLiveSince(null);
|
||||
prevOnlineRef.current = false;
|
||||
void pull();
|
||||
}, [pull]);
|
||||
}, [currentProc, pull]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentProc) return;
|
||||
void pull();
|
||||
}, [currentProc, pull, refreshToken]);
|
||||
|
||||
useEffect(() => {
|
||||
if (paused || !currentProc) return;
|
||||
@@ -190,6 +227,9 @@ export function LiveProcessLiveLogCard({
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<h3 className="text-sm font-semibold text-white">{t("当前直播日志", "Live process log")}</h3>
|
||||
<span className="rounded-full bg-white/10 px-2 py-0.5 font-mono text-[10px] text-zinc-300 ring-1 ring-white/10">
|
||||
{currentProc || "—"}
|
||||
</span>
|
||||
<span className="rounded-full bg-emerald-500/15 px-2 py-0.5 text-[10px] font-medium text-emerald-200/90 ring-1 ring-emerald-500/25">
|
||||
{paused ? t("已暂停刷新", "Paused") : t("每秒刷新", "~1s refresh")}
|
||||
</span>
|
||||
|
||||
@@ -120,9 +120,18 @@ export function LiveTiktokHdmiView({
|
||||
const [urlAutoRefresh, setUrlAutoRefresh] = useState(true);
|
||||
const [urlFetchNote, setUrlFetchNote] = useState<string | null>(null);
|
||||
const urlListDirtyRef = useRef(false);
|
||||
const urlDraftRef = useRef(urlConfig);
|
||||
const [hdmiNotes, setHdmiNotes] = useState("");
|
||||
const [checks, setChecks] = useState<Record<string, boolean>>({});
|
||||
|
||||
const applyUrlDraft = useCallback(
|
||||
(next: string) => {
|
||||
urlDraftRef.current = next;
|
||||
setUrlConfig(next);
|
||||
},
|
||||
[setUrlConfig],
|
||||
);
|
||||
|
||||
const setSourceModePersist = useCallback(
|
||||
(m: TiktokSourceMode) => {
|
||||
setSourceMode(m);
|
||||
@@ -151,17 +160,21 @@ export function LiveTiktokHdmiView({
|
||||
urlListDirtyRef.current = false;
|
||||
}, [currentProc]);
|
||||
|
||||
useEffect(() => {
|
||||
urlDraftRef.current = urlConfig;
|
||||
}, [urlConfig]);
|
||||
|
||||
const pullUrlConfigFromServer = useCallback(async () => {
|
||||
if (!currentProc) return;
|
||||
try {
|
||||
const data = await fetchJson<{ content?: string }>(
|
||||
`/get_url_config?process=${encodeURIComponent(currentProc)}`,
|
||||
);
|
||||
setUrlConfig(data.content ?? "");
|
||||
applyUrlDraft(data.content ?? "");
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}, [currentProc, fetchJson, setUrlConfig]);
|
||||
}, [applyUrlDraft, currentProc, fetchJson]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentProc || !urlAutoRefresh || sourceMode !== "ffmpeg") return;
|
||||
@@ -239,7 +252,7 @@ export function LiveTiktokHdmiView({
|
||||
const data = await fetchJson<{ content?: string }>(
|
||||
`/get_url_config?process=${encodeURIComponent(currentProc)}`,
|
||||
);
|
||||
setUrlConfig(data.content ?? "");
|
||||
applyUrlDraft(data.content ?? "");
|
||||
setUrlFetchNote(t("已从服务器读取 URL_config", "Reloaded URL_config from server"));
|
||||
} catch (e) {
|
||||
setUrlFetchNote((e as Error).message);
|
||||
@@ -250,7 +263,7 @@ export function LiveTiktokHdmiView({
|
||||
|
||||
const saveUrlAndClearDirty = async () => {
|
||||
try {
|
||||
await Promise.resolve(onSaveUrlConfig());
|
||||
await Promise.resolve(onSaveUrlConfig(urlDraftRef.current));
|
||||
urlListDirtyRef.current = false;
|
||||
} catch {
|
||||
/* parent 已 toast */
|
||||
@@ -745,7 +758,7 @@ export function LiveTiktokHdmiView({
|
||||
value={urlConfig}
|
||||
onChange={(e) => {
|
||||
urlListDirtyRef.current = true;
|
||||
setUrlConfig(e.target.value);
|
||||
applyUrlDraft(e.target.value);
|
||||
}}
|
||||
spellCheck={false}
|
||||
/>
|
||||
|
||||
@@ -362,28 +362,62 @@ export function LiveYoutubeUnmannedView({
|
||||
const [laneDrafts, setLaneDrafts] = useState<Record<string, ProLaneDraft>>({});
|
||||
const [laneSaving, setLaneSaving] = useState(false);
|
||||
const [laneStatus, setLaneStatus] = useState<string | null>(null);
|
||||
const [activeViewRefreshToken, setActiveViewRefreshToken] = useState(0);
|
||||
const urlListDirtyRef = useRef(false);
|
||||
const singleUrlDraftRef = useRef(urlConfig);
|
||||
const proUrlDraftRef = useRef(proUrlDraft);
|
||||
const currentProcRef = useRef(currentProc);
|
||||
const urlRequestSeqRef = useRef(0);
|
||||
const ytIniRequestSeqRef = useRef(0);
|
||||
|
||||
const applySingleUrlDraft = useCallback(
|
||||
(next: string) => {
|
||||
singleUrlDraftRef.current = next;
|
||||
setUrlConfig(next);
|
||||
},
|
||||
[setUrlConfig],
|
||||
);
|
||||
|
||||
const applyProUrlDraft = useCallback((next: string) => {
|
||||
proUrlDraftRef.current = next;
|
||||
setProUrlDraft(next);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
urlListDirtyRef.current = false;
|
||||
}, [currentProc]);
|
||||
|
||||
useEffect(() => {
|
||||
currentProcRef.current = currentProc;
|
||||
}, [currentProc]);
|
||||
|
||||
useEffect(() => {
|
||||
singleUrlDraftRef.current = urlConfig;
|
||||
}, [urlConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
proUrlDraftRef.current = proUrlDraft;
|
||||
}, [proUrlDraft]);
|
||||
|
||||
const pullUrlConfigFromServer = useCallback(async () => {
|
||||
if (!currentProc) return;
|
||||
const targetProc = currentProcRef.current.trim();
|
||||
if (!targetProc) return;
|
||||
const requestId = ++urlRequestSeqRef.current;
|
||||
try {
|
||||
const data = await fetchJson<{ content?: string }>(
|
||||
`/get_url_config?process=${encodeURIComponent(currentProc)}`,
|
||||
`/get_url_config?process=${encodeURIComponent(targetProc)}`,
|
||||
);
|
||||
if (requestId !== urlRequestSeqRef.current || targetProc !== currentProcRef.current.trim()) return;
|
||||
const c = data.content ?? "";
|
||||
if (urlListDirtyRef.current) return;
|
||||
if (mode === "single") setUrlConfig(c);
|
||||
if (mode === "single") applySingleUrlDraft(c);
|
||||
else {
|
||||
const localDraft = channels.find((row) => row.id === activeCh)?.urlLines ?? "";
|
||||
if (shouldPreserveLocalUrlDraft(localDraft, c)) {
|
||||
setProUrlDraft(localDraft);
|
||||
applyProUrlDraft(localDraft);
|
||||
return;
|
||||
}
|
||||
setProUrlDraft(c);
|
||||
applyProUrlDraft(c);
|
||||
if (activeCh) {
|
||||
setChannels((prev) => {
|
||||
const next = prev.map((x) => (x.id === activeCh ? { ...x, urlLines: c } : x));
|
||||
@@ -395,7 +429,7 @@ export function LiveYoutubeUnmannedView({
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}, [activeCh, channels, currentProc, fetchJson, mode, setUrlConfig]);
|
||||
}, [activeCh, applyProUrlDraft, applySingleUrlDraft, channels, fetchJson, mode]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentProc || !urlAutoRefresh) return;
|
||||
@@ -407,28 +441,31 @@ export function LiveYoutubeUnmannedView({
|
||||
}, [currentProc, urlAutoRefresh, pullUrlConfigFromServer]);
|
||||
|
||||
const reloadUrlManual = async () => {
|
||||
if (!currentProc) return;
|
||||
const targetProc = currentProcRef.current.trim();
|
||||
if (!targetProc) return;
|
||||
setUrlReloading(true);
|
||||
setUrlFetchNote(null);
|
||||
urlListDirtyRef.current = false;
|
||||
const requestId = ++urlRequestSeqRef.current;
|
||||
try {
|
||||
const data = await fetchJson<{ content?: string }>(
|
||||
`/get_url_config?process=${encodeURIComponent(currentProc)}`,
|
||||
`/get_url_config?process=${encodeURIComponent(targetProc)}`,
|
||||
);
|
||||
if (requestId !== urlRequestSeqRef.current || targetProc !== currentProcRef.current.trim()) return;
|
||||
const c = data.content ?? "";
|
||||
if (urlListDirtyRef.current) {
|
||||
setUrlFetchNote(t("检测到本地未保存修改,已保留当前草稿", "Kept the local unsaved draft"));
|
||||
return;
|
||||
}
|
||||
if (mode === "single") setUrlConfig(c);
|
||||
if (mode === "single") applySingleUrlDraft(c);
|
||||
else {
|
||||
const localDraft = channels.find((row) => row.id === activeCh)?.urlLines ?? "";
|
||||
if (shouldPreserveLocalUrlDraft(localDraft, c)) {
|
||||
setProUrlDraft(localDraft);
|
||||
applyProUrlDraft(localDraft);
|
||||
setUrlFetchNote(t("服务器暂无已保存 URL,已保留本地草稿", "Server has no saved URLs, kept the local draft"));
|
||||
return;
|
||||
}
|
||||
setProUrlDraft(c);
|
||||
applyProUrlDraft(c);
|
||||
if (activeCh) {
|
||||
setChannels((prev) => {
|
||||
const next = prev.map((x) => (x.id === activeCh ? { ...x, urlLines: c } : x));
|
||||
@@ -439,9 +476,12 @@ export function LiveYoutubeUnmannedView({
|
||||
}
|
||||
setUrlFetchNote(t("已从服务器读取 URL_config", "Reloaded URL_config from server"));
|
||||
} catch (e) {
|
||||
if (requestId !== urlRequestSeqRef.current || targetProc !== currentProcRef.current.trim()) return;
|
||||
setUrlFetchNote((e as Error).message);
|
||||
} finally {
|
||||
setUrlReloading(false);
|
||||
if (requestId === urlRequestSeqRef.current && targetProc === currentProcRef.current.trim()) {
|
||||
setUrlReloading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -552,11 +592,6 @@ export function LiveYoutubeUnmannedView({
|
||||
);
|
||||
|
||||
const active = channels.find((c) => c.id === activeCh) || channels[0];
|
||||
const activeSavedUrlDraft = useMemo(() => (active?.urlLines ?? "").trim(), [active?.urlLines]);
|
||||
const activeUrlDirty = useMemo(
|
||||
() => (active ? proUrlDraft !== (active.urlLines ?? "").trim() : false),
|
||||
[active, proUrlDraft],
|
||||
);
|
||||
const activeLaneDraft = useMemo(
|
||||
() => (active ? laneDrafts[active.id] ?? laneDraftFromChannel(active) : null),
|
||||
[active, laneDrafts],
|
||||
@@ -663,12 +698,14 @@ export function LiveYoutubeUnmannedView({
|
||||
const setModePersist = useCallback(
|
||||
(m: "single" | "pro") => {
|
||||
if (m === "single" && mode === "pro" && active) {
|
||||
if (activeUrlDirty) {
|
||||
persistChannels(channels.map((x) => (x.id === active.id ? { ...x, urlLines: proUrlDraft } : x)));
|
||||
const latestProUrlDraft = proUrlDraftRef.current;
|
||||
if (latestProUrlDraft !== (active.urlLines ?? "").trim()) {
|
||||
persistChannels(channels.map((x) => (x.id === active.id ? { ...x, urlLines: latestProUrlDraft } : x)));
|
||||
}
|
||||
}
|
||||
if (m === "pro" && channels.length) {
|
||||
const first = channels[0];
|
||||
const latestSingleUrlDraft = singleUrlDraftRef.current.trim();
|
||||
const youtubePm2Ok = staticYoutubeEntries.some((e) => e.pm2 === currentProc);
|
||||
const pm2Name =
|
||||
youtubePm2Ok && currentProc.trim()
|
||||
@@ -678,14 +715,14 @@ export function LiveYoutubeUnmannedView({
|
||||
{
|
||||
...first,
|
||||
streamKey: ytFields.key.trim() || first.streamKey || "",
|
||||
urlLines: urlConfig.trim() || first.urlLines || "",
|
||||
urlLines: latestSingleUrlDraft || first.urlLines || "",
|
||||
pm2Name,
|
||||
},
|
||||
...channels.slice(1),
|
||||
];
|
||||
persistChannels(next);
|
||||
const ch = next.find((c) => c.id === activeCh) ?? next[0];
|
||||
setProUrlDraft((ch?.urlLines ?? "").trim() || urlConfig.trim());
|
||||
applyProUrlDraft((ch?.urlLines ?? "").trim() || latestSingleUrlDraft);
|
||||
}
|
||||
setMode(m);
|
||||
try {
|
||||
@@ -697,11 +734,9 @@ export function LiveYoutubeUnmannedView({
|
||||
[
|
||||
mode,
|
||||
active,
|
||||
activeUrlDirty,
|
||||
channels,
|
||||
proUrlDraft,
|
||||
applyProUrlDraft,
|
||||
ytFields.key,
|
||||
urlConfig,
|
||||
currentProc,
|
||||
staticYoutubeEntries,
|
||||
activeCh,
|
||||
@@ -711,15 +746,16 @@ export function LiveYoutubeUnmannedView({
|
||||
|
||||
const selectProChannel = useCallback(
|
||||
(c: YoutubeProChannel) => {
|
||||
if (active && mode === "pro" && activeUrlDirty) {
|
||||
persistChannels(channels.map((x) => (x.id === active.id ? { ...x, urlLines: proUrlDraft } : x)));
|
||||
const latestProUrlDraft = proUrlDraftRef.current;
|
||||
if (active && mode === "pro" && latestProUrlDraft !== (active.urlLines ?? "").trim()) {
|
||||
persistChannels(channels.map((x) => (x.id === active.id ? { ...x, urlLines: latestProUrlDraft } : x)));
|
||||
}
|
||||
const u = (c.urlLines ?? "").trim();
|
||||
setProUrlDraft(u);
|
||||
applyProUrlDraft(u);
|
||||
setActiveCh(c.id);
|
||||
setCurrentProc(resolveChannelPm2(c));
|
||||
},
|
||||
[active, activeUrlDirty, mode, channels, proUrlDraft, setCurrentProc, persistChannels],
|
||||
[active, applyProUrlDraft, mode, channels, setCurrentProc, persistChannels],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -730,62 +766,36 @@ export function LiveYoutubeUnmannedView({
|
||||
setCurrentProc(want);
|
||||
}, [mode, activeCh, channels, setCurrentProc]);
|
||||
|
||||
useEffect(() => {
|
||||
if (mode !== "pro" || !currentProc || !activeCh) return;
|
||||
let cancelled = false;
|
||||
const targetChannelId = activeCh;
|
||||
void (async () => {
|
||||
try {
|
||||
const data = await fetchJson<{ content?: string }>(
|
||||
`/get_url_config?process=${encodeURIComponent(currentProc)}`,
|
||||
);
|
||||
if (cancelled || urlListDirtyRef.current) return;
|
||||
const c = data.content ?? "";
|
||||
const localDraft = channels.find((row) => row.id === targetChannelId)?.urlLines ?? "";
|
||||
if (shouldPreserveLocalUrlDraft(localDraft, c)) {
|
||||
setProUrlDraft(localDraft);
|
||||
return;
|
||||
}
|
||||
setProUrlDraft(c);
|
||||
urlListDirtyRef.current = false;
|
||||
setChannels((prev) => {
|
||||
const next = prev.map((x) => (x.id === targetChannelId ? { ...x, urlLines: c } : x));
|
||||
saveYoutubeProChannels(next);
|
||||
return next;
|
||||
});
|
||||
} catch {
|
||||
if (!cancelled && !urlListDirtyRef.current) {
|
||||
setProUrlDraft(activeSavedUrlDraft);
|
||||
}
|
||||
}
|
||||
})();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [activeCh, activeSavedUrlDraft, channels, currentProc, fetchJson, mode]);
|
||||
|
||||
const loadYoutubeIni = useCallback(async () => {
|
||||
if (!currentProc) return;
|
||||
const targetProc = currentProcRef.current.trim();
|
||||
if (!targetProc) return;
|
||||
const requestId = ++ytIniRequestSeqRef.current;
|
||||
setYtIniLoading(true);
|
||||
setYtIniStatus(null);
|
||||
try {
|
||||
const data = await fetchJson<{ content?: string }>(
|
||||
`/get_config?process=${encodeURIComponent(currentProc)}`,
|
||||
`/get_config?process=${encodeURIComponent(targetProc)}`,
|
||||
);
|
||||
if (requestId !== ytIniRequestSeqRef.current || targetProc !== currentProcRef.current.trim()) return;
|
||||
const text = data.content ?? "";
|
||||
setYoutubeIniText(text);
|
||||
setYtFields(parseYoutubeIniFields(text));
|
||||
} catch (e) {
|
||||
if (requestId !== ytIniRequestSeqRef.current || targetProc !== currentProcRef.current.trim()) return;
|
||||
setYtIniStatus((e as Error).message);
|
||||
} finally {
|
||||
setYtIniLoading(false);
|
||||
if (requestId === ytIniRequestSeqRef.current && targetProc === currentProcRef.current.trim()) {
|
||||
setYtIniLoading(false);
|
||||
}
|
||||
}
|
||||
}, [currentProc, fetchJson]);
|
||||
}, [fetchJson]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentProc) return;
|
||||
void pullUrlConfigFromServer();
|
||||
void loadYoutubeIni();
|
||||
}, [currentProc, loadYoutubeIni]);
|
||||
setActiveViewRefreshToken((prev) => prev + 1);
|
||||
}, [activeCh, currentProc, loadYoutubeIni, mode, pullUrlConfigFromServer]);
|
||||
|
||||
const persistActiveLaneDraft = useCallback(
|
||||
async () => {
|
||||
@@ -795,6 +805,7 @@ export function LiveYoutubeUnmannedView({
|
||||
if (!activeLaneValidation.ok) {
|
||||
throw new Error(activeLaneValidation.message);
|
||||
}
|
||||
const latestProUrlDraft = proUrlDraftRef.current;
|
||||
const next = channels.map((row) =>
|
||||
row.id === active.id
|
||||
? {
|
||||
@@ -803,7 +814,7 @@ export function LiveYoutubeUnmannedView({
|
||||
streamKey: activeLaneValidation.normalizedStreamKey,
|
||||
pm2Name: activeLaneValidation.normalizedPm2,
|
||||
notes: activeLaneValidation.normalizedNotes,
|
||||
urlLines: proUrlDraft,
|
||||
urlLines: latestProUrlDraft,
|
||||
}
|
||||
: row,
|
||||
);
|
||||
@@ -828,7 +839,7 @@ export function LiveYoutubeUnmannedView({
|
||||
streamKey: activeLaneValidation.normalizedStreamKey,
|
||||
pm2Name: activeLaneValidation.normalizedPm2,
|
||||
notes: activeLaneValidation.normalizedNotes,
|
||||
urlLines: proUrlDraft,
|
||||
urlLines: latestProUrlDraft,
|
||||
} satisfies YoutubeProChannel),
|
||||
pm2: activeLaneValidation.normalizedPm2,
|
||||
};
|
||||
@@ -839,7 +850,6 @@ export function LiveYoutubeUnmannedView({
|
||||
activeLaneValidation,
|
||||
applyChannelsLocal,
|
||||
channels,
|
||||
proUrlDraft,
|
||||
syncChannelsRemote,
|
||||
t,
|
||||
],
|
||||
@@ -933,9 +943,10 @@ export function LiveYoutubeUnmannedView({
|
||||
try {
|
||||
setLaneSaving(true);
|
||||
setLaneStatus(null);
|
||||
const latestProUrlDraft = proUrlDraftRef.current;
|
||||
const saved = await persistActiveLaneDraft();
|
||||
setCurrentProc(saved.pm2);
|
||||
await Promise.resolve(onSaveUrlConfig(proUrlDraft, saved.pm2));
|
||||
await Promise.resolve(onSaveUrlConfig(latestProUrlDraft, saved.pm2));
|
||||
urlListDirtyRef.current = false;
|
||||
setLaneStatus(t("线路与地址已保存", "Lane settings and URLs saved"));
|
||||
} catch (e) {
|
||||
@@ -948,8 +959,13 @@ export function LiveYoutubeUnmannedView({
|
||||
};
|
||||
|
||||
const saveSingleUrlAndClearDirty = async () => {
|
||||
const targetPm2 = currentProc.trim();
|
||||
if (!targetPm2) {
|
||||
notify(t("请选择进程", "Pick a process"));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await Promise.resolve(onSaveUrlConfig());
|
||||
await Promise.resolve(onSaveUrlConfig(singleUrlDraftRef.current, targetPm2));
|
||||
urlListDirtyRef.current = false;
|
||||
} catch {
|
||||
/* parent 已 toast */
|
||||
@@ -957,7 +973,7 @@ export function LiveYoutubeUnmannedView({
|
||||
};
|
||||
|
||||
const dedupeUrlDraft = async () => {
|
||||
const source = mode === "single" ? urlConfig : proUrlDraft;
|
||||
const source = mode === "single" ? singleUrlDraftRef.current : proUrlDraftRef.current;
|
||||
setUrlOptimizing(true);
|
||||
setUrlFetchNote(null);
|
||||
try {
|
||||
@@ -972,9 +988,9 @@ export function LiveYoutubeUnmannedView({
|
||||
}),
|
||||
});
|
||||
const next = data.content ?? source;
|
||||
if (mode === "single") setUrlConfig(next);
|
||||
if (mode === "single") applySingleUrlDraft(next);
|
||||
else {
|
||||
setProUrlDraft(next);
|
||||
applyProUrlDraft(next);
|
||||
}
|
||||
urlListDirtyRef.current = true;
|
||||
setUrlFetchNote(data.message || t("已去重当前 URL 列表", "Deduplicated current URL list"));
|
||||
@@ -1574,7 +1590,7 @@ export function LiveYoutubeUnmannedView({
|
||||
persistChannels([...channels, nc]);
|
||||
setActiveCh(id);
|
||||
setCurrentProc(resolveChannelPm2(nc));
|
||||
setProUrlDraft("");
|
||||
applyProUrlDraft("");
|
||||
}}
|
||||
>
|
||||
<Plus className="h-3.5 w-3.5" />
|
||||
@@ -1692,7 +1708,7 @@ export function LiveYoutubeUnmannedView({
|
||||
value={proUrlDraft}
|
||||
onChange={(e) => {
|
||||
urlListDirtyRef.current = true;
|
||||
setProUrlDraft(e.target.value);
|
||||
applyProUrlDraft(e.target.value);
|
||||
}}
|
||||
spellCheck={false}
|
||||
placeholder="https://live.douyin.com/..."
|
||||
@@ -1732,7 +1748,7 @@ export function LiveYoutubeUnmannedView({
|
||||
value={urlConfig}
|
||||
onChange={(e) => {
|
||||
urlListDirtyRef.current = true;
|
||||
setUrlConfig(e.target.value);
|
||||
applySingleUrlDraft(e.target.value);
|
||||
}}
|
||||
spellCheck={false}
|
||||
/>
|
||||
@@ -1755,6 +1771,7 @@ export function LiveYoutubeUnmannedView({
|
||||
keySuffixUi={keySuffixUi}
|
||||
showKeyRow
|
||||
pollMs={800}
|
||||
refreshToken={activeViewRefreshToken}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,6 +2,6 @@
|
||||
3:I[3946,["500","static/chunks/500-ea37cc8de90441f7.js","246","static/chunks/246-fafe28420dae1d39.js","357","static/chunks/app/android/page-84550dabda18d658.js"],"default",1]
|
||||
4:I[4707,[],""]
|
||||
5:I[6423,[],""]
|
||||
0:["nIVEbaa7YzQOC_jRgGVnk",[[["",{"children":["android",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["android",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","android","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/91df3d4117d74443.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"zh-CN","data-theme":"dark","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__variable_1e4310 __variable_c3aa02 font-sans antialiased","children":[["$","div",null,{"className":"app-bg-layer","aria-hidden":true}],["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]]}]}]],null],null],["$L6",null]]]]
|
||||
0:["X6fD94e2JgU55NfU1XPEM",[[["",{"children":["android",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["android",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","android","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/91df3d4117d74443.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"zh-CN","data-theme":"dark","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__variable_1e4310 __variable_c3aa02 font-sans antialiased","children":[["$","div",null,{"className":"app-bg-layer","aria-hidden":true}],["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]]}]}]],null],null],["$L6",null]]]]
|
||||
6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"无人直播系统 · live.local"}],["$","meta","3",{"name":"description","content":"Linux ARM/x86 一键部署的无人直播控制台:YouTube 转播、TikTok HDMI、SRS、Neko 与系统服务"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]]
|
||||
1:null
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2,6 +2,6 @@
|
||||
3:I[6367,["500","static/chunks/500-ea37cc8de90441f7.js","246","static/chunks/246-fafe28420dae1d39.js","443","static/chunks/app/console/page-75d851a154677dbc.js"],"default",1]
|
||||
4:I[4707,[],""]
|
||||
5:I[6423,[],""]
|
||||
0:["nIVEbaa7YzQOC_jRgGVnk",[[["",{"children":["console",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["console",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","console","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/91df3d4117d74443.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"zh-CN","data-theme":"dark","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__variable_1e4310 __variable_c3aa02 font-sans antialiased","children":[["$","div",null,{"className":"app-bg-layer","aria-hidden":true}],["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]]}]}]],null],null],["$L6",null]]]]
|
||||
0:["X6fD94e2JgU55NfU1XPEM",[[["",{"children":["console",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["console",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","console","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/91df3d4117d74443.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"zh-CN","data-theme":"dark","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__variable_1e4310 __variable_c3aa02 font-sans antialiased","children":[["$","div",null,{"className":"app-bg-layer","aria-hidden":true}],["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]]}]}]],null],null],["$L6",null]]]]
|
||||
6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"无人直播系统 · live.local"}],["$","meta","3",{"name":"description","content":"Linux ARM/x86 一键部署的无人直播控制台:YouTube 转播、TikTok HDMI、SRS、Neko 与系统服务"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]]
|
||||
1:null
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
||||
2:I[9107,[],"ClientPageRoot"]
|
||||
3:I[1499,["500","static/chunks/500-ea37cc8de90441f7.js","719","static/chunks/719-4dbe9dca4cff8afd.js","246","static/chunks/246-fafe28420dae1d39.js","931","static/chunks/app/page-a22341e1f7071ab6.js"],"default",1]
|
||||
3:I[1499,["500","static/chunks/500-ea37cc8de90441f7.js","719","static/chunks/719-4dbe9dca4cff8afd.js","246","static/chunks/246-fafe28420dae1d39.js","931","static/chunks/app/page-0c50020a1b5ffe1d.js"],"default",1]
|
||||
4:I[4707,[],""]
|
||||
5:I[6423,[],""]
|
||||
0:["nIVEbaa7YzQOC_jRgGVnk",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/91df3d4117d74443.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"zh-CN","data-theme":"dark","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__variable_1e4310 __variable_c3aa02 font-sans antialiased","children":[["$","div",null,{"className":"app-bg-layer","aria-hidden":true}],["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]]}]}]],null],null],["$L6",null]]]]
|
||||
0:["X6fD94e2JgU55NfU1XPEM",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/91df3d4117d74443.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"zh-CN","data-theme":"dark","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__variable_1e4310 __variable_c3aa02 font-sans antialiased","children":[["$","div",null,{"className":"app-bg-layer","aria-hidden":true}],["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]]}]}]],null],null],["$L6",null]]]]
|
||||
6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"无人直播系统 · live.local"}],["$","meta","3",{"name":"description","content":"Linux ARM/x86 一键部署的无人直播控制台:YouTube 转播、TikTok HDMI、SRS、Neko 与系统服务"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]]
|
||||
1:null
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2,6 +2,6 @@
|
||||
3:I[3398,["500","static/chunks/500-ea37cc8de90441f7.js","246","static/chunks/246-fafe28420dae1d39.js","6","static/chunks/app/shellcrash/page-3d8615ae919b9119.js"],"default",1]
|
||||
4:I[4707,[],""]
|
||||
5:I[6423,[],""]
|
||||
0:["nIVEbaa7YzQOC_jRgGVnk",[[["",{"children":["shellcrash",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["shellcrash",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","shellcrash","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/91df3d4117d74443.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"zh-CN","data-theme":"dark","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__variable_1e4310 __variable_c3aa02 font-sans antialiased","children":[["$","div",null,{"className":"app-bg-layer","aria-hidden":true}],["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]]}]}]],null],null],["$L6",null]]]]
|
||||
0:["X6fD94e2JgU55NfU1XPEM",[[["",{"children":["shellcrash",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["shellcrash",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","shellcrash","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/91df3d4117d74443.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"zh-CN","data-theme":"dark","suppressHydrationWarning":true,"children":["$","body",null,{"className":"__variable_1e4310 __variable_c3aa02 font-sans antialiased","children":[["$","div",null,{"className":"app-bg-layer","aria-hidden":true}],["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]]}]}]],null],null],["$L6",null]]]]
|
||||
6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"无人直播系统 · live.local"}],["$","meta","3",{"name":"description","content":"Linux ARM/x86 一键部署的无人直播控制台:YouTube 转播、TikTok HDMI、SRS、Neko 与系统服务"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]]
|
||||
1:null
|
||||
|
||||
Reference in New Issue
Block a user