mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-09-26 18:48:57 +03:00
Fixes (#18117)
* face library i18n fixes * face library i18n fixes * add ability to use ctrl/cmd S to save in the config editor * Use datetime as ID * Update metrics inference speed to start with 0 ms * fix android formatted thumbnail * ensure role is comma separated and stripped correctly * improve face library deletion - add a confirmation dialog - add ability to select all / delete faces in collections * Implement lazy loading for video previews * Force GPU for large embedding model * GPU is required * settings i18n fixes * Don't delete train tab * webpush debugging logs * Fix incorrectly copying zones * copy path data * Ensure that cache dir exists for Frigate+ * face docs update * Add description to upload image step to clarify the image * Clean up --------- Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
This commit is contained in:
co-authored by
Nicolas Mowen
parent
52d94231c7
commit
8094dd4075
@@ -385,6 +385,55 @@ export function RecordingView({
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [previewRowRef.current?.scrollWidth, previewRowRef.current?.scrollHeight]);
|
||||
|
||||
// visibility listener for lazy loading
|
||||
|
||||
const [visiblePreviews, setVisiblePreviews] = useState<string[]>([]);
|
||||
const visiblePreviewObserver = useRef<IntersectionObserver | null>(null);
|
||||
useEffect(() => {
|
||||
const visibleCameras = new Set<string>();
|
||||
visiblePreviewObserver.current = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
const camera = (entry.target as HTMLElement).dataset.camera;
|
||||
|
||||
if (!camera) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.isIntersecting) {
|
||||
visibleCameras.add(camera);
|
||||
} else {
|
||||
visibleCameras.delete(camera);
|
||||
}
|
||||
|
||||
setVisiblePreviews([...visibleCameras]);
|
||||
});
|
||||
},
|
||||
{ threshold: 0.1 },
|
||||
);
|
||||
|
||||
return () => {
|
||||
visiblePreviewObserver.current?.disconnect();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const previewRef = useCallback(
|
||||
(node: HTMLElement | null) => {
|
||||
if (!visiblePreviewObserver.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (node) visiblePreviewObserver.current.observe(node);
|
||||
} catch (e) {
|
||||
// no op
|
||||
}
|
||||
},
|
||||
// we need to listen on the value of the ref
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[visiblePreviewObserver.current],
|
||||
);
|
||||
|
||||
return (
|
||||
<div ref={contentRef} className="flex size-full flex-col pt-2">
|
||||
<Toaster closeButton={true} />
|
||||
@@ -631,12 +680,14 @@ export function RecordingView({
|
||||
}}
|
||||
>
|
||||
<PreviewPlayer
|
||||
previewRef={previewRef}
|
||||
className="size-full"
|
||||
camera={cam}
|
||||
timeRange={currentTimeRange}
|
||||
cameraPreviews={allPreviews ?? []}
|
||||
startTime={startTime}
|
||||
isScrubbing={scrubbing}
|
||||
isVisible={visiblePreviews.includes(cam)}
|
||||
onControllerReady={(controller) => {
|
||||
previewRefs.current[cam] = controller;
|
||||
controller.scrubToTimestamp(startTime);
|
||||
|
||||
@@ -230,7 +230,9 @@ export default function CameraSettingsView({
|
||||
if (changedValue) {
|
||||
addMessage(
|
||||
"camera_settings",
|
||||
`Unsaved review classification settings for ${capitalizeFirstLetter(selectedCamera)}`,
|
||||
t("camera.reviewClassification.unsavedChanges", {
|
||||
camera: selectedCamera,
|
||||
}),
|
||||
undefined,
|
||||
`review_classification_settings_${selectedCamera}`,
|
||||
);
|
||||
|
||||
@@ -220,7 +220,7 @@ export default function ClassificationSettingsView({
|
||||
if (changedValue) {
|
||||
addMessage(
|
||||
"search_settings",
|
||||
`Unsaved Classification settings changes`,
|
||||
t("classification.unsavedChanges"),
|
||||
undefined,
|
||||
"search_settings",
|
||||
);
|
||||
|
||||
@@ -176,7 +176,7 @@ export default function FrigatePlusSettingsView({
|
||||
if (changedValue) {
|
||||
addMessage(
|
||||
"plus_settings",
|
||||
`Unsaved Frigate+ settings changes`,
|
||||
t("frigatePlus.unsavedChanges"),
|
||||
undefined,
|
||||
"plus_settings",
|
||||
);
|
||||
|
||||
@@ -167,7 +167,7 @@ export default function MotionTunerView({
|
||||
if (changedValue) {
|
||||
addMessage(
|
||||
"motion_tuner",
|
||||
`Unsaved motion tuner changes (${selectedCamera})`,
|
||||
t("motionDetectionTuner.unsavedChanges", { camera: selectedCamera }),
|
||||
undefined,
|
||||
`motion_tuner_${selectedCamera}`,
|
||||
);
|
||||
|
||||
@@ -105,7 +105,7 @@ export default function NotificationView({
|
||||
if (changedValue) {
|
||||
addMessage(
|
||||
"notification_settings",
|
||||
`Unsaved notification settings`,
|
||||
t("notification.unsavedChanges"),
|
||||
undefined,
|
||||
`notification_settings`,
|
||||
);
|
||||
@@ -128,7 +128,7 @@ export default function NotificationView({
|
||||
if (registration) {
|
||||
addMessage(
|
||||
"notification_settings",
|
||||
"Unsaved Notification Registrations",
|
||||
t("notification.unsavedRegistrations"),
|
||||
undefined,
|
||||
"registration",
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user