From fdf7e221307fcd2df0823829e91c2ac625168534 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Fri, 13 Feb 2026 09:14:40 -0600 Subject: [PATCH] refactor frigate+ view and make tweaks to sections --- frigate/config/camera/live.py | 4 +- frigate/config/camera/motion.py | 2 +- web/public/locales/en/config/cameras.json | 6 +- web/public/locales/en/config/global.json | 6 +- web/public/locales/en/config/validation.json | 13 +- web/public/locales/en/views/settings.json | 6 + web/src/components/card/SettingsGroupCard.tsx | 56 ++ .../config-form/section-configs/live.ts | 2 +- .../config-form/section-configs/objects.ts | 2 +- .../config-form/section-configs/snapshots.ts | 2 +- .../config-form/section-validations/ffmpeg.ts | 13 + .../NotificationsSettingsExtras.tsx | 372 +++++---- web/src/pages/Logs.tsx | 2 +- web/src/pages/Settings.tsx | 2 - .../settings/FrigatePlusSettingsView.tsx | 594 ++++++------- .../settings/NotificationsSettingsView.tsx | 785 ------------------ web/src/views/settings/UiSettingsView.tsx | 29 +- 17 files changed, 594 insertions(+), 1302 deletions(-) create mode 100644 web/src/components/card/SettingsGroupCard.tsx delete mode 100644 web/src/views/settings/NotificationsSettingsView.tsx diff --git a/frigate/config/camera/live.py b/frigate/config/camera/live.py index 8302a784e..54b5a2bfd 100644 --- a/frigate/config/camera/live.py +++ b/frigate/config/camera/live.py @@ -16,12 +16,12 @@ class CameraLiveConfig(FrigateBaseModel): height: int = Field( default=720, title="Live height", - description="Height (pixels) to render the live stream in the Web UI; must be <= detect stream height.", + description="Height (pixels) to render the jsmpeg live stream in the Web UI; must be <= detect stream height.", ) quality: int = Field( default=8, ge=1, le=31, title="Live quality", - description="Encoding quality for the live jsmpeg stream (1 highest, 31 lowest).", + description="Encoding quality for the jsmpeg stream (1 highest, 31 lowest).", ) diff --git a/frigate/config/camera/motion.py b/frigate/config/camera/motion.py index 86599aa2c..d39130108 100644 --- a/frigate/config/camera/motion.py +++ b/frigate/config/camera/motion.py @@ -50,7 +50,7 @@ class MotionConfig(FrigateBaseModel): frame_height: Optional[int] = Field( default=100, title="Frame height", - description="Height in pixels to scale frames to when computing motion (useful for performance).", + description="Height in pixels to scale frames to when computing motion.", ) mask: Union[str, list[str]] = Field( default="", diff --git a/web/public/locales/en/config/cameras.json b/web/public/locales/en/config/cameras.json index ca60fa362..7fbbed4a5 100644 --- a/web/public/locales/en/config/cameras.json +++ b/web/public/locales/en/config/cameras.json @@ -224,11 +224,11 @@ }, "height": { "label": "Live height", - "description": "Height (pixels) to render the live stream in the Web UI; must be <= detect stream height." + "description": "Height (pixels) to render the jsmpeg live stream in the Web UI; must be <= detect stream height." }, "quality": { "label": "Live quality", - "description": "Encoding quality for the live jsmpeg stream (1 highest, 31 lowest)." + "description": "Encoding quality for the jsmpeg stream (1 highest, 31 lowest)." } }, "lpr": { @@ -284,7 +284,7 @@ }, "frame_height": { "label": "Frame height", - "description": "Height in pixels to scale frames to when computing motion (useful for performance)." + "description": "Height in pixels to scale frames to when computing motion." }, "mask": { "label": "Mask coordinates", diff --git a/web/public/locales/en/config/global.json b/web/public/locales/en/config/global.json index b67ec7434..f4c6db617 100644 --- a/web/public/locales/en/config/global.json +++ b/web/public/locales/en/config/global.json @@ -1367,11 +1367,11 @@ }, "height": { "label": "Live height", - "description": "Height (pixels) to render the live stream in the Web UI; must be <= detect stream height." + "description": "Height (pixels) to render the jsmpeg live stream in the Web UI; must be <= detect stream height." }, "quality": { "label": "Live quality", - "description": "Encoding quality for the live jsmpeg stream (1 highest, 31 lowest)." + "description": "Encoding quality for the jsmpeg stream (1 highest, 31 lowest)." } }, "motion": { @@ -1407,7 +1407,7 @@ }, "frame_height": { "label": "Frame height", - "description": "Height in pixels to scale frames to when computing motion (useful for performance)." + "description": "Height in pixels to scale frames to when computing motion." }, "mask": { "label": "Mask coordinates", diff --git a/web/public/locales/en/config/validation.json b/web/public/locales/en/config/validation.json index 2824f6147..638725a56 100644 --- a/web/public/locales/en/config/validation.json +++ b/web/public/locales/en/config/validation.json @@ -17,6 +17,15 @@ "additionalProperties": "Unknown property is not allowed", "oneOf": "Must match exactly one of the allowed schemas", "anyOf": "Must match at least one of the allowed schemas", - "proxy.header_map.roleHeaderRequired": "Role header is required when role mappings are configured.", - "ffmpeg.inputs.rolesUnique": "Each role can only be assigned to one input stream." + "proxy": { + "header_map": { + "roleHeaderRequired": "Role header is required when role mappings are configured." + } + }, + "ffmpeg": { + "inputs": { + "rolesUnique": "Each role can only be assigned to one input stream.", + "detectRequired": "At least one input stream must be assigned the 'detect' role." + } + } } diff --git a/web/public/locales/en/views/settings.json b/web/public/locales/en/views/settings.json index a5fe096ae..a0f8f1630 100644 --- a/web/public/locales/en/views/settings.json +++ b/web/public/locales/en/views/settings.json @@ -982,6 +982,12 @@ }, "frigatePlus": { "title": "Frigate+ Settings", + "cardTitles": { + "api": "API", + "currentModel": "Current model", + "otherModels": "Other models", + "configuration": "Configuration" + }, "apiKey": { "title": "Frigate+ API Key", "validated": "Frigate+ API key is detected and validated", diff --git a/web/src/components/card/SettingsGroupCard.tsx b/web/src/components/card/SettingsGroupCard.tsx new file mode 100644 index 000000000..3bc53fb36 --- /dev/null +++ b/web/src/components/card/SettingsGroupCard.tsx @@ -0,0 +1,56 @@ +import { ReactNode } from "react"; +import { Label } from "../ui/label"; + +export const SPLIT_ROW_CLASS_NAME = + "space-y-2 md:grid md:grid-cols-[minmax(14rem,22rem)_minmax(0,1fr)] md:items-start md:gap-x-6 md:space-y-0"; +export const DESCRIPTION_CLASS_NAME = "text-sm text-muted-foreground"; +export const CONTROL_COLUMN_CLASS_NAME = "w-full md:max-w-2xl"; + +type SettingsGroupCardProps = { + title: string; + children: ReactNode; +}; + +export function SettingsGroupCard({ title, children }: SettingsGroupCardProps) { + return ( +
{t("notification.notificationSettings.desc")}