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()
+ })
+})