feat: 播放页按来源列表切换,新增作者/搜索/hashtag 侧栏
- 播放上下文:作品链接带上来源(搜索、标签、作者、hashtag),上一条/下一条 在该列表内移动;当前作品不在列表中时退回全部作品的发布时间顺序 - 顶部提示标签显示当前列表与位置,点击打开侧栏列表,✕ 退出 - 侧栏改为「评论 | TA的作品 | 搜索结果/#hashtag」标签页,作品封面网格可就地切换 - 作者模式:打开「TA的作品」进入,关闭侧栏不退出,点提示 ✕ 后回到原来的列表 - 从搜索结果进入或点 hashtag 时自动打开对应列表 - 描述中的 hashtag 可点击,按完整 hashtag 精确匹配(#丰川祥子 不含 #丰川祥子cos) - 新增 /api/playlist;搜索 SQL 抽到 lib/search-query.ts 与播放页共用,保证顺序一致 - 移动端:底部抽屉、点作品后收起,媒体区支持上下滑切换 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import { ChevronUp, ListVideo, X } from "lucide-react";
|
||||
import { memo } from "react";
|
||||
|
||||
interface ContextChipProps {
|
||||
label: string;
|
||||
position: number;
|
||||
total: number;
|
||||
/** 提供时整个标签可点:展开 / 打开侧栏里的完整列表 */
|
||||
onExpand?: () => void;
|
||||
expandLabel?: string;
|
||||
onExit: () => void;
|
||||
exitLabel: string;
|
||||
}
|
||||
|
||||
// 顶部的模式提示:说明上下切换当前在哪个列表里移动,避免「为什么跳到这里了」的困惑
|
||||
export const ContextChip = memo(function ContextChip({
|
||||
label,
|
||||
position,
|
||||
total,
|
||||
onExpand,
|
||||
expandLabel,
|
||||
onExit,
|
||||
exitLabel,
|
||||
}: ContextChipProps) {
|
||||
const content = (
|
||||
<>
|
||||
<ListVideo size={14} className="shrink-0 text-rose-300" />
|
||||
<span className="truncate">{label}</span>
|
||||
<span className="shrink-0 tabular-nums text-white/60">
|
||||
{position}/{total}
|
||||
</span>
|
||||
{onExpand && <ChevronUp size={14} className="shrink-0 text-white/70" />}
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="absolute left-1/2 top-14 z-40 flex max-w-[calc(100%-1.5rem)] sm:top-3 sm:max-w-[calc(100%-14rem)] -translate-x-1/2 items-center rounded-full border border-white/20 bg-black/60 text-xs font-medium text-white shadow-lg backdrop-blur">
|
||||
{onExpand ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onExpand}
|
||||
className="flex min-w-0 items-center gap-1.5 py-1.5 pl-3 pr-1 cursor-pointer"
|
||||
aria-label={expandLabel}
|
||||
title={expandLabel}
|
||||
>
|
||||
{content}
|
||||
</button>
|
||||
) : (
|
||||
<div className="flex min-w-0 items-center gap-1.5 py-1.5 pl-3 pr-1">
|
||||
{content}
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
onClick={onExit}
|
||||
className="mr-1 grid h-6 w-6 shrink-0 place-items-center rounded-full text-white/70 hover:bg-white/15 hover:text-white cursor-pointer"
|
||||
aria-label={exitLabel}
|
||||
title={exitLabel}
|
||||
>
|
||||
<X size={14} />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user