From c5fcf6aa1fa0d94bd61679f3846912ac50cd96d5 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Wed, 11 Feb 2026 10:09:49 -0600 Subject: [PATCH] add timezone widget --- web/public/locales/en/views/settings.json | 3 + .../config-form/section-configs/ui.ts | 5 ++ .../config-form/theme/frigateTheme.ts | 2 + .../theme/widgets/TimezoneSelectWidget.tsx | 62 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 web/src/components/config-form/theme/widgets/TimezoneSelectWidget.tsx diff --git a/web/public/locales/en/views/settings.json b/web/public/locales/en/views/settings.json index bb3891932..f80e12d83 100644 --- a/web/public/locales/en/views/settings.json +++ b/web/public/locales/en/views/settings.json @@ -1215,6 +1215,9 @@ "keyPlaceholder": "New key", "remove": "Remove" }, + "timezone": { + "defaultOption": "Use browser timezone" + }, "ffmpegArgs": { "preset": "Preset", "manual": "Manual arguments", diff --git a/web/src/components/config-form/section-configs/ui.ts b/web/src/components/config-form/section-configs/ui.ts index 398ed359b..a30083cb5 100644 --- a/web/src/components/config-form/section-configs/ui.ts +++ b/web/src/components/config-form/section-configs/ui.ts @@ -18,6 +18,11 @@ const ui: SectionConfigOverrides = { "unit_system", ], advancedFields: [], + uiSchema: { + timezone: { + "ui:widget": "timezoneSelect", + }, + }, }, }; diff --git a/web/src/components/config-form/theme/frigateTheme.ts b/web/src/components/config-form/theme/frigateTheme.ts index 8bd7ea72b..04103154d 100644 --- a/web/src/components/config-form/theme/frigateTheme.ts +++ b/web/src/components/config-form/theme/frigateTheme.ts @@ -23,6 +23,7 @@ import { AudioLabelSwitchesWidget } from "./widgets/AudioLabelSwitchesWidget"; import { ZoneSwitchesWidget } from "./widgets/ZoneSwitchesWidget"; import { ArrayAsTextWidget } from "./widgets/ArrayAsTextWidget"; import { FfmpegArgsWidget } from "./widgets/FfmpegArgsWidget"; +import { TimezoneSelectWidget } from "./widgets/TimezoneSelectWidget"; import { FieldTemplate } from "./templates/FieldTemplate"; import { ObjectFieldTemplate } from "./templates/ObjectFieldTemplate"; @@ -65,6 +66,7 @@ export const frigateTheme: FrigateTheme = { objectLabels: ObjectLabelSwitchesWidget, audioLabels: AudioLabelSwitchesWidget, zoneNames: ZoneSwitchesWidget, + timezoneSelect: TimezoneSelectWidget, }, templates: { FieldTemplate: FieldTemplate as React.ComponentType, diff --git a/web/src/components/config-form/theme/widgets/TimezoneSelectWidget.tsx b/web/src/components/config-form/theme/widgets/TimezoneSelectWidget.tsx new file mode 100644 index 000000000..3e5253270 --- /dev/null +++ b/web/src/components/config-form/theme/widgets/TimezoneSelectWidget.tsx @@ -0,0 +1,62 @@ +import { useMemo } from "react"; +import type { WidgetProps } from "@rjsf/utils"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { useTranslation } from "react-i18next"; + +const DEFAULT_TIMEZONE_VALUE = "__browser__"; + +function getTimezoneList(): string[] { + if (typeof Intl !== "undefined") { + const intl = Intl as typeof Intl & { + supportedValuesOf?: (key: string) => string[]; + }; + const supported = intl.supportedValuesOf?.("timeZone"); + if (supported && supported.length > 0) { + return [...supported].sort(); + } + } + + const fallback = Intl.DateTimeFormat().resolvedOptions().timeZone; + return fallback ? [fallback] : ["UTC"]; +} + +export function TimezoneSelectWidget(props: WidgetProps) { + const { id, value, disabled, readonly, onChange, schema } = props; + const { t } = useTranslation(["views/settings", "common"]); + + const timezones = useMemo(() => getTimezoneList(), []); + const selectedValue = value ? String(value) : DEFAULT_TIMEZONE_VALUE; + const defaultLabel = t("configForm.timezone.defaultOption", { + ns: "views/settings", + }); + + return ( + + ); +} + +export default TimezoneSelectWidget;