From 2fc982dbcec149869faf41a0840857e59329ba53 Mon Sep 17 00:00:00 2001 From: Yuwang Cai Date: Fri, 22 Nov 2024 16:28:56 +0800 Subject: [PATCH] fix: update clipboard text on going back to tab --- src/use-clipboard-text.ts | 6 +++++- tests/use-clipboard-text.test.ts | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/use-clipboard-text.ts b/src/use-clipboard-text.ts index eda8da5..15ea66a 100644 --- a/src/use-clipboard-text.ts +++ b/src/use-clipboard-text.ts @@ -79,7 +79,11 @@ export function useClipboardText(options: UseClipboardTextOptions = {}) { useDocumentEventListener("cut", read); useDocumentEventListener("copy", read); - // TODO: Visibility change event listener + useDocumentEventListener("visibilitychange", (_, document) => { + if (document.visibilityState === "visible") { + read(); + } + }); return { /** diff --git a/tests/use-clipboard-text.test.ts b/tests/use-clipboard-text.test.ts index 3ca55ba..68d934b 100644 --- a/tests/use-clipboard-text.test.ts +++ b/tests/use-clipboard-text.test.ts @@ -3,6 +3,7 @@ import { useClipboardText } from "src"; const mockReadText = vi.fn(); const mockWriteText = vi.fn(); +const mockVisibilityState = vi.spyOn(document, "visibilityState", "get"); beforeAll(() => { vi.stubGlobal("navigator", { @@ -125,6 +126,32 @@ it("listens to copy events", async () => { expect(mockReadText).toHaveBeenCalledTimes(2); }); +it("refreshes clipboard text when the user goes back to the tab", async () => { + mockReadText.mockResolvedValueOnce("hello").mockResolvedValueOnce("world"); + mockVisibilityState.mockReturnValue("visible"); + + const { result } = renderHook(() => useClipboardText()); + await waitFor(() => expect(result.current.text).not.toEqual("")); + + expect(result.current.text).toEqual("hello"); + expect(result.current.error).toEqual(null); + expect(mockReadText).toHaveBeenCalledTimes(1); + + mockVisibilityState.mockReturnValue("hidden"); + await act(async () => fireEvent(document, new Event("visibilitychange"))); + + expect(result.current.text).toEqual("hello"); + expect(result.current.error).toEqual(null); + expect(mockReadText).toHaveBeenCalledTimes(1); + + mockVisibilityState.mockReturnValue("visible"); + await act(async () => fireEvent(document, new Event("visibilitychange"))); + + expect(result.current.text).toEqual("world"); + expect(result.current.error).toEqual(null); + expect(mockReadText).toHaveBeenCalledTimes(2); +}); + it("recovers from error after any successful read", async () => { mockReadText .mockRejectedValueOnce(new Error("error"))