From 5bf745f45f829ebd2d19243d4051401435972180 Mon Sep 17 00:00:00 2001 From: kris Date: Sat, 11 Apr 2026 02:44:01 +0800 Subject: [PATCH] Hide pinned controls on Web conversations --- src/components/app-ui.tsx | 14 +++++------ tests/conversation-home-items.test.ts | 34 ++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/components/app-ui.tsx b/src/components/app-ui.tsx index 16bafc9..76b10d4 100644 --- a/src/components/app-ui.tsx +++ b/src/components/app-ui.tsx @@ -410,13 +410,17 @@ export function getConversationListItemPresentation(conversation: ConversationIt } export function getConversationActionAvailability(conversation: ConversationItem) { - const canTogglePin = conversation.projectId !== "master-agent"; return { - canTogglePin, + canTogglePin: false, togglePinLabel: conversation.topPinnedLabel || conversation.manualPinned ? "取消置顶" : "置顶", }; } +export function getConversationPinnedBadgeLabel(conversation: ConversationItem) { + void conversation; + return ""; +} + export function getConversationActionsPath(projectId: string) { return `/api/v1/conversations/${encodeURIComponent(projectId)}/actions`; } @@ -526,11 +530,7 @@ export function ConversationList({
- {conversation.projectId === "master-agent" - ? "置顶" - : conversation.topPinnedLabel - ? "置顶" - : ""} + {getConversationPinnedBadgeLabel(conversation)}
{conversation.latestReplyLabel}
{conversation.contextBudgetIndicator.visible && diff --git a/tests/conversation-home-items.test.ts b/tests/conversation-home-items.test.ts index ed29eac..84d23ea 100644 --- a/tests/conversation-home-items.test.ts +++ b/tests/conversation-home-items.test.ts @@ -15,6 +15,7 @@ let formatTimestampLabel: (typeof import("../src/lib/boss-projections"))["format let getConversationListItemPresentation: (typeof import("../src/components/app-ui"))["getConversationListItemPresentation"]; let getConversationActionAvailability: (typeof import("../src/components/app-ui"))["getConversationActionAvailability"]; let getConversationActionsPath: (typeof import("../src/components/app-ui"))["getConversationActionsPath"]; +let getConversationPinnedBadgeLabel: (typeof import("../src/components/app-ui"))["getConversationPinnedBadgeLabel"]; async function setup() { if (runtimeRoot) return; @@ -37,6 +38,7 @@ async function setup() { getConversationListItemPresentation = ui.getConversationListItemPresentation; getConversationActionAvailability = ui.getConversationActionAvailability; getConversationActionsPath = ui.getConversationActionsPath; + getConversationPinnedBadgeLabel = ui.getConversationPinnedBadgeLabel; } test.after(async () => { @@ -705,7 +707,7 @@ test("conversation home compacts imported previews and trims local workspace pre assert.equal(item?.lastMessagePreview, "已导入线程"); }); -test("folder archive homepage rows expose pin toggles when the folder is pinned", async () => { +test("folder archive homepage rows do not expose pin toggles in the Web surface", async () => { await setup(); const state = await readState(); @@ -738,8 +740,34 @@ test("folder archive homepage rows expose pin toggles when the folder is pinned" assert.ok(folder, "expected grouped folder archive item"); const actions = getConversationActionAvailability(folder!); - assert.equal(actions.canTogglePin, true); - assert.equal(actions.togglePinLabel, "取消置顶"); + assert.equal(actions.canTogglePin, false); +}); + +test("homepage rows do not expose pinned labels in the Web surface", async () => { + await setup(); + const state = await readState(); + + state.projects = state.projects.filter((project) => project.id === "master-agent"); + state.projects.push({ + ...buildImportedThreadProject( + "mac-studio", + "boss-thread-1", + "Boss", + "boss", + "归档确认", + "thread-1", + "2026-03-30T11:00:00+08:00", + ), + pinned: true, + }); + + const pinnedThread = getConversationHomeItems(state).find((item) => item.projectId === "boss-thread-1"); + assert.ok(pinnedThread, "expected pinned thread item"); + assert.equal(getConversationPinnedBadgeLabel(pinnedThread!), ""); + + const masterAgent = getConversationHomeItems(state).find((item) => item.projectId === "master-agent"); + assert.ok(masterAgent, "expected master agent item"); + assert.equal(getConversationPinnedBadgeLabel(masterAgent!), ""); }); test("folder archive action path encodes folder keys with nested path segments", async () => {