feat: 对话列表支持分页、收藏、置顶
收藏(is_favorite)/置顶(is_pinned)作为布尔标记存入对话已有 metadata,
复用现有 PATCH /api/threads/{id} 与 search 往返,无需后端改动与迁移。
- hooks: 新增 useUpdateThreadMetadata + useToggleThreadPin/Favorite
- utils: 新增 isThreadPinned/isThreadFavorite/sortThreadsPinnedFirst
- 侧边栏: 置顶优先排序 + 下拉菜单收藏/置顶项 + 置顶图标
- 对话页: 置顶区 + 全部/收藏过滤 + 页码翻页(每页20) + 行内收藏/置顶按钮
- i18n: zh-CN/en-US/types 新增相关文案
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
80d2db6315
commit
50d70a5050
7 files changed
+489
-139
No files matched your search
@@ -81,6 +81,28 @@ export function titleOfThread(thread: AgentThread, fallback = "Untitled") {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
export function isThreadPinned(thread: AgentThread): boolean {
|
||||
return (thread.metadata as Record<string, unknown> | null)?.is_pinned === true;
|
||||
}
|
||||
|
||||
export function isThreadFavorite(thread: AgentThread): boolean {
|
||||
return (thread.metadata as Record<string, unknown> | null)?.is_favorite === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stable sort that lifts pinned (置顶) threads to the top while preserving the
|
||||
* incoming order (typically `updated_at` desc) within both the pinned and the
|
||||
* unpinned group.
|
||||
*/
|
||||
export function sortThreadsPinnedFirst(threads: AgentThread[]): AgentThread[] {
|
||||
const pinned: AgentThread[] = [];
|
||||
const rest: AgentThread[] = [];
|
||||
for (const thread of threads) {
|
||||
(isThreadPinned(thread) ? pinned : rest).push(thread);
|
||||
}
|
||||
return [...pinned, ...rest];
|
||||
}
|
||||
|
||||
export function sanitizeThreadTitleForDisplay(title: string | null | undefined) {
|
||||
if (!title) return "Untitled";
|
||||
|
||||
|
||||
Reference in new issue
Block a user