import { ArrowLeft, Hash, Search } from "lucide-react"; import Link from "next/link"; import { memo, useState } from "react"; import { playbackContextQuery } from "@/lib/playback-context"; import { type PlaylistState, usePlaylist } from "../hooks/usePlaylist"; import { useRelatedHashtags } from "../hooks/useRelatedHashtags"; import type { PlaybackContextInfo } from "../types.ts"; import { WorksGrid } from "./WorksGrid"; interface ContextListTabProps { active: boolean; context: PlaybackContextInfo; list: PlaylistState; currentId: string; contextQuery: string; /** hashtag 上下文时的 tag 名(用来取相关 tag) */ hashtagName: string | null; /** 对应的搜索结果页链接(搜索上下文才有) */ searchPageHref: string | null; onSelect: () => void; } // 侧栏的「搜索结果 / #hashtag / 标签」列表:和上下切换的顺序完全一致。 // hashtag 列表上方显示相关 tag(按共现计算);点相关 tag 只在侧栏里预览它的作品,不打断当前播放, // 在预览里点作品才切换到那个 tag 的列表。 export const ContextListTab = memo(function ContextListTab({ active, context, list, currentId, contextQuery, hashtagName, searchPageHref, onSelect, }: ContextListTabProps) { // 正在预览的相关 tag(null 表示显示当前列表本身) const [browsing, setBrowsing] = useState(null); const viewTag = browsing ?? hashtagName; const related = useRelatedHashtags(viewTag, active); const browseQuery = browsing ? playbackContextQuery({ kind: "hashtag", name: browsing }) : ""; const browseList = usePlaylist(browseQuery, active && Boolean(browsing)); const pickTag = (name: string) => { setBrowsing( name.toLowerCase() === hashtagName?.toLowerCase() ? null : name, ); }; const Icon = context.kind === "hashtag" ? Hash : Search; const header = browsing ? ( <>
#{browsing}
{related ? `共 ${related.count} 个 · ` : ""}点作品切换到这个 tag
) : ( <>
{context.label}
第 {context.position} 个 · 共 {context.total} 个
{searchPageHref && ( 在搜索页查看 )} ); const relatedRow = viewTag && related && related.related.length > 0 ? (
相关 {related.related.map((tag) => ( ))}
) : null; return ( ); });