Skip to content

Commit

Permalink
Merge branch 'blakeblackshear:dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
weitheng authored Nov 6, 2024
2 parents 421a2cd + fc0fb15 commit 8b66a43
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 108 deletions.
115 changes: 10 additions & 105 deletions web/src/components/menu/GeneralSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "../ui/dropdown-menu";
import { Button } from "../ui/button";

import { Link } from "react-router-dom";
import { CgDarkMode } from "react-icons/cg";
import {
Expand All @@ -33,30 +33,15 @@ import {
useTheme,
} from "@/context/theme-provider";
import { IoColorPalette } from "react-icons/io5";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "../ui/alert-dialog";
import { useEffect, useState } from "react";

import { useState } from "react";
import { useRestart } from "@/api/ws";
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
} from "../ui/sheet";

import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import ActivityIndicator from "../indicators/activity-indicator";
import { isDesktop, isMobile } from "react-device-detect";
import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer";
import {
Expand All @@ -68,8 +53,8 @@ import {
} from "../ui/dialog";
import { TooltipPortal } from "@radix-ui/react-tooltip";
import { cn } from "@/lib/utils";
import { baseUrl } from "@/api/baseUrl";
import useSWR from "swr";
import RestartDialog from "../overlay/dialog/RestartDialog";

type GeneralSettingsProps = {
className?: string;
Expand All @@ -83,35 +68,8 @@ export default function GeneralSettings({ className }: GeneralSettingsProps) {

const { theme, colorScheme, setTheme, setColorScheme } = useTheme();
const [restartDialogOpen, setRestartDialogOpen] = useState(false);
const [restartingSheetOpen, setRestartingSheetOpen] = useState(false);
const [countdown, setCountdown] = useState(60);

const { send: sendRestart } = useRestart();

useEffect(() => {
let countdownInterval: NodeJS.Timeout;

if (restartingSheetOpen) {
countdownInterval = setInterval(() => {
setCountdown((prevCountdown) => prevCountdown - 1);
}, 1000);
}

return () => {
clearInterval(countdownInterval);
};
}, [restartingSheetOpen]);

useEffect(() => {
if (countdown === 0) {
window.location.href = baseUrl;
}
}, [countdown]);

const handleForceReload = () => {
window.location.href = baseUrl;
};

const Container = isDesktop ? DropdownMenu : Drawer;
const Trigger = isDesktop ? DropdownMenuTrigger : DrawerTrigger;
const Content = isDesktop ? DropdownMenuContent : DrawerContent;
Expand Down Expand Up @@ -413,64 +371,11 @@ export default function GeneralSettings({ className }: GeneralSettingsProps) {
</div>
</Content>
</Container>
{restartDialogOpen && (
<AlertDialog
open={restartDialogOpen}
onOpenChange={() => setRestartDialogOpen(false)}
>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Are you sure you want to restart Frigate?
</AlertDialogTitle>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={() => {
setRestartingSheetOpen(true);
sendRestart("restart");
}}
>
Restart
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)}
{restartingSheetOpen && (
<>
<Sheet
open={restartingSheetOpen}
onOpenChange={() => setRestartingSheetOpen(false)}
>
<SheetContent
side="top"
onInteractOutside={(e) => e.preventDefault()}
>
<div className="flex flex-col items-center">
<ActivityIndicator />
<SheetHeader className="mt-5 text-center">
<SheetTitle className="text-center">
Frigate is Restarting
</SheetTitle>
<SheetDescription className="text-center">
<p>This page will reload in {countdown} seconds.</p>
</SheetDescription>
</SheetHeader>
<Button
size="lg"
className="mt-5"
aria-label="Force reload now"
onClick={handleForceReload}
>
Force Reload Now
</Button>
</div>
</SheetContent>
</Sheet>
</>
)}
<RestartDialog
isOpen={restartDialogOpen}
onClose={() => setRestartDialogOpen(false)}
onRestart={() => sendRestart("restart")}
/>
</>
);
}
122 changes: 122 additions & 0 deletions web/src/components/overlay/dialog/RestartDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { useState, useEffect } from "react";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
Sheet,
SheetContent,
SheetHeader,
SheetTitle,
SheetDescription,
} from "@/components/ui/sheet";
import { Button } from "@/components/ui/button";
import ActivityIndicator from "@/components/indicators/activity-indicator";
import { baseUrl } from "@/api/baseUrl";

type RestartDialogProps = {
isOpen: boolean;
onClose: () => void;
onRestart: () => void;
};

export default function RestartDialog({
isOpen,
onClose,
onRestart,
}: RestartDialogProps) {
const [restartDialogOpen, setRestartDialogOpen] = useState(isOpen);
const [restartingSheetOpen, setRestartingSheetOpen] = useState(false);
const [countdown, setCountdown] = useState(60);

useEffect(() => {
setRestartDialogOpen(isOpen);
}, [isOpen]);

useEffect(() => {
let countdownInterval: NodeJS.Timeout;

if (restartingSheetOpen) {
countdownInterval = setInterval(() => {
setCountdown((prevCountdown) => prevCountdown - 1);
}, 1000);
}

return () => {
clearInterval(countdownInterval);
};
}, [restartingSheetOpen]);

useEffect(() => {
if (countdown === 0) {
window.location.href = baseUrl;
}
}, [countdown]);

const handleRestart = () => {
setRestartingSheetOpen(true);
onRestart();
};

const handleForceReload = () => {
window.location.href = baseUrl;
};

return (
<>
<AlertDialog
open={restartDialogOpen}
onOpenChange={() => {
setRestartDialogOpen(false);
onClose();
}}
>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Are you sure you want to restart Frigate?
</AlertDialogTitle>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction onClick={handleRestart}>
Restart
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>

<Sheet
open={restartingSheetOpen}
onOpenChange={() => setRestartingSheetOpen(false)}
>
<SheetContent side="top" onInteractOutside={(e) => e.preventDefault()}>
<div className="flex flex-col items-center">
<ActivityIndicator />
<SheetHeader className="mt-5 text-center">
<SheetTitle className="text-center">
Frigate is Restarting
</SheetTitle>
<SheetDescription className="text-center">
<div>This page will reload in {countdown} seconds.</div>
</SheetDescription>
</SheetHeader>
<Button
size="lg"
className="mt-5"
aria-label="Force reload now"
onClick={handleForceReload}
>
Force Reload Now
</Button>
</div>
</SheetContent>
</Sheet>
</>
);
}
10 changes: 9 additions & 1 deletion web/src/pages/ConfigEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Toaster } from "@/components/ui/sonner";
import { toast } from "sonner";
import { LuCopy, LuSave } from "react-icons/lu";
import { MdOutlineRestartAlt } from "react-icons/md";
import RestartDialog from "@/components/overlay/dialog/RestartDialog";

