|
|
@@ -190,16 +190,24 @@ function VideoRow({
|
|
|
<div className="wt-branch" role="treeitem" aria-expanded={hasRoutes ? open : undefined}>
|
|
|
<div className={`wt-row video ${tone}`}>
|
|
|
<Toggle open={open} disabled={!hasRoutes} onClick={() => onToggle(node.key)} />
|
|
|
- <button type="button" className="wt-row-main" onClick={() => onOpenDrawer(videoDrawer(node))}>
|
|
|
- <span className={`wt-dot ${tone}`} />
|
|
|
- {depth === 0 && hideRootIndex ? null : (
|
|
|
- <span className="wt-kicker">{depth === 0 ? `起点 ${(index ?? 0) + 1}` : "游走到的"}</span>
|
|
|
- )}
|
|
|
- <span className="wt-title">{node.title}</span>
|
|
|
+ <div className="wt-row-main">
|
|
|
+ <button
|
|
|
+ type="button"
|
|
|
+ className="wt-summary-trigger"
|
|
|
+ onClick={() => onOpenDrawer(videoDrawer(node))}
|
|
|
+ aria-label={`查看摘要:${node.title}`}
|
|
|
+ title="查看摘要"
|
|
|
+ >
|
|
|
+ <span className={`wt-dot ${tone}`} />
|
|
|
+ {depth === 0 && hideRootIndex ? null : (
|
|
|
+ <span className="wt-kicker">{depth === 0 ? `起点 ${(index ?? 0) + 1}` : "游走到的"}</span>
|
|
|
+ )}
|
|
|
+ </button>
|
|
|
+ <VideoTitleLink runId={runId} video={node.video} title={node.title} />
|
|
|
<span className="wt-author">{node.author}</span>
|
|
|
{node.score ? <span className="wt-score">{node.score}</span> : null}
|
|
|
<span className={`wt-status ${tone}`}>{node.decisionLabel}</span>
|
|
|
- </button>
|
|
|
+ </div>
|
|
|
<span className="wt-row-right">
|
|
|
{hasRoutes ? (
|
|
|
<span className={`wt-badge ${walked ? "go" : "stop"}`}>
|
|
|
@@ -304,15 +312,13 @@ function Toggle({ open, disabled, onClick }: { open: boolean; disabled: boolean;
|
|
|
}
|
|
|
|
|
|
function RowLinks({ video, runId }: { video: RawRecord; runId: string }) {
|
|
|
- // platform content ids (视频号 finder ids) can contain / + = which break path routing;
|
|
|
- // prefer the clean content_discovery_id for the detail route.
|
|
|
- const detailId = maybeText(video.content_discovery_id) || text(video.id, "");
|
|
|
- if (!detailId) return null;
|
|
|
+ const detailHref = videoDetailHref(runId, video);
|
|
|
+ if (!detailHref) return null;
|
|
|
const platformUrl = text(video.platform_url, "");
|
|
|
const platformLabel = text(video.platform_label, "原视频");
|
|
|
return (
|
|
|
<span className="wt-links">
|
|
|
- <Link className="wt-link" href={`/runs/${encodeURIComponent(runId)}/videos/${encodeURIComponent(detailId)}`} onClick={(e) => e.stopPropagation()}>
|
|
|
+ <Link className="wt-link" href={detailHref} onClick={(e) => e.stopPropagation()}>
|
|
|
详情
|
|
|
</Link>
|
|
|
{platformUrl ? (
|
|
|
@@ -325,6 +331,25 @@ function RowLinks({ video, runId }: { video: RawRecord; runId: string }) {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+function VideoTitleLink({ runId, video, title }: { runId: string; video: RawRecord; title: string }) {
|
|
|
+ const detailHref = videoDetailHref(runId, video);
|
|
|
+ if (!detailHref) return <span className="wt-title">{title}</span>;
|
|
|
+ return (
|
|
|
+ <Link className="wt-title wt-title-link" href={detailHref}>
|
|
|
+ {title}
|
|
|
+ </Link>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+function videoDetailHref(runId: string, video: RawRecord): string {
|
|
|
+ // platform content ids (视频号 finder ids) can contain / + = which break path routing;
|
|
|
+ // prefer the clean content_discovery_id for the detail route.
|
|
|
+ const detailId = maybeText(video.content_discovery_id) || text(video.id, "");
|
|
|
+ return detailId
|
|
|
+ ? `/runs/${encodeURIComponent(runId)}/videos/${encodeURIComponent(detailId)}`
|
|
|
+ : "";
|
|
|
+}
|
|
|
+
|
|
|
// ---------------------------------------------------------------------------
|
|
|
// build
|
|
|
// ---------------------------------------------------------------------------
|