From 19981526c78fb2ff93c05b177021d189597982ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Chaonan=E2=80=9D?=
Date: Wed, 22 Jul 2026 15:05:54 +0800
Subject: [PATCH] fix: record prompt copy
---
.../src/entrypoints/popup/App.test.tsx | 4 +-
apps/extension/src/entrypoints/popup/App.tsx | 66 ++++++++++++-------
2 files changed, 45 insertions(+), 25 deletions(-)
diff --git a/apps/extension/src/entrypoints/popup/App.test.tsx b/apps/extension/src/entrypoints/popup/App.test.tsx
index 54062f0..155e7b6 100644
--- a/apps/extension/src/entrypoints/popup/App.test.tsx
+++ b/apps/extension/src/entrypoints/popup/App.test.tsx
@@ -199,7 +199,9 @@ describe("App", () => {
expect(copied).toContain("--browser 03c3e47f");
expect(copied).toContain('--purpose "发布 wiki 文档"');
expect(copied).not.toMatch(/bsk record start[^\n]*--url/);
- await waitFor(() => expect(copyButton.textContent).toContain("已复制"));
+ // Button label stays static; a transient toast confirms the copy.
+ expect(copyButton.textContent).toContain("复制录制指令");
+ await waitFor(() => expect(screen.getByRole("status").textContent).toContain("已复制"));
});
it("includes --url in record prompt when a start URL is provided", async () => {
diff --git a/apps/extension/src/entrypoints/popup/App.tsx b/apps/extension/src/entrypoints/popup/App.tsx
index 84166bb..6aee921 100644
--- a/apps/extension/src/entrypoints/popup/App.tsx
+++ b/apps/extension/src/entrypoints/popup/App.tsx
@@ -41,7 +41,10 @@ export function App() {
const [copiedInstanceId, setCopiedInstanceId] = useState(false);
const [purposeDraft, setPurposeDraft] = useState("");
const [startUrlDraft, setStartUrlDraft] = useState("");
- const [copiedPrompt, setCopiedPrompt] = useState(false);
+ // Bumped on every successful copy so the "copied" toast re-shows (and its
+ // auto-hide timer restarts) even when the copied content is unchanged.
+ const [copiedTick, setCopiedTick] = useState(0);
+ const showCopiedToast = copiedTick > 0;
useEffect(() => {
const query = window.matchMedia("(prefers-color-scheme: dark)");
@@ -56,9 +59,21 @@ export function App() {
useEffect(() => {
setCopiedInstanceId(false);
- setCopiedPrompt(false);
+ setCopiedTick(0);
}, [snapshot.instanceId]);
+ // Hide the copied toast when the command changes (topic / start URL edits).
+ useEffect(() => {
+ setCopiedTick(0);
+ }, [purposeDraft, startUrlDraft]);
+
+ // Auto-hide the copied toast shortly after it appears.
+ useEffect(() => {
+ if (copiedTick === 0) return;
+ const timer = window.setTimeout(() => setCopiedTick(0), 1500);
+ return () => window.clearTimeout(timer);
+ }, [copiedTick]);
+
const isSkewed = statusState === "version_skew";
const daemonVersion = snapshot.handshake?.version ?? "—";
const daemonProtocol = snapshot.handshake?.protocol_version ?? "—";
@@ -92,7 +107,7 @@ export function App() {
const copyRecordPrompt = async () => {
if (!recordReady || !navigator.clipboard?.writeText) return;
await navigator.clipboard.writeText(recordPrompt);
- setCopiedPrompt(true);
+ setCopiedTick((tick) => tick + 1);
};
const headerTitle =
@@ -338,29 +353,32 @@ export function App() {
{t("popup.record.hintDisconnected")}
)}
-