type SaveOptions = "saveonly" | "restart";

Expand All @@ -33,6 +34,8 @@ function ConfigEditor() {
const configRef = useRef<HTMLDivElement | null>(null);
const schemaConfiguredRef = useRef(false);

const [restartDialogOpen, setRestartDialogOpen] = useState(false);

const onHandleSaveConfig = useCallback(
async (save_option: SaveOptions) => {
if (!editorRef.current) {
Expand Down Expand Up @@ -202,7 +205,7 @@ function ConfigEditor() {
size="sm"
className="flex items-center gap-2"
aria-label="Save and restart"
onClick={() => onHandleSaveConfig("restart")}
onClick={() => setRestartDialogOpen(true)}
>
<div className="relative size-5">
<LuSave className="absolute left-0 top-0 size-3 text-secondary-foreground" />
Expand Down Expand Up @@ -231,6 +234,11 @@ function ConfigEditor() {
<div ref={configRef} className="mt-2 h-[calc(100%-2.75rem)]" />
</div>
<Toaster closeButton={true} />
<RestartDialog
isOpen={restartDialogOpen}
onClose={() => setRestartDialogOpen(false)}
onRestart={() => onHandleSaveConfig("restart")}
/>
</div>
);
}
Expand Down
4 changes: 2 additions & 2 deletions web/src/utils/iconUtil.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
GiDeer,
GiFox,
GiGoat,
GiHummingbird,
GiPolarBear,
GiPostStamp,
GiRabbit,
Expand All @@ -36,6 +35,7 @@ import {
import { LuBox, LuLassoSelect } from "react-icons/lu";
import * as LuIcons from "react-icons/lu";
import { MdRecordVoiceOver } from "react-icons/md";
import { PiBirdFill } from "react-icons/pi";

export function getAttributeLabels(config?: FrigateConfig) {
if (!config) {
Expand Down Expand Up @@ -66,7 +66,7 @@ export function getIconForLabel(label: string, className?: string) {
case "bicycle":
return <FaBicycle key={label} className={className} />;
case "bird":
return <GiHummingbird key={label} className={className} />;
return <PiBirdFill key={label} className={className} />;
case "boat":
return <GiSailboat key={label} className={className} />;
case "bus":
Expand Down
1 change: 1 addition & 0 deletions web/src/utils/stringUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export const capitalizeFirstLetter = (text: string): string => {

export const capitalizeAll = (text: string): string => {
return text
.replaceAll("_", " ")
.split(" ")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");
Expand Down

0 comments on commit 8b66a43

Please sign in to comment.