Compare commits

...

3 Commits

Author SHA1 Message Date
Josh Hawkins
da891cfa66 remove duplicate language 2026-02-09 09:42:54 -06:00
Josh Hawkins
92318c79d5 prevent console warnings about missing titles and descriptions
make these invisible with sr-only
2026-02-09 09:42:40 -06:00
Josh Hawkins
1d506c1684 work around radix pointer events issue when dialog is opened from drawer
fixes https://github.com/blakeblackshear/frigate/discussions/21940
2026-02-09 09:42:11 -06:00
4 changed files with 72 additions and 6 deletions

View File

@ -1,6 +1,7 @@
{ {
"restart": { "restart": {
"title": "Are you sure you want to restart Frigate?", "title": "Are you sure you want to restart Frigate?",
"description": "This will briefly stop Frigate while it restarts.",
"button": "Restart", "button": "Restart",
"restarting": { "restarting": {
"title": "Frigate is Restarting", "title": "Frigate is Restarting",

View File

@ -42,12 +42,20 @@ import {
TooltipTrigger, TooltipTrigger,
} from "@/components/ui/tooltip"; } from "@/components/ui/tooltip";
import { isDesktop, isMobile } from "react-device-detect"; import { isDesktop, isMobile } from "react-device-detect";
import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer"; import {
Drawer,
DrawerContent,
DrawerDescription,
DrawerTitle,
DrawerTrigger,
} from "../ui/drawer";
import { import {
Dialog, Dialog,
DialogClose, DialogClose,
DialogContent, DialogContent,
DialogDescription,
DialogPortal, DialogPortal,
DialogTitle,
DialogTrigger, DialogTrigger,
} from "../ui/dialog"; } from "../ui/dialog";
import { TooltipPortal } from "@radix-ui/react-tooltip"; import { TooltipPortal } from "@radix-ui/react-tooltip";
@ -194,6 +202,16 @@ export default function GeneralSettings({ className }: GeneralSettingsProps) {
: "max-h-[75dvh] overflow-hidden p-2" : "max-h-[75dvh] overflow-hidden p-2"
} }
> >
{!isDesktop && (
<>
<DrawerTitle className="sr-only">
{t("menu.settings")}
</DrawerTitle>
<DrawerDescription className="sr-only">
{t("menu.settings")}
</DrawerDescription>
</>
)}
<div className="scrollbar-container w-full flex-col overflow-y-auto overflow-x-hidden"> <div className="scrollbar-container w-full flex-col overflow-y-auto overflow-x-hidden">
{isMobile && ( {isMobile && (
<div className="mb-2"> <div className="mb-2">
@ -355,6 +373,16 @@ export default function GeneralSettings({ className }: GeneralSettingsProps) {
: "scrollbar-container max-h-[75dvh] w-[92%] overflow-y-scroll rounded-lg md:rounded-2xl" : "scrollbar-container max-h-[75dvh] w-[92%] overflow-y-scroll rounded-lg md:rounded-2xl"
} }
> >
{!isDesktop && (
<>
<DialogTitle className="sr-only">
{t("menu.languages")}
</DialogTitle>
<DialogDescription className="sr-only">
{t("menu.languages")}
</DialogDescription>
</>
)}
<span tabIndex={0} className="sr-only" /> <span tabIndex={0} className="sr-only" />
{languages.map(({ code, label }) => ( {languages.map(({ code, label }) => (
<MenuItem <MenuItem
@ -395,6 +423,16 @@ export default function GeneralSettings({ className }: GeneralSettingsProps) {
isDesktop ? "" : "w-[92%] rounded-lg md:rounded-2xl" isDesktop ? "" : "w-[92%] rounded-lg md:rounded-2xl"
} }
> >
{!isDesktop && (
<>
<DialogTitle className="sr-only">
{t("menu.darkMode.label")}
</DialogTitle>
<DialogDescription className="sr-only">
{t("menu.darkMode.label")}
</DialogDescription>
</>
)}
<span tabIndex={0} className="sr-only" /> <span tabIndex={0} className="sr-only" />
<MenuItem <MenuItem
className={ className={
@ -472,6 +510,16 @@ export default function GeneralSettings({ className }: GeneralSettingsProps) {
isDesktop ? "" : "w-[92%] rounded-lg md:rounded-2xl" isDesktop ? "" : "w-[92%] rounded-lg md:rounded-2xl"
} }
> >
{!isDesktop && (
<>
<DialogTitle className="sr-only">
{t("menu.theme.label")}
</DialogTitle>
<DialogDescription className="sr-only">
{t("menu.theme.label")}
</DialogDescription>
</>
)}
<span tabIndex={0} className="sr-only" /> <span tabIndex={0} className="sr-only" />
{colorSchemes.map((scheme) => ( {colorSchemes.map((scheme) => (
<MenuItem <MenuItem

View File

@ -4,6 +4,7 @@ import {
AlertDialogAction, AlertDialogAction,
AlertDialogCancel, AlertDialogCancel,
AlertDialogContent, AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter, AlertDialogFooter,
AlertDialogHeader, AlertDialogHeader,
AlertDialogTitle, AlertDialogTitle,
@ -37,6 +38,12 @@ export default function RestartDialog({
const [restartingSheetOpen, setRestartingSheetOpen] = useState(false); const [restartingSheetOpen, setRestartingSheetOpen] = useState(false);
const [countdown, setCountdown] = useState(60); const [countdown, setCountdown] = useState(60);
const clearBodyPointerEvents = () => {
if (typeof document !== "undefined") {
document.body.style.pointerEvents = "";
}
};
useEffect(() => { useEffect(() => {
setRestartDialogOpen(isOpen); setRestartDialogOpen(isOpen);
}, [isOpen]); }, [isOpen]);
@ -74,14 +81,25 @@ export default function RestartDialog({
<> <>
<AlertDialog <AlertDialog
open={restartDialogOpen} open={restartDialogOpen}
onOpenChange={() => { onOpenChange={(open) => {
setRestartDialogOpen(false); if (!open) {
onClose(); setRestartDialogOpen(false);
onClose();
clearBodyPointerEvents();
}
}} }}
> >
<AlertDialogContent> <AlertDialogContent
onCloseAutoFocus={(event) => {
event.preventDefault();
clearBodyPointerEvents();
}}
>
<AlertDialogHeader> <AlertDialogHeader>
<AlertDialogTitle>{t("restart.title")}</AlertDialogTitle> <AlertDialogTitle>{t("restart.title")}</AlertDialogTitle>
<AlertDialogDescription className="sr-only">
{t("restart.description")}
</AlertDialogDescription>
</AlertDialogHeader> </AlertDialogHeader>
<AlertDialogFooter> <AlertDialogFooter>
<AlertDialogCancel> <AlertDialogCancel>

View File

@ -26,6 +26,5 @@ export const supportedLanguageKeys = [
"lt", "lt",
"uk", "uk",
"cs", "cs",
"sk",
"hu", "hu",
]; ];