mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-08-02 09:02:15 +03:00
Tweaks (#22656)
* tweak language * show validation errors in json response * fix export hwaccel args field in UI * increase annotation offset consts * fix save button race conditions, add reset spinner, and fix enrichments profile leak - Disable both Save and SaveAll buttons while either operation is in progress so users cannot trigger concurrent saves - Show activity indicator on Reset to Default/Global button during the API call - Enrichments panes (semantic search, genai, face recognition) now always show base config fields regardless of profile selection in the header dropdown * fix genai additional_concerns validation error with textarea array widget The additional_concerns field is list[str] in the backend but was using the textarea widget which produces a string value, causing validation errors. Created a TextareaArrayWidget that converts between array (one item per line) and textarea display, and switched additional_concerns to use it * populate and sort global audio filters for all audio labels * add column labels in profiles view * enforce a minimum value of 2 for min_initialized * reuse widget and refactor for multiline * fix * change record copy preset to transcode audio to aac
This commit is contained in:
@@ -9,15 +9,16 @@ import { toast } from "sonner";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { LuExternalLink, LuInfo, LuMinus, LuPlus } from "react-icons/lu";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
ANNOTATION_OFFSET_MAX,
|
||||
ANNOTATION_OFFSET_MIN,
|
||||
ANNOTATION_OFFSET_STEP,
|
||||
} from "@/lib/const";
|
||||
import { isMobile } from "react-device-detect";
|
||||
import { useIsAdmin } from "@/hooks/use-is-admin";
|
||||
import { useDocDomain } from "@/hooks/use-doc-domain";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
const OFFSET_MIN = -2500;
|
||||
const OFFSET_MAX = 2500;
|
||||
const OFFSET_STEP = 50;
|
||||
|
||||
type Props = {
|
||||
className?: string;
|
||||
};
|
||||
@@ -43,7 +44,10 @@ export default function AnnotationOffsetSlider({ className }: Props) {
|
||||
(delta: number) => {
|
||||
setAnnotationOffset((prev) => {
|
||||
const next = prev + delta;
|
||||
return Math.max(OFFSET_MIN, Math.min(OFFSET_MAX, next));
|
||||
return Math.max(
|
||||
ANNOTATION_OFFSET_MIN,
|
||||
Math.min(ANNOTATION_OFFSET_MAX, next),
|
||||
);
|
||||
});
|
||||
},
|
||||
[setAnnotationOffset],
|
||||
@@ -114,17 +118,17 @@ export default function AnnotationOffsetSlider({ className }: Props) {
|
||||
size="icon"
|
||||
className="size-8 shrink-0"
|
||||
aria-label="-50ms"
|
||||
onClick={() => stepOffset(-OFFSET_STEP)}
|
||||
disabled={annotationOffset <= OFFSET_MIN}
|
||||
onClick={() => stepOffset(-ANNOTATION_OFFSET_STEP)}
|
||||
disabled={annotationOffset <= ANNOTATION_OFFSET_MIN}
|
||||
>
|
||||
<LuMinus className="size-4" />
|
||||
</Button>
|
||||
<div className="w-full flex-1 landscape:flex">
|
||||
<Slider
|
||||
value={[annotationOffset]}
|
||||
min={OFFSET_MIN}
|
||||
max={OFFSET_MAX}
|
||||
step={OFFSET_STEP}
|
||||
min={ANNOTATION_OFFSET_MIN}
|
||||
max={ANNOTATION_OFFSET_MAX}
|
||||
step={ANNOTATION_OFFSET_STEP}
|
||||
onValueChange={handleChange}
|
||||
/>
|
||||
</div>
|
||||
@@ -134,8 +138,8 @@ export default function AnnotationOffsetSlider({ className }: Props) {
|
||||
size="icon"
|
||||
className="size-8 shrink-0"
|
||||
aria-label="+50ms"
|
||||
onClick={() => stepOffset(OFFSET_STEP)}
|
||||
disabled={annotationOffset >= OFFSET_MAX}
|
||||
onClick={() => stepOffset(ANNOTATION_OFFSET_STEP)}
|
||||
disabled={annotationOffset >= ANNOTATION_OFFSET_MAX}
|
||||
>
|
||||
<LuPlus className="size-4" />
|
||||
</Button>
|
||||
|
||||
@@ -13,10 +13,11 @@ import { Slider } from "@/components/ui/slider";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { useDocDomain } from "@/hooks/use-doc-domain";
|
||||
import { useIsAdmin } from "@/hooks/use-is-admin";
|
||||
|
||||
const OFFSET_MIN = -2500;
|
||||
const OFFSET_MAX = 2500;
|
||||
const OFFSET_STEP = 50;
|
||||
import {
|
||||
ANNOTATION_OFFSET_MAX,
|
||||
ANNOTATION_OFFSET_MIN,
|
||||
ANNOTATION_OFFSET_STEP,
|
||||
} from "@/lib/const";
|
||||
|
||||
type AnnotationSettingsPaneProps = {
|
||||
event: Event;
|
||||
@@ -49,7 +50,10 @@ export function AnnotationSettingsPane({
|
||||
(delta: number) => {
|
||||
setAnnotationOffset((prev) => {
|
||||
const next = prev + delta;
|
||||
return Math.max(OFFSET_MIN, Math.min(OFFSET_MAX, next));
|
||||
return Math.max(
|
||||
ANNOTATION_OFFSET_MIN,
|
||||
Math.min(ANNOTATION_OFFSET_MAX, next),
|
||||
);
|
||||
});
|
||||
},
|
||||
[setAnnotationOffset],
|
||||
@@ -128,16 +132,16 @@ export function AnnotationSettingsPane({
|
||||
size="icon"
|
||||
className="size-8 shrink-0"
|
||||
aria-label="-50ms"
|
||||
onClick={() => stepOffset(-OFFSET_STEP)}
|
||||
disabled={annotationOffset <= OFFSET_MIN}
|
||||
onClick={() => stepOffset(-ANNOTATION_OFFSET_STEP)}
|
||||
disabled={annotationOffset <= ANNOTATION_OFFSET_MIN}
|
||||
>
|
||||
<LuMinus className="size-4" />
|
||||
</Button>
|
||||
<Slider
|
||||
value={[annotationOffset]}
|
||||
min={OFFSET_MIN}
|
||||
max={OFFSET_MAX}
|
||||
step={OFFSET_STEP}
|
||||
min={ANNOTATION_OFFSET_MIN}
|
||||
max={ANNOTATION_OFFSET_MAX}
|
||||
step={ANNOTATION_OFFSET_STEP}
|
||||
onValueChange={handleSliderChange}
|
||||
className="flex-1"
|
||||
/>
|
||||
@@ -147,8 +151,8 @@ export function AnnotationSettingsPane({
|
||||
size="icon"
|
||||
className="size-8 shrink-0"
|
||||
aria-label="+50ms"
|
||||
onClick={() => stepOffset(OFFSET_STEP)}
|
||||
disabled={annotationOffset >= OFFSET_MAX}
|
||||
onClick={() => stepOffset(ANNOTATION_OFFSET_STEP)}
|
||||
disabled={annotationOffset >= ANNOTATION_OFFSET_MAX}
|
||||
>
|
||||
<LuPlus className="size-4" />
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user