From 4f682857acbe528f5c473b1a457265731e7139fc Mon Sep 17 00:00:00 2001 From: "Moon.eth" Date: Wed, 29 Jul 2026 12:44:15 +0900 Subject: [PATCH] refresh --- src/App.svelte | 3 ++ src/components/common/RefreshHotkey.svelte | 43 +++++++++++++++++++++ src/components/common/RefreshHotkey.test.ts | 36 +++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 src/components/common/RefreshHotkey.svelte create mode 100644 src/components/common/RefreshHotkey.test.ts diff --git a/src/App.svelte b/src/App.svelte index 29e6e9e..c5b0462 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -6,6 +6,7 @@ import SiteHeader from '$components/chrome/SiteHeader.svelte' import SiteNav from '$components/chrome/SiteNav.svelte' import SiteFooter from '$components/chrome/SiteFooter.svelte' + import RefreshHotkey from '$components/common/RefreshHotkey.svelte' import Home from '$routes/Home.svelte' import Profile from '$routes/Profile.svelte' import Timeline from '$routes/Timeline.svelte' @@ -56,6 +57,8 @@ ) + +
diff --git a/src/components/common/RefreshHotkey.svelte b/src/components/common/RefreshHotkey.svelte new file mode 100644 index 0000000..e416436 --- /dev/null +++ b/src/components/common/RefreshHotkey.svelte @@ -0,0 +1,43 @@ + + + diff --git a/src/components/common/RefreshHotkey.test.ts b/src/components/common/RefreshHotkey.test.ts new file mode 100644 index 0000000..486fb18 --- /dev/null +++ b/src/components/common/RefreshHotkey.test.ts @@ -0,0 +1,36 @@ +import { fireEvent, render } from '@testing-library/svelte' +import { describe, expect, it, vi } from 'vitest' +import RefreshHotkey from './RefreshHotkey.svelte' + +describe('RefreshHotkey', () => { + it('refreshes for Shift+R from anywhere on the page', async () => { + const onrefresh = vi.fn() + render(RefreshHotkey, { props: { onrefresh } }) + + const event = new KeyboardEvent('keydown', { + key: 'R', + shiftKey: true, + bubbles: true, + cancelable: true, + }) + window.dispatchEvent(event) + + expect(onrefresh).toHaveBeenCalledOnce() + expect(event.defaultPrevented).toBe(true) + }) + + it('ignores typing, repeats, and other modifier combinations', async () => { + const onrefresh = vi.fn() + render(RefreshHotkey, { props: { onrefresh } }) + const input = document.createElement('input') + document.body.append(input) + + await fireEvent.keyDown(input, { key: 'R', shiftKey: true }) + await fireEvent.keyDown(window, { key: 'r' }) + await fireEvent.keyDown(window, { key: 'R', shiftKey: true, repeat: true }) + await fireEvent.keyDown(window, { key: 'R', shiftKey: true, ctrlKey: true }) + await fireEvent.keyDown(window, { key: 'R', shiftKey: true, metaKey: true }) + + expect(onrefresh).not.toHaveBeenCalled() + }) +})