From fc60229755aa223e1e0da8703c053e14f6a7cdfe Mon Sep 17 00:00:00 2001 From: Frank Yang Date: Sun, 29 Mar 2026 15:22:46 +0800 Subject: [PATCH] fix(slack): restore debounced initial reaction --- .../status-reactions.slack-lifecycle.test.ts | 27 +++++++++++++++++++ src/channels/status-reactions.ts | 4 +-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/channels/status-reactions.slack-lifecycle.test.ts b/src/channels/status-reactions.slack-lifecycle.test.ts index 629ee773743..d20f192eca3 100644 --- a/src/channels/status-reactions.slack-lifecycle.test.ts +++ b/src/channels/status-reactions.slack-lifecycle.test.ts @@ -117,6 +117,33 @@ describe("Slack status reaction lifecycle", () => { expect(active.has(DEFAULT_EMOJIS.stallHard)).toBe(false); }); + it("restoreInitial still applies initial emoji when it is only debounced", async () => { + const { adapter, active } = createSlackMockAdapter(); + const ctrl = createStatusReactionController({ + enabled: true, + adapter, + initialEmoji: "eyes", + emojis: { thinking: "eyes" }, + timing: { debounceMs: 20, stallSoftMs: 99999, stallHardMs: 99999 }, + }); + + void ctrl.setQueued(); + await vi.advanceTimersByTimeAsync(1); + expect(active.has("eyes")).toBe(true); + + void ctrl.setTool("web_search"); + await vi.advanceTimersByTimeAsync(25); + expect(active.has(DEFAULT_EMOJIS.web)).toBe(true); + expect(active.has("eyes")).toBe(false); + + void ctrl.setThinking(); + await ctrl.restoreInitial(); + + expect(active.has("eyes")).toBe(true); + expect(active.has(DEFAULT_EMOJIS.web)).toBe(false); + expect(adapter.setReaction).toHaveBeenCalledTimes(3); + }); + it("does nothing when disabled", async () => { const { adapter, active } = createSlackMockAdapter(); const ctrl = createStatusReactionController({ diff --git a/src/channels/status-reactions.ts b/src/channels/status-reactions.ts index 475b4cd1f27..a7114c91c9c 100644 --- a/src/channels/status-reactions.ts +++ b/src/channels/status-reactions.ts @@ -380,9 +380,9 @@ export function createStatusReactionController(params: { } const alreadyInitial = currentEmoji === initialEmoji; - const initialAlreadyPending = pendingEmoji === initialEmoji; + const initialAlreadyQueuedImmediately = pendingEmoji === initialEmoji && debounceTimer === null; clearAllTimers(); - if (alreadyInitial || initialAlreadyPending) { + if (alreadyInitial || initialAlreadyQueuedImmediately) { pendingEmoji = ""; return; }