Prevent cmd-k key listener interference
This commit is contained in:
parent
68775381d1
commit
25cb686ace
@ -94,11 +94,11 @@ export default function RootLayout({
|
||||
</main>
|
||||
<CommandK />
|
||||
</ThemeProviderClient>
|
||||
<Analytics debug={false} />
|
||||
<SpeedInsights debug={false} />
|
||||
<PhotoEscapeHandler />
|
||||
<ToasterWithThemes />
|
||||
</AppStateProvider>
|
||||
<Analytics />
|
||||
<SpeedInsights />
|
||||
<PhotoEscapeHandler />
|
||||
<ToasterWithThemes />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
@ -40,6 +40,7 @@ export default function CommandKClient({
|
||||
const {
|
||||
isCommandKOpen: isOpen,
|
||||
setIsCommandKOpen: setIsOpen,
|
||||
setShouldRespondToKeyboardCommands,
|
||||
} = useAppState();
|
||||
|
||||
const isOpenRef = useRef(isOpen);
|
||||
@ -103,12 +104,15 @@ export default function CommandKClient({
|
||||
}, [queryLive]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOpen) {
|
||||
if (isOpen) {
|
||||
setShouldRespondToKeyboardCommands?.(false);
|
||||
} else if (!isOpen) {
|
||||
setQueryLive('');
|
||||
setQueriedSections([]);
|
||||
setIsLoading(false);
|
||||
setTimeout(() => setShouldRespondToKeyboardCommands?.(true), 500);
|
||||
}
|
||||
}, [isOpen]);
|
||||
}, [isOpen, setShouldRespondToKeyboardCommands]);
|
||||
|
||||
const sectionTheme: CommandKSection = {
|
||||
heading: 'Theme',
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { getEscapePath } from '@/site/paths';
|
||||
import { useAppState } from '@/state';
|
||||
import { useRouter, usePathname } from 'next/navigation';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
@ -11,17 +12,21 @@ export default function PhotoEscapeHandler() {
|
||||
|
||||
const pathname = usePathname();
|
||||
|
||||
const { shouldRespondToKeyboardCommands } = useAppState();
|
||||
|
||||
const escapePath = getEscapePath(pathname);
|
||||
|
||||
useEffect(() => {
|
||||
const onKeyUp = (e: KeyboardEvent) => {
|
||||
if (e.key.toUpperCase() === 'ESCAPE' && escapePath) {
|
||||
router.push(escapePath, { scroll: false });
|
||||
if (shouldRespondToKeyboardCommands) {
|
||||
const onKeyUp = (e: KeyboardEvent) => {
|
||||
if (e.key.toUpperCase() === 'ESCAPE' && escapePath) {
|
||||
router.push(escapePath, { scroll: false });
|
||||
};
|
||||
};
|
||||
};
|
||||
window.addEventListener(LISTENER_KEYUP, onKeyUp);
|
||||
return () => window.removeEventListener(LISTENER_KEYUP, onKeyUp);
|
||||
}, [router, escapePath]);
|
||||
window.addEventListener(LISTENER_KEYUP, onKeyUp);
|
||||
return () => window.removeEventListener(LISTENER_KEYUP, onKeyUp);
|
||||
}
|
||||
}, [shouldRespondToKeyboardCommands, router, escapePath]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -30,40 +30,46 @@ export default function PhotoLinks({
|
||||
}) {
|
||||
const router = useRouter();
|
||||
|
||||
const { setNextPhotoAnimation } = useAppState();
|
||||
const {
|
||||
setNextPhotoAnimation,
|
||||
shouldRespondToKeyboardCommands,
|
||||
} = useAppState();
|
||||
|
||||
const previousPhoto = getPreviousPhoto(photo, photos);
|
||||
const nextPhoto = getNextPhoto(photo, photos);
|
||||
|
||||
useEffect(() => {
|
||||
const onKeyUp = (e: KeyboardEvent) => {
|
||||
switch (e.key.toUpperCase()) {
|
||||
case 'ARROWLEFT':
|
||||
case 'J':
|
||||
if (previousPhoto) {
|
||||
setNextPhotoAnimation?.(ANIMATION_RIGHT);
|
||||
router.push(
|
||||
pathForPhoto(previousPhoto, tag, camera, simulation),
|
||||
{ scroll: false },
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'ARROWRIGHT':
|
||||
case 'L':
|
||||
if (nextPhoto) {
|
||||
setNextPhotoAnimation?.(ANIMATION_LEFT);
|
||||
router.push(
|
||||
pathForPhoto(nextPhoto, tag, camera, simulation),
|
||||
{ scroll: false },
|
||||
);
|
||||
}
|
||||
break;
|
||||
if (shouldRespondToKeyboardCommands) {
|
||||
const onKeyUp = (e: KeyboardEvent) => {
|
||||
switch (e.key.toUpperCase()) {
|
||||
case 'ARROWLEFT':
|
||||
case 'J':
|
||||
if (previousPhoto) {
|
||||
setNextPhotoAnimation?.(ANIMATION_RIGHT);
|
||||
router.push(
|
||||
pathForPhoto(previousPhoto, tag, camera, simulation),
|
||||
{ scroll: false },
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'ARROWRIGHT':
|
||||
case 'L':
|
||||
if (nextPhoto) {
|
||||
setNextPhotoAnimation?.(ANIMATION_LEFT);
|
||||
router.push(
|
||||
pathForPhoto(nextPhoto, tag, camera, simulation),
|
||||
{ scroll: false },
|
||||
);
|
||||
}
|
||||
break;
|
||||
};
|
||||
};
|
||||
};
|
||||
window.addEventListener(LISTENER_KEYUP, onKeyUp);
|
||||
return () => window.removeEventListener(LISTENER_KEYUP, onKeyUp);
|
||||
window.addEventListener(LISTENER_KEYUP, onKeyUp);
|
||||
return () => window.removeEventListener(LISTENER_KEYUP, onKeyUp);
|
||||
}
|
||||
}, [
|
||||
router,
|
||||
shouldRespondToKeyboardCommands,
|
||||
setNextPhotoAnimation,
|
||||
previousPhoto,
|
||||
nextPhoto,
|
||||
|
||||
@ -17,6 +17,9 @@ export default function AppStateProvider({
|
||||
const [nextPhotoAnimation, setNextPhotoAnimation] =
|
||||
useState<AnimationConfig>();
|
||||
|
||||
const [shouldRespondToKeyboardCommands, setShouldRespondToKeyboardCommands] =
|
||||
useState(true);
|
||||
|
||||
const [isCommandKOpen, setIsCommandKOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@ -30,9 +33,11 @@ export default function AppStateProvider({
|
||||
hasLoaded,
|
||||
setHasLoaded,
|
||||
nextPhotoAnimation,
|
||||
setNextPhotoAnimation,
|
||||
shouldRespondToKeyboardCommands,
|
||||
setShouldRespondToKeyboardCommands,
|
||||
isCommandKOpen,
|
||||
setIsCommandKOpen,
|
||||
setNextPhotoAnimation,
|
||||
clearNextPhotoAnimation: () => setNextPhotoAnimation?.(undefined),
|
||||
}}
|
||||
>
|
||||
|
||||
@ -6,9 +6,11 @@ export interface AppStateContext {
|
||||
hasLoaded?: boolean
|
||||
setHasLoaded?: Dispatch<SetStateAction<boolean>>
|
||||
nextPhotoAnimation?: AnimationConfig
|
||||
setNextPhotoAnimation?: Dispatch<SetStateAction<AnimationConfig | undefined>>
|
||||
shouldRespondToKeyboardCommands?: boolean
|
||||
setShouldRespondToKeyboardCommands?: Dispatch<SetStateAction<boolean>>
|
||||
isCommandKOpen?: boolean
|
||||
setIsCommandKOpen?: Dispatch<SetStateAction<boolean>>
|
||||
setNextPhotoAnimation?: (animation?: AnimationConfig) => void
|
||||
clearNextPhotoAnimation?: () => void
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user