mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-16 03:52:09 +03:00
Send content ref to get page changes for free
This commit is contained in:
parent
9096f113c1
commit
7614e6435d
@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect } from "react";
|
||||
import { MutableRefObject, useCallback, useEffect, useMemo } from "react";
|
||||
|
||||
export type KeyModifiers = {
|
||||
down: boolean;
|
||||
@ -9,8 +9,17 @@ export type KeyModifiers = {
|
||||
|
||||
export default function useKeyboardListener(
|
||||
keys: string[],
|
||||
listener: (key: string | null, modifiers: KeyModifiers) => boolean,
|
||||
listener?: (key: string | null, modifiers: KeyModifiers) => boolean,
|
||||
contentRef?: MutableRefObject<HTMLDivElement | null>,
|
||||
) {
|
||||
const pageKeys = useMemo(
|
||||
() =>
|
||||
contentRef != undefined
|
||||
? ["ArrowDown", "ArrowUp", "PageDown", "PageUp"]
|
||||
: [],
|
||||
[contentRef],
|
||||
);
|
||||
|
||||
const keyDownListener = useCallback(
|
||||
(e: KeyboardEvent) => {
|
||||
// @ts-expect-error we know this field exists
|
||||
@ -25,14 +34,44 @@ export default function useKeyboardListener(
|
||||
shift: e.shiftKey,
|
||||
};
|
||||
|
||||
if (keys.includes(e.key)) {
|
||||
if (contentRef && pageKeys.includes(e.key)) {
|
||||
switch (e.key) {
|
||||
case "ArrowDown":
|
||||
contentRef.current?.scrollBy({
|
||||
top: 100,
|
||||
behavior: "smooth",
|
||||
});
|
||||
break;
|
||||
case "ArrowUp":
|
||||
contentRef.current?.scrollBy({
|
||||
top: -100,
|
||||
behavior: "smooth",
|
||||
});
|
||||
break;
|
||||
case "PageDown":
|
||||
contentRef.current?.scrollBy({
|
||||
top: contentRef.current.clientHeight / 2,
|
||||
behavior: "smooth",
|
||||
});
|
||||
break;
|
||||
case "PageUp":
|
||||
contentRef.current?.scrollBy({
|
||||
top: -contentRef.current.clientHeight / 2,
|
||||
behavior: "smooth",
|
||||
});
|
||||
break;
|
||||
}
|
||||
} else if (keys.includes(e.key) && listener) {
|
||||
const preventDefault = listener(e.key, modifiers);
|
||||
if (preventDefault) e.preventDefault();
|
||||
} else if (e.key === "Shift" || e.key === "Control" || e.key === "Meta") {
|
||||
} else if (
|
||||
listener &&
|
||||
(e.key === "Shift" || e.key === "Control" || e.key === "Meta")
|
||||
) {
|
||||
listener(null, modifiers);
|
||||
}
|
||||
},
|
||||
[keys, listener],
|
||||
[keys, pageKeys, listener, contentRef],
|
||||
);
|
||||
|
||||
const keyUpListener = useCallback(
|
||||
@ -48,10 +87,13 @@ export default function useKeyboardListener(
|
||||
shift: false,
|
||||
};
|
||||
|
||||
if (keys.includes(e.key)) {
|
||||
e.preventDefault();
|
||||
listener(e.key, modifiers);
|
||||
} else if (e.key === "Shift" || e.key === "Control" || e.key === "Meta") {
|
||||
if (listener && keys.includes(e.key)) {
|
||||
const preventDefault = listener(e.key, modifiers);
|
||||
if (preventDefault) e.preventDefault();
|
||||
} else if (
|
||||
listener &&
|
||||
(e.key === "Shift" || e.key === "Control" || e.key === "Meta")
|
||||
) {
|
||||
listener(null, modifiers);
|
||||
}
|
||||
},
|
||||
|
||||
@ -113,43 +113,7 @@ function Exports() {
|
||||
// Keyboard Listener
|
||||
|
||||
const contentRef = useRef<HTMLDivElement | null>(null);
|
||||
useKeyboardListener(
|
||||
["ArrowDown", "ArrowUp", "PageDown", "PageUp"],
|
||||
(key, modifiers) => {
|
||||
if (!modifiers.down) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case "ArrowDown":
|
||||
contentRef.current?.scrollBy({
|
||||
top: 100,
|
||||
behavior: "smooth",
|
||||
});
|
||||
break;
|
||||
case "ArrowUp":
|
||||
contentRef.current?.scrollBy({
|
||||
top: -100,
|
||||
behavior: "smooth",
|
||||
});
|
||||
break;
|
||||
case "PageDown":
|
||||
contentRef.current?.scrollBy({
|
||||
top: contentRef.current.clientHeight / 2,
|
||||
behavior: "smooth",
|
||||
});
|
||||
break;
|
||||
case "PageUp":
|
||||
contentRef.current?.scrollBy({
|
||||
top: -contentRef.current.clientHeight / 2,
|
||||
behavior: "smooth",
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
);
|
||||
useKeyboardListener([], undefined, contentRef);
|
||||
|
||||
return (
|
||||
<div className="flex size-full flex-col gap-2 overflow-hidden px-1 pt-2 md:p-2">
|
||||
|
||||
@ -270,7 +270,7 @@ export default function FaceLibrary() {
|
||||
|
||||
const contentRef = useRef<HTMLDivElement | null>(null);
|
||||
useKeyboardListener(
|
||||
["a", "Escape", "ArrowDown", "ArrowUp", "PageDown", "PageUp"],
|
||||
["a", "Escape"],
|
||||
(key, modifiers) => {
|
||||
if (!modifiers.down) {
|
||||
return true;
|
||||
@ -293,34 +293,11 @@ export default function FaceLibrary() {
|
||||
case "Escape":
|
||||
setSelectedFaces([]);
|
||||
return true;
|
||||
case "ArrowDown":
|
||||
contentRef.current?.scrollBy({
|
||||
top: 100,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
case "ArrowUp":
|
||||
contentRef.current?.scrollBy({
|
||||
top: -100,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
case "PageDown":
|
||||
contentRef.current?.scrollBy({
|
||||
top: contentRef.current.clientHeight / 2,
|
||||
behavior: "smooth",
|
||||
});
|
||||
break;
|
||||
case "PageUp":
|
||||
contentRef.current?.scrollBy({
|
||||
top: -contentRef.current.clientHeight / 2,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
contentRef,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@ -235,7 +235,7 @@ export default function ModelTrainingView({ model }: ModelTrainingViewProps) {
|
||||
|
||||
const contentRef = useRef<HTMLDivElement | null>(null);
|
||||
useKeyboardListener(
|
||||
["a", "Escape", "ArrowDown", "ArrowUp", "PageDown", "PageUp"],
|
||||
["a", "Escape"],
|
||||
(key, modifiers) => {
|
||||
if (!modifiers.down) {
|
||||
return true;
|
||||
@ -259,34 +259,11 @@ export default function ModelTrainingView({ model }: ModelTrainingViewProps) {
|
||||
case "Escape":
|
||||
setSelectedImages([]);
|
||||
return true;
|
||||
case "ArrowDown":
|
||||
contentRef.current?.scrollBy({
|
||||
top: 100,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
case "ArrowUp":
|
||||
contentRef.current?.scrollBy({
|
||||
top: -100,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
case "PageDown":
|
||||
contentRef.current?.scrollBy({
|
||||
top: contentRef.current.clientHeight / 2,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
case "PageUp":
|
||||
contentRef.current?.scrollBy({
|
||||
top: -contentRef.current.clientHeight / 2,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
contentRef,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@ -651,7 +651,7 @@ function DetectionReview({
|
||||
// keyboard
|
||||
|
||||
useKeyboardListener(
|
||||
["a", "r", "Escape", "ArrowDown", "ArrowUp", "PageDown", "PageUp"],
|
||||
["a", "r", "Escape"],
|
||||
(key, modifiers) => {
|
||||
if (!modifiers.down) {
|
||||
return true;
|
||||
@ -679,34 +679,11 @@ function DetectionReview({
|
||||
case "Escape":
|
||||
setSelectedReviews([]);
|
||||
return true;
|
||||
case "ArrowDown":
|
||||
contentRef.current?.scrollBy({
|
||||
top: 100,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
case "ArrowUp":
|
||||
contentRef.current?.scrollBy({
|
||||
top: -100,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
case "PageDown":
|
||||
contentRef.current?.scrollBy({
|
||||
top: contentRef.current.clientHeight / 2,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
case "PageUp":
|
||||
contentRef.current?.scrollBy({
|
||||
top: -contentRef.current.clientHeight / 2,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
contentRef,
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@ -359,30 +359,6 @@ export default function SearchView({
|
||||
setSearchDetail(uniqueResults[newIndex]);
|
||||
}
|
||||
return true;
|
||||
case "ArrowDown":
|
||||
contentRef.current?.scrollBy({
|
||||
top: 100,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
case "ArrowUp":
|
||||
contentRef.current?.scrollBy({
|
||||
top: -100,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
case "PageDown":
|
||||
contentRef.current?.scrollBy({
|
||||
top: contentRef.current.clientHeight / 2,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
case "PageUp":
|
||||
contentRef.current?.scrollBy({
|
||||
top: -contentRef.current.clientHeight / 2,
|
||||
behavior: "smooth",
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -391,17 +367,9 @@ export default function SearchView({
|
||||
);
|
||||
|
||||
useKeyboardListener(
|
||||
[
|
||||
"a",
|
||||
"Escape",
|
||||
"ArrowDown",
|
||||
"ArrowLeft",
|
||||
"ArrowRight",
|
||||
"ArrowUp",
|
||||
"PageDown",
|
||||
"PageUp",
|
||||
],
|
||||
["a", "Escape", "ArrowLeft", "ArrowRight"],
|
||||
onKeyboardShortcut,
|
||||
contentRef,
|
||||
);
|
||||
|
||||
// scroll into view
|
||||
|
||||
Loading…
Reference in New Issue
Block a user