|
1 | 1 | import { StarIcon as StarIconOutline } from "@heroicons/react/24/outline"; |
2 | 2 | import { StarIcon as StarIconSolid } from "@heroicons/react/20/solid"; |
3 | 3 | import { useFetcher, useLocation, useSearchParams } from "@remix-run/react"; |
4 | | -import { useEffect, useRef } from "react"; |
| 4 | +import { useEffect } from "react"; |
5 | 5 | import { useIsImpersonating } from "~/hooks/useOrganizations"; |
| 6 | +import { useShortcutKeys } from "~/hooks/useShortcutKeys"; |
6 | 7 | import { useOptionalUser } from "~/hooks/useUser"; |
7 | 8 | import { cn } from "~/utils/cn"; |
8 | 9 | import { Button } from "../primitives/Buttons"; |
9 | 10 | import { ShortcutKey } from "../primitives/ShortcutKey"; |
10 | | -import { useShortcuts } from "../primitives/ShortcutsProvider"; |
11 | 11 | import { SimpleTooltip } from "../primitives/Tooltip"; |
12 | 12 | import { |
13 | 13 | buildFavoriteLabel, |
@@ -35,7 +35,6 @@ export function FavoritePageButton({ |
35 | 35 | const location = useLocation(); |
36 | 36 | const favorites = useFavorites(); |
37 | 37 | const fetcher = useFetcher(); |
38 | | - const { areShortcutsEnabled } = useShortcuts(); |
39 | 38 | const [, setSearchParams] = useSearchParams(); |
40 | 39 |
|
41 | 40 | // The marker param and pagination position never count toward URL identity, so paging through |
@@ -86,44 +85,19 @@ export function FavoritePageButton({ |
86 | 85 | } |
87 | 86 | }; |
88 | 87 |
|
89 | | - // The listener reads the latest toggle through a ref so it isn't re-attached every render |
90 | | - const toggleRef = useRef(toggle); |
91 | | - toggleRef.current = toggle; |
92 | | - |
93 | 88 | const showButton = user !== undefined && !isImpersonating; |
94 | 89 |
|
95 | | - useEffect(() => { |
96 | | - if (!showButton || !areShortcutsEnabled) return; |
97 | | - |
98 | | - const onKeyDown = (event: KeyboardEvent) => { |
99 | | - // Matched on `event.code`: on macOS, Option makes "F" report "ƒ" via `event.key`, so the |
100 | | - // event.key-based useShortcutKeys hook can't capture Option+letter (see GlobalShortcuts). |
101 | | - if ( |
102 | | - event.code !== "KeyF" || |
103 | | - !event.altKey || |
104 | | - event.metaKey || |
105 | | - event.ctrlKey || |
106 | | - event.shiftKey |
107 | | - ) { |
108 | | - return; |
109 | | - } |
110 | | - const target = event.target; |
111 | | - if ( |
112 | | - target instanceof HTMLElement && |
113 | | - (target.tagName === "INPUT" || |
114 | | - target.tagName === "TEXTAREA" || |
115 | | - target.tagName === "SELECT" || |
116 | | - target.isContentEditable) |
117 | | - ) { |
118 | | - return; |
119 | | - } |
| 90 | + // Option+F reports event.key "ƒ" on macOS, but the hotkeys matcher falls back to the physical |
| 91 | + // event.code ("KeyF"), so the standard hook captures it; exact modifier matching keeps the |
| 92 | + // bare "f" filter shortcut separate. |
| 93 | + useShortcutKeys({ |
| 94 | + shortcut: { key: "f", modifiers: ["alt"] }, |
| 95 | + action: (event) => { |
120 | 96 | event.preventDefault(); |
121 | | - toggleRef.current(); |
122 | | - }; |
123 | | - |
124 | | - document.addEventListener("keydown", onKeyDown); |
125 | | - return () => document.removeEventListener("keydown", onKeyDown); |
126 | | - }, [showButton, areShortcutsEnabled]); |
| 97 | + toggle(); |
| 98 | + }, |
| 99 | + disabled: !showButton, |
| 100 | + }); |
127 | 101 |
|
128 | 102 | if (!showButton) { |
129 | 103 | return null; |
|
0 commit comments