Compare commits

..

26 Commits

Author SHA1 Message Date
Hosted Weblate
64f9e7076b
Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (92 of 92 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (116 of 116 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (116 of 116 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 93.1% (108 of 116 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (52 of 52 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (39 of 39 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (118 of 118 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: OverTheHillsAndFarAway <prosjektx@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/objects/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/nb_NO/
Translation: Frigate NVR/common
Translation: Frigate NVR/objects
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-settings
Translation: Frigate NVR/views-system
2025-11-24 13:45:29 +00:00
Hosted Weblate
84cf7748c7
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (52 of 52 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (116 of 116 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (39 of 39 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (214 of 214 strings)

Co-authored-by: GuoQing Liu <842607283@qq.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/zh_Hans/
Translation: Frigate NVR/common
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-settings
Translation: Frigate NVR/views-system
2025-11-24 13:45:29 +00:00
Hosted Weblate
a151df29d4
Translated using Weblate (Slovenian)
Currently translated at 100.0% (214 of 214 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Kaboom <kaboom083@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/sl/
Translation: Frigate NVR/common
2025-11-24 13:45:28 +00:00
Hosted Weblate
fcd8823c6f
Translated using Weblate (Slovak)
Currently translated at 97.6% (125 of 128 strings)

Translated using Weblate (Slovak)

Currently translated at 99.1% (115 of 116 strings)

Translated using Weblate (Slovak)

Currently translated at 99.5% (213 of 214 strings)

Translated using Weblate (Slovak)

Currently translated at 83.8% (536 of 639 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (92 of 92 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Michal K <michal@totaljs.com>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/sk/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/sk/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/sk/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/sk/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/sk/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/sk/
Translation: Frigate NVR/common
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-settings
Translation: Frigate NVR/views-system
2025-11-24 13:45:27 +00:00
Hosted Weblate
4b0e37f800
Translated using Weblate (Swedish)
Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (92 of 92 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (54 of 54 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (116 of 116 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (39 of 39 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (118 of 118 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Kristian Johansson <knmjohansson@gmail.com>
Co-authored-by: OverTheHillsAndFarAway <prosjektx@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/sv/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/sv/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/objects/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/sv/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/sv/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/sv/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/sv/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/sv/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/sv/
Translation: Frigate NVR/common
Translation: Frigate NVR/components-dialog
Translation: Frigate NVR/objects
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-settings
Translation: Frigate NVR/views-system
2025-11-24 13:45:27 +00:00
Hosted Weblate
f48be307dd
Translated using Weblate (French)
Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (French)

Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (French)

Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (French)

Currently translated at 100.0% (92 of 92 strings)

Translated using Weblate (French)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (French)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (French)

Currently translated at 100.0% (39 of 39 strings)

Translated using Weblate (French)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (French)

Currently translated at 100.0% (116 of 116 strings)

Translated using Weblate (French)

Currently translated at 100.0% (118 of 118 strings)

Translated using Weblate (French)

Currently translated at 100.0% (635 of 635 strings)

Translated using Weblate (French)

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (French)

Currently translated at 100.0% (108 of 108 strings)

Translated using Weblate (French)

Currently translated at 100.0% (52 of 52 strings)

Translated using Weblate (French)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (French)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (French)

Currently translated at 97.1% (103 of 106 strings)

Translated using Weblate (French)

Currently translated at 97.1% (103 of 106 strings)

Translated using Weblate (French)

Currently translated at 100.0% (598 of 598 strings)

Translated using Weblate (French)

Currently translated at 100.0% (127 of 127 strings)

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Apocoloquintose <bertrand.moreux@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/fr/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/fr/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/fr/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/fr/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/fr/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/fr/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/fr/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/fr/
Translation: Frigate NVR/common
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-settings
Translation: Frigate NVR/views-system
2025-11-24 13:45:26 +00:00
Hosted Weblate
7329563d62
Translated using Weblate (Spanish)
Currently translated at 90.2% (83 of 92 strings)

Translated using Weblate (Spanish)

Currently translated at 30.1% (35 of 116 strings)

Translated using Weblate (Spanish)

Currently translated at 64.0% (409 of 639 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (39 of 39 strings)

Translated using Weblate (Spanish)

Currently translated at 76.3% (97 of 127 strings)

Translated using Weblate (Spanish)

Currently translated at 29.3% (34 of 116 strings)

Translated using Weblate (Spanish)

Currently translated at 24.1% (28 of 116 strings)

Translated using Weblate (Spanish)

Currently translated at 25.4% (27 of 106 strings)

Translated using Weblate (Spanish)

Currently translated at 26.4% (28 of 106 strings)

Translated using Weblate (Spanish)

Currently translated at 76.3% (97 of 127 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (39 of 39 strings)

Co-authored-by: Adrian C <adriancuervo@gmail.com>
Co-authored-by: Gerard Ricart Castells <gerard.ricart@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Josep Olivé <josepolive89@gmail.com>
Co-authored-by: Ramòn Rueda <virem1@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/es/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/es/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/es/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/es/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/es/
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-settings
2025-11-24 13:45:25 +00:00
Hosted Weblate
2fba55c72f
Translated using Weblate (Dutch)
Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (116 of 116 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (92 of 92 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (39 of 39 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (116 of 116 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (635 of 635 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (108 of 108 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (52 of 52 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (598 of 598 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (207 of 207 strings)

Translated using Weblate (Dutch)

Currently translated at 97.1% (103 of 106 strings)

Translated using Weblate (Dutch)

Currently translated at 97.1% (103 of 106 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (598 of 598 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (127 of 127 strings)

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Marijn <168113859+Marijn0@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/nl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/nl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/nl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/nl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/nl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/nl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/nl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/nl/
Translation: Frigate NVR/common
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-settings
Translation: Frigate NVR/views-system
2025-11-24 13:45:24 +00:00
Hosted Weblate
31b492dbc4
Translated using Weblate (Italian)
Currently translated at 100.0% (92 of 92 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (116 of 116 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (118 of 118 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (39 of 39 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (52 of 52 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (54 of 54 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (501 of 501 strings)

Co-authored-by: Gringo <ita.translations@tiscali.it>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/it/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/it/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/it/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/it/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/it/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/it/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/it/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/it/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/it/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/it/
Translation: Frigate NVR/audio
Translation: Frigate NVR/common
Translation: Frigate NVR/components-dialog
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-settings
Translation: Frigate NVR/views-system
2025-11-24 13:45:24 +00:00
Hosted Weblate
09aa713b76
Translated using Weblate (Polish)
Currently translated at 63.8% (408 of 639 strings)

Translated using Weblate (Polish)

Currently translated at 30.0% (34 of 113 strings)

Translated using Weblate (Polish)

Currently translated at 75.5% (96 of 127 strings)

Translated using Weblate (Polish)

Currently translated at 27.3% (29 of 106 strings)

Translated using Weblate (Polish)

Currently translated at 68.3% (409 of 598 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (52 of 52 strings)

Translated using Weblate (Polish)

Currently translated at 98.1% (53 of 54 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (39 of 39 strings)

Translated using Weblate (Polish)

Currently translated at 74.8% (95 of 127 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (10 of 10 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Mateusz Paś <piciuok@gmail.com>
Co-authored-by: Wojciech Niziński <niziak-weblate@spox.org>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-auth/pl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/pl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/pl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/pl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/pl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-exports/pl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/pl/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/pl/
Translation: Frigate NVR/components-auth
Translation: Frigate NVR/components-dialog
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-exports
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-settings
2025-11-24 13:45:23 +00:00
Hosted Weblate
95f151c693
Translated using Weblate (Croatian)
Currently translated at 33.3% (2 of 6 strings)

Translated using Weblate (Croatian)

Currently translated at 21.1% (11 of 52 strings)

Translated using Weblate (Croatian)

Currently translated at 2.7% (2 of 72 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Josip <josipmiki54@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-filter/hr/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/hr/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-recording/hr/
Translation: Frigate NVR/components-filter
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-recording
2025-11-24 13:45:22 +00:00
Hosted Weblate
f50941cbb6
Translated using Weblate (Czech)
Currently translated at 14.6% (17 of 116 strings)

Translated using Weblate (Czech)

Currently translated at 13.7% (16 of 116 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Czech)

Currently translated at 63.0% (403 of 639 strings)

Translated using Weblate (Czech)

Currently translated at 76.9% (30 of 39 strings)

Translated using Weblate (Czech)

Currently translated at 4.7% (5 of 106 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Jakub Sojka <sojkubu@seznam.cz>
Co-authored-by: Martin Janda <janda@chilliit.cz>
Co-authored-by: Michal K <michal@totaljs.com>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/cs/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/cs/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-exports/cs/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/cs/
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-exports
Translation: Frigate NVR/views-settings
2025-11-24 13:45:21 +00:00
Hosted Weblate
4d6e3a80d9
Translated using Weblate (Catalan)
Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (92 of 92 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (39 of 39 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (116 of 116 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (108 of 108 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (52 of 52 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (598 of 598 strings)

Translated using Weblate (Catalan)

Currently translated at 97.1% (103 of 106 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (598 of 598 strings)

Translated using Weblate (Catalan)

Currently translated at 100.0% (127 of 127 strings)

Co-authored-by: Eduardo Pastor Fernández <123eduardoneko123@gmail.com>
Co-authored-by: Gerard Ricart Castells <gerard.ricart@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/ca/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/ca/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/ca/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/ca/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/ca/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/ca/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/ca/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/ca/
Translation: Frigate NVR/common
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-settings
Translation: Frigate NVR/views-system
2025-11-24 13:45:21 +00:00
Hosted Weblate
3a39872eff
Translated using Weblate (Ukrainian)
Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (92 of 92 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (39 of 39 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (116 of 116 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (635 of 635 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (108 of 108 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (52 of 52 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Ukrainian)

Currently translated at 97.1% (103 of 106 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (598 of 598 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (127 of 127 strings)

Co-authored-by: Alex Taran <oleksii.taran@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Максим Горпиніч <gorpinicmaksim0@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/uk/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/uk/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/uk/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/uk/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/uk/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/uk/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/uk/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/uk/
Translation: Frigate NVR/common
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-settings
Translation: Frigate NVR/views-system
2025-11-24 13:45:20 +00:00
Hosted Weblate
9c481b41cf
Translated using Weblate (Bulgarian)
Currently translated at 31.1% (28 of 90 strings)

Translated using Weblate (Bulgarian)

Currently translated at 7.6% (1 of 13 strings)

Translated using Weblate (Bulgarian)

Currently translated at 50.0% (1 of 2 strings)

Translated using Weblate (Bulgarian)

Currently translated at 50.0% (1 of 2 strings)

Translated using Weblate (Bulgarian)

Currently translated at 7.4% (4 of 54 strings)

Translated using Weblate (Bulgarian)

Currently translated at 10.0% (1 of 10 strings)

Translated using Weblate (Bulgarian)

Currently translated at 17.7% (21 of 118 strings)

Co-authored-by: Borislav <sartheris@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-auth/bg/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/bg/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-icons/bg/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-input/bg/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/objects/bg/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-exports/bg/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/bg/
Translation: Frigate NVR/components-auth
Translation: Frigate NVR/components-dialog
Translation: Frigate NVR/components-icons
Translation: Frigate NVR/components-input
Translation: Frigate NVR/objects
Translation: Frigate NVR/views-exports
Translation: Frigate NVR/views-live
2025-11-24 13:45:19 +00:00
Hosted Weblate
edaa23c1b0
Translated using Weblate (Romanian)
Currently translated at 100.0% (128 of 128 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (125 of 125 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (92 of 92 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (118 of 118 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (639 of 639 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (39 of 39 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (214 of 214 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (116 of 116 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (108 of 108 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (52 of 52 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (598 of 598 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Romanian)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Romanian)

Currently translated at 97.1% (103 of 106 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: lukasig <lukasig@hotmail.com>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/ro/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/ro/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/ro/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/ro/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/ro/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/ro/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/ro/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/ro/
Translation: Frigate NVR/common
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-settings
Translation: Frigate NVR/views-system
2025-11-24 13:45:18 +00:00
Hosted Weblate
2664f289b9
Translated using Weblate (Russian)
Currently translated at 68.7% (439 of 639 strings)

Translated using Weblate (Russian)

Currently translated at 98.5% (211 of 214 strings)

Translated using Weblate (Russian)

Currently translated at 95.5% (108 of 113 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (52 of 52 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (501 of 501 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (108 of 108 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (54 of 54 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Russian)

Currently translated at 78.0% (467 of 598 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (52 of 52 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (127 of 127 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (39 of 39 strings)

Translated using Weblate (Russian)

Currently translated at 73.9% (442 of 598 strings)

Translated using Weblate (Russian)

Currently translated at 95.5% (86 of 90 strings)

Translated using Weblate (Russian)

Currently translated at 98.0% (51 of 52 strings)

Translated using Weblate (Russian)

Currently translated at 71.6% (91 of 127 strings)

Translated using Weblate (Russian)

Currently translated at 86.4% (433 of 501 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Артём Владимиров <artyomka71@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/ru/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/ru/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/ru/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/ru/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/ru/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/ru/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/ru/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/ru/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/ru/
Translation: Frigate NVR/audio
Translation: Frigate NVR/common
Translation: Frigate NVR/components-dialog
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-settings
2025-11-24 13:45:17 +00:00
Hosted Weblate
3e851c6eef
Translated using Weblate (Greek)
Currently translated at 100.0% (10 of 10 strings)

Co-authored-by: Christos Sidiropoulos <dev@csidirop.de>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-auth/el/
Translation: Frigate NVR/components-auth
2025-11-24 13:45:16 +00:00
Hosted Weblate
d3b1f5da43
Translated using Weblate (Danish)
Currently translated at 48.3% (57 of 118 strings)

Translated using Weblate (Danish)

Currently translated at 16.6% (9 of 54 strings)

Translated using Weblate (Danish)

Currently translated at 7.7% (9 of 116 strings)

Translated using Weblate (Danish)

Currently translated at 6.7% (8 of 118 strings)

Translated using Weblate (Danish)

Currently translated at 1.4% (9 of 639 strings)

Translated using Weblate (Danish)

Currently translated at 16.6% (8 of 48 strings)

Translated using Weblate (Danish)

Currently translated at 100.0% (6 of 6 strings)

Translated using Weblate (Danish)

Currently translated at 10.0% (9 of 90 strings)

Translated using Weblate (Danish)

Currently translated at 17.3% (9 of 52 strings)

Translated using Weblate (Danish)

Currently translated at 61.5% (8 of 13 strings)

Translated using Weblate (Danish)

Currently translated at 9.4% (12 of 127 strings)

Translated using Weblate (Danish)

Currently translated at 25.6% (10 of 39 strings)

Translated using Weblate (Danish)

Currently translated at 80.0% (8 of 10 strings)

Translated using Weblate (Danish)

Currently translated at 36.0% (9 of 25 strings)

Translated using Weblate (Danish)

Currently translated at 100.0% (2 of 2 strings)

Translated using Weblate (Danish)

Currently translated at 12.5% (9 of 72 strings)

Translated using Weblate (Danish)

Currently translated at 14.8% (8 of 54 strings)

Translated using Weblate (Danish)

Currently translated at 19.5% (9 of 46 strings)

Translated using Weblate (Danish)

Currently translated at 90.0% (9 of 10 strings)

Translated using Weblate (Danish)

Currently translated at 16.9% (85 of 501 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: demention666 <anders+GITHUB@familien-harder.dk>
Co-authored-by: dinf60 <dinf60@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-auth/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-camera/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-filter/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-input/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-player/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-configeditor/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-exports/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-recording/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-search/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/da/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/da/
Translation: Frigate NVR/audio
Translation: Frigate NVR/components-auth
Translation: Frigate NVR/components-camera
Translation: Frigate NVR/components-dialog
Translation: Frigate NVR/components-filter
Translation: Frigate NVR/components-input
Translation: Frigate NVR/components-player
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-configeditor
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-exports
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-live
Translation: Frigate NVR/views-recording
Translation: Frigate NVR/views-search
Translation: Frigate NVR/views-settings
Translation: Frigate NVR/views-system
2025-11-24 13:45:16 +00:00
Hosted Weblate
11405710d6
Translated using Weblate (German)
Currently translated at 19.8% (23 of 116 strings)

Translated using Weblate (German)

Currently translated at 89.7% (35 of 39 strings)

Translated using Weblate (German)

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (German)

Currently translated at 77.7% (497 of 639 strings)

Translated using Weblate (German)

Currently translated at 98.0% (51 of 52 strings)

Translated using Weblate (German)

Currently translated at 18.1% (21 of 116 strings)

Translated using Weblate (German)

Currently translated at 84.6% (33 of 39 strings)

Translated using Weblate (German)

Currently translated at 6.0% (7 of 116 strings)

Translated using Weblate (German)

Currently translated at 92.3% (48 of 52 strings)

Translated using Weblate (German)

Currently translated at 93.7% (119 of 127 strings)

Translated using Weblate (German)

Currently translated at 71.6% (91 of 127 strings)

Translated using Weblate (German)

Currently translated at 100.0% (54 of 54 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (635 of 635 strings)

Translated using Weblate (German)

Currently translated at 100.0% (209 of 209 strings)

Translated using Weblate (German)

Currently translated at 88.4% (443 of 501 strings)

Co-authored-by: Christos Sidiropoulos <dev@csidirop.de>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Marijn <168113859+Marijn0@users.noreply.github.com>
Co-authored-by: mvdberge <micha.vordemberge@christmann.info>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/de/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/de/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/de/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/de/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/de/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/de/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-exports/de/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/de/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/de/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/nl/
Translation: Frigate NVR/audio
Translation: Frigate NVR/common
Translation: Frigate NVR/components-dialog
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-explore
Translation: Frigate NVR/views-exports
Translation: Frigate NVR/views-facelibrary
Translation: Frigate NVR/views-settings
2025-11-24 13:45:15 +00:00
Hosted Weblate
1681ba5984
Translated using Weblate (Portuguese (Brazil))
Currently translated at 24.1% (28 of 116 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 68.7% (439 of 639 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.4% (38 of 39 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Marcelo Popper Costa <marcelo_popper@hotmail.com>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/pt_BR/
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-settings
2025-11-24 13:45:14 +00:00
Hosted Weblate
4be578dc27
Translated using Weblate (Lithuanian)
Currently translated at 30.1% (32 of 106 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: MaBeniu <runnerm@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/lt/
Translation: Frigate NVR/views-classificationmodel
2025-11-24 13:45:13 +00:00
Hosted Weblate
cd944ae948
Added translation using Weblate (Latvian)
Added translation using Weblate (Latvian)

Added translation using Weblate (Latvian)

Added translation using Weblate (Latvian)

Added translation using Weblate (Latvian)

Added translation using Weblate (Latvian)

Added translation using Weblate (Latvian)

Added translation using Weblate (Latvian)

Added translation using Weblate (Latvian)

Added translation using Weblate (Latvian)

Added translation using Weblate (Latvian)

Update translation files

Updated by "Squash Git commits" add-on in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Languages add-on <noreply-addon-languages@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/
Translation: Frigate NVR/common
2025-11-24 13:45:12 +00:00
Hosted Weblate
03898c91fe
Translated using Weblate (Turkish)
Currently translated at 35.8% (38 of 106 strings)

Co-authored-by: Emircanos <emircan368@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/tr/
Translation: Frigate NVR/views-classificationmodel
2025-11-24 13:45:11 +00:00
Nicolas Mowen
2a9c028f55
Update ROCm to 7.1.0 (#21032)
Some checks are pending
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions
* Update ROCm to 7.1.0

* Change to be consistent
2025-11-24 07:45:00 -06:00
Josh Hawkins
aa8b423b68
Miscellaneous Fixes (#21024)
* fix wording in reference config

* spacing tweaks

* make live view settings drawer scrollable

* clarify audio transcription docs

* change audio transcription icon to activity indicator when transcription is in progress

the backend doesn't implement any kind of queueing for speech event transcription

* tracking details tweaks

- Add attribute box overlay and area
- Add score
- Throttle swr revalidation during video component rerendering

* add mse codecs to console debug on errors

* add camera name
2025-11-24 06:34:56 -07:00
36 changed files with 611 additions and 403 deletions

View File

@ -15,7 +15,7 @@ ARG AMDGPU
RUN apt update -qq && \
apt install -y wget gpg && \
wget -O rocm.deb https://repo.radeon.com/amdgpu-install/7.0.2/ubuntu/jammy/amdgpu-install_7.0.2.70002-1_all.deb && \
wget -O rocm.deb https://repo.radeon.com/amdgpu-install/7.1/ubuntu/jammy/amdgpu-install_7.1.70100-1_all.deb && \
apt install -y ./rocm.deb && \
apt update && \
apt install -qq -y rocm

View File

@ -1 +1 @@
onnxruntime-migraphx @ https://github.com/NickM-27/frigate-onnxruntime-rocm/releases/download/v7.0.2/onnxruntime_migraphx-1.23.1-cp311-cp311-linux_x86_64.whl
onnxruntime-migraphx @ https://github.com/NickM-27/frigate-onnxruntime-rocm/releases/download/v7.1.0/onnxruntime_migraphx-1.23.1-cp311-cp311-linux_x86_64.whl

View File

@ -2,7 +2,7 @@ variable "AMDGPU" {
default = "gfx900"
}
variable "ROCM" {
default = "7.0.2"
default = "7.1"
}
variable "HSA_OVERRIDE_GFX_VERSION" {
default = ""

View File

@ -144,4 +144,10 @@ In order to use transcription and translation for past events, you must enable a
The transcribed/translated speech will appear in the description box in the Tracked Object Details pane. If Semantic Search is enabled, embeddings are generated for the transcription text and are fully searchable using the description search type.
Recorded `speech` events will always use a `whisper` model, regardless of the `model_size` config setting. Without a GPU, generating transcriptions for longer `speech` events may take a fair amount of time, so be patient.
:::note
Only one `speech` event may be transcribed at a time. Frigate does not automatically transcribe `speech` events or implement a queue for long-running transcription model inference.
:::
Recorded `speech` events will always use a `whisper` model, regardless of the `model_size` config setting. Without a supported Nvidia GPU, generating transcriptions for longer `speech` events may take a fair amount of time, so be patient.

View File

@ -700,11 +700,11 @@ genai:
# Optional: Configuration for audio transcription
# NOTE: only the enabled option can be overridden at the camera level
audio_transcription:
# Optional: Enable license plate recognition (default: shown below)
# Optional: Enable live and speech event audio transcription (default: shown below)
enabled: False
# Optional: The device to run the models on (default: shown below)
# Optional: The device to run the models on for live transcription. (default: shown below)
device: CPU
# Optional: Set the model size used for transcription. (default: shown below)
# Optional: Set the model size used for live transcription. (default: shown below)
model_size: small
# Optional: Set the language used for transcription translation. (default: shown below)
# List of language codes: https://github.com/openai/whisper/blob/main/whisper/tokenizer.py#L10

View File

@ -542,6 +542,7 @@ def transcribe_audio(request: Request, body: AudioTranscriptionBody):
status_code=409, # 409 Conflict
)
else:
logger.debug(f"Failed to transcribe audio, response: {response}")
return JSONResponse(
content={
"success": False,

View File

@ -23,6 +23,7 @@ from frigate.const import (
NOTIFICATION_TEST,
REQUEST_REGION_GRID,
UPDATE_AUDIO_ACTIVITY,
UPDATE_AUDIO_TRANSCRIPTION_STATE,
UPDATE_BIRDSEYE_LAYOUT,
UPDATE_CAMERA_ACTIVITY,
UPDATE_EMBEDDINGS_REINDEX_PROGRESS,
@ -61,6 +62,7 @@ class Dispatcher:
self.model_state: dict[str, ModelStatusTypesEnum] = {}
self.embeddings_reindex: dict[str, Any] = {}
self.birdseye_layout: dict[str, Any] = {}
self.audio_transcription_state: str = "idle"
self._camera_settings_handlers: dict[str, Callable] = {
"audio": self._on_audio_command,
"audio_transcription": self._on_audio_transcription_command,
@ -178,6 +180,19 @@ class Dispatcher:
def handle_model_state() -> None:
self.publish("model_state", json.dumps(self.model_state.copy()))
def handle_update_audio_transcription_state() -> None:
if payload:
self.audio_transcription_state = payload
self.publish(
"audio_transcription_state",
json.dumps(self.audio_transcription_state),
)
def handle_audio_transcription_state() -> None:
self.publish(
"audio_transcription_state", json.dumps(self.audio_transcription_state)
)
def handle_update_embeddings_reindex_progress() -> None:
self.embeddings_reindex = payload
self.publish(
@ -264,10 +279,12 @@ class Dispatcher:
UPDATE_MODEL_STATE: handle_update_model_state,
UPDATE_EMBEDDINGS_REINDEX_PROGRESS: handle_update_embeddings_reindex_progress,
UPDATE_BIRDSEYE_LAYOUT: handle_update_birdseye_layout,
UPDATE_AUDIO_TRANSCRIPTION_STATE: handle_update_audio_transcription_state,
NOTIFICATION_TEST: handle_notification_test,
"restart": handle_restart,
"embeddingsReindexProgress": handle_embeddings_reindex_progress,
"modelState": handle_model_state,
"audioTranscriptionState": handle_audio_transcription_state,
"birdseyeLayout": handle_birdseye_layout,
"onConnect": handle_on_connect,
}

View File

@ -113,6 +113,7 @@ CLEAR_ONGOING_REVIEW_SEGMENTS = "clear_ongoing_review_segments"
UPDATE_CAMERA_ACTIVITY = "update_camera_activity"
UPDATE_AUDIO_ACTIVITY = "update_audio_activity"
EXPIRE_AUDIO_ACTIVITY = "expire_audio_activity"
UPDATE_AUDIO_TRANSCRIPTION_STATE = "update_audio_transcription_state"
UPDATE_EVENT_DESCRIPTION = "update_event_description"
UPDATE_REVIEW_DESCRIPTION = "update_review_description"
UPDATE_MODEL_STATE = "update_model_state"

View File

@ -13,6 +13,7 @@ from frigate.config import FrigateConfig
from frigate.const import (
CACHE_DIR,
MODEL_CACHE_DIR,
UPDATE_AUDIO_TRANSCRIPTION_STATE,
UPDATE_EVENT_DESCRIPTION,
)
from frigate.data_processing.types import PostProcessDataEnum
@ -190,6 +191,8 @@ class AudioTranscriptionPostProcessor(PostProcessorApi):
self.transcription_running = False
self.transcription_thread = None
self.requestor.send_data(UPDATE_AUDIO_TRANSCRIPTION_STATE, "idle")
def handle_request(self, topic: str, request_data: dict[str, any]) -> str | None:
if topic == "transcribe_audio":
event = request_data["event"]
@ -203,6 +206,8 @@ class AudioTranscriptionPostProcessor(PostProcessorApi):
# Mark as running and start the thread
self.transcription_running = True
self.requestor.send_data(UPDATE_AUDIO_TRANSCRIPTION_STATE, "processing")
self.transcription_thread = threading.Thread(
target=self._transcription_wrapper, args=(event,), daemon=True
)

View File

@ -109,6 +109,7 @@ class TimelineProcessor(threading.Thread):
event_data["region"],
),
"attribute": "",
"score": event_data["score"],
},
}

View File

@ -100,7 +100,7 @@
"updatedSublabel": "Subetiqueta actualitzada amb èxit.",
"updatedLPR": "Matrícula actualitzada amb èxit.",
"regenerate": "El {{provider}} ha sol·licitat una nova descripció. En funció de la velocitat del vostre proveïdor, la nova descripció pot trigar un temps a regenerar-se.",
"audioTranscription": "Transcripció d'àudio sol·licitada amb èxit."
"audioTranscription": "S'ha sol·licitat correctament la transcripció d'àudio. Depenent de la velocitat del vostre servidor Frigate, la transcripció pot trigar una estona a completar-se."
},
"error": {
"regenerate": "No s'ha pogut contactar amb {{provider}} per obtenir una nova descripció: {{errorMessage}}",

View File

@ -28,7 +28,11 @@
"categorizedImage": "Bild erfolgreich klassifiziert",
"trainedModel": "Modell erfolgreich trainiert.",
"trainingModel": "Modelltraining erfolgreich gestartet.",
"updatedModel": "Modellkonfiguration erfolgreich aktualisiert"
"updatedModel": "Modellkonfiguration erfolgreich aktualisiert",
"renamedCategory": "Klasse erfolgreich in {{name}} umbenannt"
},
"error": {
"deleteImageFailed": "Löschen fehlgeschlagen: {{errorMessage}}"
}
}
}

View File

@ -44,6 +44,8 @@
"aria": "Detailansicht umschalten",
"trackedObject_one": "{{count}} Objekt",
"trackedObject_other": "{{count}} Objekte",
"noObjectDetailData": "Keine detaillierten Daten des Objekt verfügbar."
"noObjectDetailData": "Keine detaillierten Daten des Objekt verfügbar.",
"noDataFound": "Keine Detaildaten zur Überprüfung",
"settings": "Detailansicht Einstellungen"
}
}

View File

@ -40,9 +40,9 @@
"deleteModel": {
"title": "Borrar Modelo de Clasificación",
"single": "¿Está seguro de que quiere eliminar {{name}}? Esto borrar permanentemente todos los datos asociados incluidas las imágenes y los datos de entrenamiento. Esta acción no se puede deshacer.",
"desc_one": "¿Estas seguro de que quiere borrar {{count}} modelo/s? Esto borrara permanentemente todos los datos asociados, incluyendo imágenes y datos de entrenamiento. Esta acción no puede ser desehecha.",
"desc_many": "",
"desc_other": ""
"desc_one": "¿Estas seguro de que quiere borrar {{count}} modelo? Esto borrara permanentemente todos los datos asociados, incluyendo imágenes y datos de entrenamiento. Esta acción no puede ser desehecha.",
"desc_many": "¿Estas seguro de que quiere borrar {{count}} modelos? Esto borrara permanentemente todos los datos asociados, incluyendo imágenes y datos de entrenamiento. Esta acción no puede ser desehecha.",
"desc_other": "¿Estas seguro de que quiere borrar {{count}} modelos? Esto borrara permanentemente todos los datos asociados, incluyendo imágenes y datos de entrenamiento. Esta acción no puede ser desehecha."
},
"edit": {
"title": "Editar modelo de clasificación"

View File

@ -85,7 +85,7 @@
"disable": "Ocultar estadísticas de transmisión"
},
"manualRecording": {
"title": "Grabación bajo demanda",
"title": "Bajo demanda",
"tips": "Iniciar un evento manual basado en la configuración de retención de grabaciones de esta cámara.",
"playInBackground": {
"label": "Reproducir en segundo plano",

View File

@ -42,7 +42,7 @@
"regenerate": "Une nouvelle description a été demandée à {{provider}}. Selon la vitesse de votre fournisseur, la régénération de la nouvelle description peut prendre un certain temps.",
"updatedSublabel": "Sous-étiquette mise à jour avec succès",
"updatedLPR": "Plaque d'immatriculation mise à jour avec succès",
"audioTranscription": "Transcription audio demandée avec succès"
"audioTranscription": "Transcription audio demandée avec succès. Selon la vitesse de votre serveur Frigate, la transcription peut prendre un certain temps."
},
"error": {
"regenerate": "Échec de l'appel de {{provider}} pour une nouvelle description : {{errorMessage}}",

View File

@ -105,7 +105,7 @@
"regenerate": "Er is een nieuwe beschrijving aangevraagd bij {{provider}}. Afhankelijk van de snelheid van je provider kan het regenereren van de nieuwe beschrijving enige tijd duren.",
"updatedSublabel": "Sublabel succesvol bijgewerkt.",
"updatedLPR": "Kenteken succesvol bijgewerkt.",
"audioTranscription": "Audiotranscriptie succesvol aangevraagd."
"audioTranscription": "Audio-transcriptie succesvol aangevraagd. Afhankelijk van de snelheid van uw Frigate-server kan het even duren voordat de transcriptie voltooid is."
},
"error": {
"updatedSublabelFailed": "Het is niet gelukt om het sublabel bij te werken: {{errorMessage}}",

View File

@ -104,7 +104,7 @@
"updatedLPR": "Номерний знак успішно оновлено.",
"updatedSublabel": "Підмітку успішно оновлено.",
"regenerate": "Новий опис було запрошено від {{provider}}. Залежно від швидкості вашого провайдера, його перегенерація може зайняти деякий час.",
"audioTranscription": "Запит на аудіотранскрипцію успішно надіслано."
"audioTranscription": "Запит на аудіотранскрипцію успішно надіслано. Залежно від швидкості вашого сервера Frigate, транскрипція може тривати деякий час."
},
"error": {
"regenerate": "Не вдалося звернутися до {{provider}} для отримання нового опису: {{errorMessage}}",

View File

@ -461,6 +461,40 @@ export function useEmbeddingsReindexProgress(
return { payload: data };
}
export function useAudioTranscriptionProcessState(
revalidateOnFocus: boolean = true,
): { payload: string } {
const {
value: { payload },
send: sendCommand,
} = useWs("audio_transcription_state", "audioTranscriptionState");
const data = useDeepMemo(
payload ? (JSON.parse(payload as string) as string) : "idle",
);
useEffect(() => {
let listener = undefined;
if (revalidateOnFocus) {
sendCommand("audioTranscriptionState");
listener = () => {
if (document.visibilityState == "visible") {
sendCommand("audioTranscriptionState");
}
};
addEventListener("visibilitychange", listener);
}
return () => {
if (listener) {
removeEventListener("visibilitychange", listener);
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [revalidateOnFocus]);
return { payload: data || "idle" };
}
export function useBirdseyeLayout(revalidateOnFocus: boolean = true): {
payload: string;
} {

View File

@ -42,6 +42,7 @@ type ObjectData = {
pathPoints: PathPoint[];
currentZones: string[];
currentBox?: number[];
currentAttributeBox?: number[];
};
export default function ObjectTrackOverlay({
@ -105,6 +106,12 @@ export default function ObjectTrackOverlay({
selectedObjectIds.length > 0
? ["event_ids", { ids: selectedObjectIds.join(",") }]
: null,
null,
{
revalidateOnFocus: false,
revalidateOnReconnect: false,
dedupingInterval: 30000,
},
);
// Fetch timeline data for each object ID using fixed number of hooks
@ -112,7 +119,12 @@ export default function ObjectTrackOverlay({
selectedObjectIds.length > 0
? `timeline?source_id=${selectedObjectIds.join(",")}&limit=1000`
: null,
{ revalidateOnFocus: false },
null,
{
revalidateOnFocus: false,
revalidateOnReconnect: false,
dedupingInterval: 30000,
},
);
const getZonesFriendlyNames = (zones: string[], config: FrigateConfig) => {
@ -270,6 +282,7 @@ export default function ObjectTrackOverlay({
);
const currentBox = nearbyTimelineEvent?.data?.box;
const currentAttributeBox = nearbyTimelineEvent?.data?.attribute_box;
return {
objectId,
@ -278,6 +291,7 @@ export default function ObjectTrackOverlay({
pathPoints: combinedPoints,
currentZones,
currentBox,
currentAttributeBox,
};
})
.filter((obj: ObjectData) => obj.pathPoints.length > 0); // Only include objects with path data
@ -482,6 +496,20 @@ export default function ObjectTrackOverlay({
/>
</g>
)}
{objData.currentAttributeBox && showBoundingBoxes && (
<g>
<rect
x={objData.currentAttributeBox[0] * videoWidth}
y={objData.currentAttributeBox[1] * videoHeight}
width={objData.currentAttributeBox[2] * videoWidth}
height={objData.currentAttributeBox[3] * videoHeight}
fill="none"
stroke={objData.color}
strokeWidth={boxStroke}
opacity="0.9"
/>
</g>
)}
</g>
);
})}

View File

@ -92,6 +92,7 @@ import { DialogPortal } from "@radix-ui/react-dialog";
import { useDetailStream } from "@/context/detail-stream-context";
import { PiSlidersHorizontalBold } from "react-icons/pi";
import { HiSparkles } from "react-icons/hi";
import { useAudioTranscriptionProcessState } from "@/api/ws";
const SEARCH_TABS = ["snapshot", "tracking_details"] as const;
export type SearchTab = (typeof SEARCH_TABS)[number];
@ -1076,6 +1077,11 @@ function ObjectDetailsTab({
});
}, [search, t]);
// audio transcription processing state
const { payload: audioTranscriptionProcessState } =
useAudioTranscriptionProcessState();
// frigate+ submission
type SubmissionState = "reviewing" | "uploading" | "submitted";
@ -1431,10 +1437,20 @@ function ObjectDetailsTab({
<TooltipTrigger asChild>
<button
aria-label={t("itemMenu.audioTranscription.label")}
className="text-primary/40 hover:text-primary/80"
className={cn(
"text-primary/40",
audioTranscriptionProcessState === "processing"
? "cursor-not-allowed"
: "hover:text-primary/80",
)}
onClick={onTranscribe}
disabled={audioTranscriptionProcessState === "processing"}
>
<FaMicrophone className="size-4" />
{audioTranscriptionProcessState === "processing" ? (
<ActivityIndicator className="size-4" />
) : (
<FaMicrophone className="size-4" />
)}
</button>
</TooltipTrigger>
<TooltipContent>

View File

@ -75,12 +75,15 @@ export function TrackingDetails({
setIsVideoLoading(true);
}, [event.id]);
const { data: eventSequence } = useSWR<TrackingDetailsSequence[]>([
"timeline",
const { data: eventSequence } = useSWR<TrackingDetailsSequence[]>(
["timeline", { source_id: event.id }],
null,
{
source_id: event.id,
revalidateOnFocus: false,
revalidateOnReconnect: false,
dedupingInterval: 30000,
},
]);
);
const { data: config } = useSWR<FrigateConfig>("config");
@ -104,6 +107,12 @@ export function TrackingDetails({
},
]
: null,
null,
{
revalidateOnFocus: false,
revalidateOnReconnect: false,
dedupingInterval: 30000,
},
);
// Convert a timeline timestamp to actual video player time, accounting for
@ -714,53 +723,6 @@ export function TrackingDetails({
)}
<div className="space-y-2">
{eventSequence.map((item, idx) => {
const isActive =
Math.abs(
(effectiveTime ?? 0) - (item.timestamp ?? 0),
) <= 0.5;
const formattedEventTimestamp = config
? formatUnixTimestampToDateTime(item.timestamp ?? 0, {
timezone: config.ui.timezone,
date_format:
config.ui.time_format == "24hour"
? t(
"time.formattedTimestampHourMinuteSecond.24hour",
{ ns: "common" },
)
: t(
"time.formattedTimestampHourMinuteSecond.12hour",
{ ns: "common" },
),
time_style: "medium",
date_style: "medium",
})
: "";
const ratio =
Array.isArray(item.data.box) &&
item.data.box.length >= 4
? (
aspectRatio *
(item.data.box[2] / item.data.box[3])
).toFixed(2)
: "N/A";
const areaPx =
Array.isArray(item.data.box) &&
item.data.box.length >= 4
? Math.round(
(config.cameras[event.camera]?.detect?.width ??
0) *
(config.cameras[event.camera]?.detect
?.height ?? 0) *
(item.data.box[2] * item.data.box[3]),
)
: undefined;
const areaPct =
Array.isArray(item.data.box) &&
item.data.box.length >= 4
? (item.data.box[2] * item.data.box[3]).toFixed(4)
: undefined;
return (
<div
key={`${item.timestamp}-${item.source_id ?? ""}-${idx}`}
@ -770,11 +732,7 @@ export function TrackingDetails({
>
<LifecycleIconRow
item={item}
isActive={isActive}
formattedEventTimestamp={formattedEventTimestamp}
ratio={ratio}
areaPx={areaPx}
areaPct={areaPct}
event={event}
onClick={() => handleLifecycleClick(item)}
setSelectedZone={setSelectedZone}
getZoneColor={getZoneColor}
@ -798,11 +756,7 @@ export function TrackingDetails({
type LifecycleIconRowProps = {
item: TrackingDetailsSequence;
isActive?: boolean;
formattedEventTimestamp: string;
ratio: string;
areaPx?: number;
areaPct?: string;
event: Event;
onClick: () => void;
setSelectedZone: (z: string) => void;
getZoneColor: (zoneName: string) => number[] | undefined;
@ -812,11 +766,7 @@ type LifecycleIconRowProps = {
function LifecycleIconRow({
item,
isActive,
formattedEventTimestamp,
ratio,
areaPx,
areaPct,
event,
onClick,
setSelectedZone,
getZoneColor,
@ -826,9 +776,101 @@ function LifecycleIconRow({
const { t } = useTranslation(["views/explore", "components/player"]);
const { data: config } = useSWR<FrigateConfig>("config");
const [isOpen, setIsOpen] = useState(false);
const navigate = useNavigate();
const aspectRatio = useMemo(() => {
if (!config) {
return 16 / 9;
}
return (
config.cameras[event.camera].detect.width /
config.cameras[event.camera].detect.height
);
}, [config, event]);
const isActive = useMemo(
() => Math.abs((effectiveTime ?? 0) - (item.timestamp ?? 0)) <= 0.5,
[effectiveTime, item.timestamp],
);
const formattedEventTimestamp = useMemo(
() =>
config
? formatUnixTimestampToDateTime(item.timestamp ?? 0, {
timezone: config.ui.timezone,
date_format:
config.ui.time_format == "24hour"
? t("time.formattedTimestampHourMinuteSecond.24hour", {
ns: "common",
})
: t("time.formattedTimestampHourMinuteSecond.12hour", {
ns: "common",
}),
time_style: "medium",
date_style: "medium",
})
: "",
[config, item.timestamp, t],
);
const ratio = useMemo(
() =>
Array.isArray(item.data.box) && item.data.box.length >= 4
? (aspectRatio * (item.data.box[2] / item.data.box[3])).toFixed(2)
: "N/A",
[aspectRatio, item.data.box],
);
const areaPx = useMemo(
() =>
Array.isArray(item.data.box) && item.data.box.length >= 4
? Math.round(
(config?.cameras[event.camera]?.detect?.width ?? 0) *
(config?.cameras[event.camera]?.detect?.height ?? 0) *
(item.data.box[2] * item.data.box[3]),
)
: undefined,
[config, event.camera, item.data.box],
);
const attributeAreaPx = useMemo(
() =>
Array.isArray(item.data.attribute_box) &&
item.data.attribute_box.length >= 4
? Math.round(
(config?.cameras[event.camera]?.detect?.width ?? 0) *
(config?.cameras[event.camera]?.detect?.height ?? 0) *
(item.data.attribute_box[2] * item.data.attribute_box[3]),
)
: undefined,
[config, event.camera, item.data.attribute_box],
);
const attributeAreaPct = useMemo(
() =>
Array.isArray(item.data.attribute_box) &&
item.data.attribute_box.length >= 4
? (item.data.attribute_box[2] * item.data.attribute_box[3]).toFixed(4)
: undefined,
[item.data.attribute_box],
);
const areaPct = useMemo(
() =>
Array.isArray(item.data.box) && item.data.box.length >= 4
? (item.data.box[2] * item.data.box[3]).toFixed(4)
: undefined,
[item.data.box],
);
const score = useMemo(() => {
if (item.data.score !== undefined) {
return (item.data.score * 100).toFixed(0) + "%";
}
return "N/A";
}, [item.data.score]);
return (
<div
role="button"
@ -856,16 +898,28 @@ function LifecycleIconRow({
<div className="text-md flex items-start break-words text-left">
{getLifecycleItemDescription(item)}
</div>
<div className="mt-1 flex flex-wrap items-center gap-2 text-xs text-secondary-foreground md:gap-5">
<div className="flex items-center gap-1">
<div className="my-2 ml-2 flex flex-col flex-wrap items-start gap-1.5 text-xs text-secondary-foreground">
<div className="flex items-center gap-1.5">
<span className="text-primary-variant">
{t("trackingDetails.lifecycleItemDesc.header.score")}
</span>
<span className="font-medium text-primary">{score}</span>
</div>
<div className="flex items-center gap-1.5">
<span className="text-primary-variant">
{t("trackingDetails.lifecycleItemDesc.header.ratio")}
</span>
<span className="font-medium text-primary">{ratio}</span>
</div>
<div className="flex items-center gap-1">
<div className="flex items-center gap-1.5">
<span className="text-primary-variant">
{t("trackingDetails.lifecycleItemDesc.header.area")}
{t("trackingDetails.lifecycleItemDesc.header.area")}{" "}
{attributeAreaPx !== undefined &&
attributeAreaPct !== undefined && (
<span className="text-primary-variant">
({getTranslatedLabel(item.data.label)})
</span>
)}
</span>
{areaPx !== undefined && areaPct !== undefined ? (
<span className="font-medium text-primary">
@ -876,9 +930,25 @@ function LifecycleIconRow({
<span>N/A</span>
)}
</div>
{attributeAreaPx !== undefined &&
attributeAreaPct !== undefined && (
<div className="flex items-center gap-1.5">
<span className="text-primary-variant">
{t("trackingDetails.lifecycleItemDesc.header.area")} (
{getTranslatedLabel(item.data.attribute)})
</span>
<span className="font-medium text-primary">
{t("information.pixels", {
ns: "common",
area: attributeAreaPx,
})}{" "}
· {attributeAreaPct}%
</span>
</div>
)}
{item.data?.zones && item.data.zones.length > 0 && (
<div className="flex flex-wrap items-center gap-2">
<div className="mt-1 flex flex-wrap items-center gap-2">
{item.data.zones.map((zone, zidx) => {
const color = getZoneColor(zone)?.join(",") ?? "0,0,0";
return (

View File

@ -82,6 +82,7 @@ function MSEPlayer({
[key: string]: (msg: { value: string; type: string }) => void;
}>({});
const msRef = useRef<MediaSource | null>(null);
const mseCodecRef = useRef<string | null>(null);
const wsURL = useMemo(() => {
return `${baseUrl.replace(/^http/, "ws")}live/mse/api/ws?src=${camera}`;
@ -93,6 +94,10 @@ function MSEPlayer({
console.error(
`${camera} - MSE error '${error}': ${description} See the documentation: https://docs.frigate.video/configuration/live/#live-player-error-messages`,
);
if (mseCodecRef.current) {
// eslint-disable-next-line no-console
console.error(`${camera} - MSE codec in use: ${mseCodecRef.current}`);
}
onError?.(error);
},
[camera, onError],
@ -299,6 +304,9 @@ function MSEPlayer({
onmessageRef.current["mse"] = (msg) => {
if (msg.type !== "mse") return;
// Store the codec value for error logging
mseCodecRef.current = msg.value;
let sb: SourceBuffer | undefined;
try {
sb = msRef.current?.addSourceBuffer(msg.value);

View File

@ -16,6 +16,7 @@ export type TrackingDetailsSequence = {
data: {
camera: string;
label: string;
score: number;
sub_label: string;
box?: [number, number, number, number];
region: [number, number, number, number];

View File

@ -1376,329 +1376,343 @@ function FrigateCameraFeatures({
title={t("cameraSettings.title", { camera })}
/>
</DrawerTrigger>
<DrawerContent className="rounded-2xl px-2 py-4">
<div className="mt-2 flex flex-col gap-2">
{isAdmin && (
<>
<FilterSwitch
label={t("cameraSettings.cameraEnabled")}
isChecked={enabledState == "ON"}
onCheckedChange={() =>
sendEnabled(enabledState == "ON" ? "OFF" : "ON")
}
/>
<FilterSwitch
label={t("cameraSettings.objectDetection")}
isChecked={detectState == "ON"}
onCheckedChange={() =>
sendDetect(detectState == "ON" ? "OFF" : "ON")
}
/>
{recordingEnabled && (
<DrawerContent className="max-h-[75dvh] overflow-hidden rounded-2xl">
<div className="scrollbar-container mt-2 flex h-auto flex-col gap-2 overflow-y-auto px-2 py-4">
<>
{isAdmin && (
<>
<FilterSwitch
label={t("cameraSettings.recording")}
isChecked={recordState == "ON"}
label={t("cameraSettings.cameraEnabled")}
isChecked={enabledState == "ON"}
onCheckedChange={() =>
sendRecord(recordState == "ON" ? "OFF" : "ON")
sendEnabled(enabledState == "ON" ? "OFF" : "ON")
}
/>
)}
<FilterSwitch
label={t("cameraSettings.snapshots")}
isChecked={snapshotState == "ON"}
onCheckedChange={() =>
sendSnapshot(snapshotState == "ON" ? "OFF" : "ON")
}
/>
{audioDetectEnabled && (
<FilterSwitch
label={t("cameraSettings.audioDetection")}
isChecked={audioState == "ON"}
label={t("cameraSettings.objectDetection")}
isChecked={detectState == "ON"}
onCheckedChange={() =>
sendAudio(audioState == "ON" ? "OFF" : "ON")
sendDetect(detectState == "ON" ? "OFF" : "ON")
}
/>
)}
{audioDetectEnabled && transcriptionEnabled && (
{recordingEnabled && (
<FilterSwitch
label={t("cameraSettings.recording")}
isChecked={recordState == "ON"}
onCheckedChange={() =>
sendRecord(recordState == "ON" ? "OFF" : "ON")
}
/>
)}
<FilterSwitch
label={t("cameraSettings.transcription")}
disabled={audioState == "OFF"}
isChecked={transcriptionState == "ON"}
label={t("cameraSettings.snapshots")}
isChecked={snapshotState == "ON"}
onCheckedChange={() =>
sendTranscription(transcriptionState == "ON" ? "OFF" : "ON")
sendSnapshot(snapshotState == "ON" ? "OFF" : "ON")
}
/>
)}
{autotrackingEnabled && (
<FilterSwitch
label={t("cameraSettings.autotracking")}
isChecked={autotrackingState == "ON"}
onCheckedChange={() =>
sendAutotracking(autotrackingState == "ON" ? "OFF" : "ON")
}
/>
)}
</>
)}
</div>
{audioDetectEnabled && (
<FilterSwitch
label={t("cameraSettings.audioDetection")}
isChecked={audioState == "ON"}
onCheckedChange={() =>
sendAudio(audioState == "ON" ? "OFF" : "ON")
}
/>
)}
{audioDetectEnabled && transcriptionEnabled && (
<FilterSwitch
label={t("cameraSettings.transcription")}
disabled={audioState == "OFF"}
isChecked={transcriptionState == "ON"}
onCheckedChange={() =>
sendTranscription(
transcriptionState == "ON" ? "OFF" : "ON",
)
}
/>
)}
{autotrackingEnabled && (
<FilterSwitch
label={t("cameraSettings.autotracking")}
isChecked={autotrackingState == "ON"}
onCheckedChange={() =>
sendAutotracking(autotrackingState == "ON" ? "OFF" : "ON")
}
/>
)}
</>
)}
<div className="mt-3 flex flex-col gap-5">
{!isRestreamed && (
<div className="flex flex-col gap-2 p-2">
<Label>{t("stream.title")}</Label>
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
<LuX className="size-4 text-danger" />
<div>
{t("streaming.restreaming.disabled", {
ns: "components/dialog",
})}
</div>
<Popover>
<PopoverTrigger asChild>
<div className="cursor-pointer p-0">
<LuInfo className="size-4" />
<span className="sr-only">
{t("button.info", { ns: "common" })}
</span>
</div>
</PopoverTrigger>
<PopoverContent className="w-80 text-xs">
{t("streaming.restreaming.desc.title", {
ns: "components/dialog",
})}
<div className="mt-2 flex items-center text-primary">
<Link
to={getLocaleDocUrl("configuration/live")}
target="_blank"
rel="noopener noreferrer"
className="inline"
>
{t("readTheDocumentation", { ns: "common" })}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</div>
</div>
)}
{isRestreamed && Object.values(camera.live.streams).length > 0 && (
<div className="mt-1 p-2">
<div className="mb-1 text-sm">{t("stream.title")}</div>
<Select
value={streamName}
onValueChange={(value) => {
setStreamName?.(value);
}}
disabled={debug}
>
<SelectTrigger className="w-full">
<SelectValue>
{Object.keys(camera.live.streams).find(
(key) => camera.live.streams[key] === streamName,
)}
</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectGroup>
{Object.entries(camera.live.streams).map(
([stream, name]) => (
<SelectItem
key={stream}
className="cursor-pointer"
value={name}
>
{stream}
</SelectItem>
),
)}
</SelectGroup>
</SelectContent>
</Select>
{debug && (
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
<>
<LuX className="size-8 text-danger" />
<div>{t("stream.debug.picker")}</div>
</>
</div>
)}
{preferredLiveMode != "jsmpeg" && !debug && isRestreamed && (
<div className="mt-1 flex flex-row items-center gap-1 text-sm text-muted-foreground">
{supportsAudioOutput ? (
<>
<LuCheck className="size-4 text-success" />
<div>{t("stream.audio.available")}</div>
</>
) : (
<>
<LuX className="size-4 text-danger" />
<div>{t("stream.audio.unavailable")}</div>
<Popover>
<PopoverTrigger asChild>
<div className="cursor-pointer p-0">
<LuInfo className="size-4" />
<span className="sr-only">
{t("button.info", { ns: "common" })}
</span>
</div>
</PopoverTrigger>
<PopoverContent className="w-52 text-xs">
{t("stream.audio.tips.title")}
<div className="mt-2 flex items-center text-primary">
<Link
to={getLocaleDocUrl("configuration/live")}
target="_blank"
rel="noopener noreferrer"
className="inline"
>
{t("readTheDocumentation", { ns: "common" })}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</>
)}
</div>
)}
{preferredLiveMode != "jsmpeg" &&
!debug &&
isRestreamed &&
supportsAudioOutput && (
<div className="mt-3 flex flex-col gap-5">
{!isRestreamed && (
<div className="flex flex-col gap-2 p-2">
<Label>{t("stream.title")}</Label>
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
{supports2WayTalk ? (
<>
<LuCheck className="size-4 text-success" />
<div>{t("stream.twoWayTalk.available")}</div>
</>
) : (
<>
<LuX className="size-4 text-danger" />
<div>{t("stream.twoWayTalk.unavailable")}</div>
<Popover>
<PopoverTrigger asChild>
<div className="cursor-pointer p-0">
<LuInfo className="size-4" />
<span className="sr-only">
{t("button.info", { ns: "common" })}
</span>
</div>
</PopoverTrigger>
<PopoverContent className="w-52 text-xs">
{t("stream.twoWayTalk.tips")}
<div className="mt-2 flex items-center text-primary">
<Link
to={getLocaleDocUrl(
"configuration/live/#webrtc-extra-configuration",
)}
target="_blank"
rel="noopener noreferrer"
className="inline"
<LuX className="size-4 text-danger" />
<div>
{t("streaming.restreaming.disabled", {
ns: "components/dialog",
})}
</div>
<Popover>
<PopoverTrigger asChild>
<div className="cursor-pointer p-0">
<LuInfo className="size-4" />
<span className="sr-only">
{t("button.info", { ns: "common" })}
</span>
</div>
</PopoverTrigger>
<PopoverContent className="w-80 text-xs">
{t("streaming.restreaming.desc.title", {
ns: "components/dialog",
})}
<div className="mt-2 flex items-center text-primary">
<Link
to={getLocaleDocUrl("configuration/live")}
target="_blank"
rel="noopener noreferrer"
className="inline"
>
{t("readTheDocumentation", { ns: "common" })}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</div>
</div>
)}
{isRestreamed &&
Object.values(camera.live.streams).length > 0 && (
<div className="mt-1 p-2">
<div className="mb-1 text-sm">{t("stream.title")}</div>
<Select
value={streamName}
onValueChange={(value) => {
setStreamName?.(value);
}}
disabled={debug}
>
<SelectTrigger className="w-full">
<SelectValue>
{Object.keys(camera.live.streams).find(
(key) => camera.live.streams[key] === streamName,
)}
</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectGroup>
{Object.entries(camera.live.streams).map(
([stream, name]) => (
<SelectItem
key={stream}
className="cursor-pointer"
value={name}
>
{t("readTheDocumentation", { ns: "common" })}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</>
{stream}
</SelectItem>
),
)}
</SelectGroup>
</SelectContent>
</Select>
{debug && (
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
<>
<LuX className="size-8 text-danger" />
<div>{t("stream.debug.picker")}</div>
</>
</div>
)}
{preferredLiveMode != "jsmpeg" &&
!debug &&
isRestreamed && (
<div className="mt-1 flex flex-row items-center gap-1 text-sm text-muted-foreground">
{supportsAudioOutput ? (
<>
<LuCheck className="size-4 text-success" />
<div>{t("stream.audio.available")}</div>
</>
) : (
<>
<LuX className="size-4 text-danger" />
<div>{t("stream.audio.unavailable")}</div>
<Popover>
<PopoverTrigger asChild>
<div className="cursor-pointer p-0">
<LuInfo className="size-4" />
<span className="sr-only">
{t("button.info", { ns: "common" })}
</span>
</div>
</PopoverTrigger>
<PopoverContent className="w-52 text-xs">
{t("stream.audio.tips.title")}
<div className="mt-2 flex items-center text-primary">
<Link
to={getLocaleDocUrl("configuration/live")}
target="_blank"
rel="noopener noreferrer"
className="inline"
>
{t("readTheDocumentation", {
ns: "common",
})}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</>
)}
</div>
)}
{preferredLiveMode != "jsmpeg" &&
!debug &&
isRestreamed &&
supportsAudioOutput && (
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
{supports2WayTalk ? (
<>
<LuCheck className="size-4 text-success" />
<div>{t("stream.twoWayTalk.available")}</div>
</>
) : (
<>
<LuX className="size-4 text-danger" />
<div>{t("stream.twoWayTalk.unavailable")}</div>
<Popover>
<PopoverTrigger asChild>
<div className="cursor-pointer p-0">
<LuInfo className="size-4" />
<span className="sr-only">
{t("button.info", { ns: "common" })}
</span>
</div>
</PopoverTrigger>
<PopoverContent className="w-52 text-xs">
{t("stream.twoWayTalk.tips")}
<div className="mt-2 flex items-center text-primary">
<Link
to={getLocaleDocUrl(
"configuration/live/#webrtc-extra-configuration",
)}
target="_blank"
rel="noopener noreferrer"
className="inline"
>
{t("readTheDocumentation", {
ns: "common",
})}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</>
)}
</div>
)}
{preferredLiveMode == "jsmpeg" && isRestreamed && (
<div className="mt-2 flex flex-col items-center gap-3">
<div className="flex flex-row items-center gap-2">
<IoIosWarning className="mr-1 size-8 text-danger" />
<p className="text-sm">
{t("stream.lowBandwidth.tips")}
</p>
</div>
<Button
className={`flex items-center gap-2.5 rounded-lg`}
aria-label={t("stream.lowBandwidth.resetStream")}
variant="outline"
size="sm"
disabled={debug}
onClick={() => setLowBandwidth(false)}
>
<MdOutlineRestartAlt className="size-5 text-primary-variant" />
<div className="text-primary-variant">
{t("stream.lowBandwidth.resetStream")}
</div>
</Button>
</div>
)}
</div>
)}
{preferredLiveMode == "jsmpeg" && isRestreamed && (
<div className="mt-2 flex flex-col items-center gap-3">
<div className="flex flex-row items-center gap-2">
<IoIosWarning className="mr-1 size-8 text-danger" />
<p className="text-sm">{t("stream.lowBandwidth.tips")}</p>
</div>
<div className="flex flex-col gap-1 px-2">
<div className="mb-1 text-sm font-medium leading-none">
{t("manualRecording.title")}
</div>
<div className="flex flex-row items-stretch gap-2">
<Button
className={`flex items-center gap-2.5 rounded-lg`}
aria-label={t("stream.lowBandwidth.resetStream")}
variant="outline"
size="sm"
disabled={debug}
onClick={() => setLowBandwidth(false)}
onClick={handleSnapshotClick}
disabled={!cameraEnabled || debug || isSnapshotLoading}
className="h-auto w-full whitespace-normal"
>
<MdOutlineRestartAlt className="size-5 text-primary-variant" />
<div className="text-primary-variant">
{t("stream.lowBandwidth.resetStream")}
</div>
{isSnapshotLoading && (
<ActivityIndicator className="mr-2 size-4" />
)}
{t("snapshot.takeSnapshot")}
</Button>
<Button
onClick={handleEventButtonClick}
className={cn(
"h-auto w-full whitespace-normal",
isRecording &&
"animate-pulse bg-red-500 hover:bg-red-600",
)}
disabled={debug}
>
{t("manualRecording." + (isRecording ? "end" : "start"))}
</Button>
</div>
<p className="text-sm text-muted-foreground">
{t("manualRecording.tips")}
</p>
</div>
{isRestreamed && (
<>
<div className="flex flex-col gap-2">
<FilterSwitch
label={t("manualRecording.playInBackground.label")}
isChecked={playInBackground}
onCheckedChange={(checked) => {
setPlayInBackground(checked);
}}
disabled={debug}
/>
<p className="mx-2 -mt-2 text-sm text-muted-foreground">
{t("manualRecording.playInBackground.desc")}
</p>
</div>
<div className="flex flex-col gap-2">
<FilterSwitch
label={t("manualRecording.showStats.label")}
isChecked={showStats}
onCheckedChange={(checked) => {
setShowStats(checked);
}}
disabled={debug}
/>
<p className="mx-2 -mt-2 text-sm text-muted-foreground">
{t("manualRecording.showStats.desc")}
</p>
</div>
</>
)}
</div>
)}
<div className="flex flex-col gap-1 px-2">
<div className="mb-1 text-sm font-medium leading-none">
{t("manualRecording.title")}
</div>
<div className="flex flex-row items-stretch gap-2">
<Button
onClick={handleSnapshotClick}
disabled={!cameraEnabled || debug || isSnapshotLoading}
className="h-auto w-full whitespace-normal"
>
{isSnapshotLoading && (
<ActivityIndicator className="mr-2 size-4" />
)}
{t("snapshot.takeSnapshot")}
</Button>
<Button
onClick={handleEventButtonClick}
className={cn(
"h-auto w-full whitespace-normal",
isRecording && "animate-pulse bg-red-500 hover:bg-red-600",
)}
disabled={debug}
>
{t("manualRecording." + (isRecording ? "end" : "start"))}
</Button>
</div>
<p className="text-sm text-muted-foreground">
{t("manualRecording.tips")}
</p>
</div>
{isRestreamed && (
<>
<div className="flex flex-col gap-2">
<div className="mb-3 flex flex-col">
<FilterSwitch
label={t("manualRecording.playInBackground.label")}
isChecked={playInBackground}
onCheckedChange={(checked) => {
setPlayInBackground(checked);
}}
disabled={debug}
label={t("streaming.debugView", { ns: "components/dialog" })}
isChecked={debug}
onCheckedChange={(checked) => setDebug(checked)}
/>
<p className="mx-2 -mt-2 text-sm text-muted-foreground">
{t("manualRecording.playInBackground.desc")}
</p>
</div>
<div className="flex flex-col gap-2">
<FilterSwitch
label={t("manualRecording.showStats.label")}
isChecked={showStats}
onCheckedChange={(checked) => {
setShowStats(checked);
}}
disabled={debug}
/>
<p className="mx-2 -mt-2 text-sm text-muted-foreground">
{t("manualRecording.showStats.desc")}
</p>
</div>
</>
)}
<div className="mb-3 flex flex-col">
<FilterSwitch
label={t("streaming.debugView", { ns: "components/dialog" })}
isChecked={debug}
onCheckedChange={(checked) => setDebug(checked)}
/>
</div>
</div>
</>
</div>
</DrawerContent>
</Drawer>

View File

@ -784,7 +784,7 @@ export default function AuthenticationView({
return (
<div className="flex size-full flex-col">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none md:mr-3 md:mt-0">
<div className="scrollbar-container order-last mb-2 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none md:mr-3 md:mt-0">
{section === "users" && UsersSection}
{section === "roles" && RolesSection}
{!section && (

View File

@ -65,7 +65,7 @@ export default function CameraManagementView({
closeButton
/>
<div className="flex size-full flex-col md:flex-row">
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<div className="scrollbar-container order-last mb-2 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
{viewMode === "settings" ? (
<>
<Heading as="h4" className="mb-2">

View File

@ -298,7 +298,7 @@ export default function CameraReviewSettingsView({
<>
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<div className="scrollbar-container order-last mb-2 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<Heading as="h4" className="mb-2">
{t("cameraReview.title")}
</Heading>

View File

@ -244,7 +244,7 @@ export default function EnrichmentsSettingsView({
return (
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<div className="scrollbar-container order-last mb-2 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<Heading as="h4" className="mb-2">
{t("enrichments.title")}
</Heading>

View File

@ -211,7 +211,7 @@ export default function FrigatePlusSettingsView({
<>
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<div className="scrollbar-container order-last mb-2 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<Heading as="h4" className="mb-2">
{t("frigatePlus.title")}
</Heading>

View File

@ -434,7 +434,7 @@ export default function MasksAndZonesView({
{cameraConfig && editingPolygons && (
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mr-3 md:mt-0 md:w-3/12">
<div className="scrollbar-container order-last mb-2 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mr-3 md:mt-0 md:w-3/12">
{editPane == "zone" && (
<ZoneEditPane
polygons={editingPolygons}

View File

@ -191,7 +191,7 @@ export default function MotionTunerView({
return (
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mr-3 md:mt-0 md:w-3/12">
<div className="scrollbar-container order-last mb-2 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mr-3 md:mt-0 md:w-3/12">
<Heading as="h4" className="mb-2">
{t("motionDetectionTuner.title")}
</Heading>

View File

@ -331,7 +331,7 @@ export default function NotificationView({
if (!("Notification" in window) || !window.isSecureContext) {
return (
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<div className="scrollbar-container order-last mb-2 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<div className="grid w-full grid-cols-1 gap-4 md:grid-cols-2">
<div className="col-span-1">
<Heading as="h4" className="mb-2">
@ -385,7 +385,7 @@ export default function NotificationView({
<>
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto px-2 md:order-none">
<div className="scrollbar-container order-last mb-2 mt-2 flex h-full w-full flex-col overflow-y-auto px-2 md:order-none">
<div
className={cn(
isAdmin && "grid w-full grid-cols-1 gap-4 md:grid-cols-2",

View File

@ -164,7 +164,7 @@ export default function ObjectSettingsView({
return (
<div className="mt-1 flex size-full flex-col pb-2 md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0 md:w-3/12">
<div className="scrollbar-container order-last mb-2 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0 md:w-3/12">
<Heading as="h4" className="mb-2">
{t("debug.title")}
</Heading>
@ -434,7 +434,7 @@ function ObjectList({ cameraConfig, objects }: ObjectListProps) {
{t("debug.objectShapeFilterDrawing.area")}
</p>
{obj.area ? (
<>
<div className="text-end">
<div className="text-xs">
px: {obj.area.toString()}
</div>
@ -448,7 +448,7 @@ function ObjectList({ cameraConfig, objects }: ObjectListProps) {
.toFixed(4)
.toString()}
</div>
</>
</div>
) : (
"-"
)}

View File

@ -440,7 +440,7 @@ export default function TriggerView({
return (
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none md:mr-3 md:mt-0">
<div className="scrollbar-container order-last mb-2 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none md:mr-3 md:mt-0">
{!isSemanticSearchEnabled ? (
<div className="mb-5 flex flex-row items-center justify-between gap-2">
<div className="flex flex-col items-start">

View File

@ -108,7 +108,7 @@ export default function UiSettingsView() {
<>
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<div className="scrollbar-container order-last mb-2 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<Heading as="h4" className="mb-2">
{t("general.title")}
</Heading>