mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	UI tweaks (#17685)
* Fix i18n key * ensure license_plate is added to filter list for dedicated lpr cameras * add ability to use browser back button to close MobilePage * add license_plate to review filter * remove overlay state hook in review * don't zoom text on iOS
This commit is contained in:
		
							parent
							
								
									ea98785097
								
							
						
					
					
						commit
						e09f0a6b11
					
				| @ -93,6 +93,10 @@ export default function ReviewFilterGroup({ | ||||
|         labels.add(label); | ||||
|       }); | ||||
| 
 | ||||
|       if (cameraConfig.type == "lpr") { | ||||
|         labels.add("license_plate"); | ||||
|       } | ||||
| 
 | ||||
|       if (cameraConfig.audio.enabled_in_config) { | ||||
|         cameraConfig.audio.listen.forEach((label) => { | ||||
|           labels.add(label); | ||||
|  | ||||
| @ -69,6 +69,10 @@ export default function SearchFilterGroup({ | ||||
|         } | ||||
|       }); | ||||
| 
 | ||||
|       if (cameraConfig.type == "lpr") { | ||||
|         labels.add("license_plate"); | ||||
|       } | ||||
| 
 | ||||
|       if (cameraConfig.audio.enabled_in_config) { | ||||
|         cameraConfig.audio.listen.forEach((label) => { | ||||
|           labels.add(label); | ||||
|  | ||||
| @ -1,4 +1,10 @@ | ||||
| import { createContext, useContext, useEffect, useState } from "react"; | ||||
| import { | ||||
|   createContext, | ||||
|   useContext, | ||||
|   useEffect, | ||||
|   useState, | ||||
|   useCallback, | ||||
| } from "react"; | ||||
| import { createPortal } from "react-dom"; | ||||
| import { motion, AnimatePresence } from "framer-motion"; | ||||
| import { IoMdArrowRoundBack } from "react-icons/io"; | ||||
| @ -6,6 +12,7 @@ import { cn } from "@/lib/utils"; | ||||
| import { isPWA } from "@/utils/isPWA"; | ||||
| import { Button } from "@/components/ui/button"; | ||||
| import { useTranslation } from "react-i18next"; | ||||
| import { useLocation } from "react-router-dom"; | ||||
| 
 | ||||
| const MobilePageContext = createContext<{ | ||||
|   open: boolean; | ||||
| @ -24,16 +31,48 @@ export function MobilePage({ | ||||
|   onOpenChange, | ||||
| }: MobilePageProps) { | ||||
|   const [uncontrolledOpen, setUncontrolledOpen] = useState(false); | ||||
|   const location = useLocation(); | ||||
| 
 | ||||
|   const open = controlledOpen ?? uncontrolledOpen; | ||||
|   const setOpen = (value: boolean) => { | ||||
|   const setOpen = useCallback( | ||||
|     (value: boolean) => { | ||||
|       if (onOpenChange) { | ||||
|         onOpenChange(value); | ||||
|       } else { | ||||
|         setUncontrolledOpen(value); | ||||
|       } | ||||
|     }, | ||||
|     [onOpenChange, setUncontrolledOpen], | ||||
|   ); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     let isActive = true; | ||||
| 
 | ||||
|     if (open && isActive) { | ||||
|       window.history.pushState({ isMobilePage: true }, "", location.pathname); | ||||
|     } | ||||
| 
 | ||||
|     const handlePopState = (event: PopStateEvent) => { | ||||
|       if (open && isActive) { | ||||
|         event.preventDefault(); | ||||
|         setOpen(false); | ||||
|         // Delay replaceState to ensure state updates are processed
 | ||||
|         setTimeout(() => { | ||||
|           if (isActive) { | ||||
|             window.history.replaceState(null, "", location.pathname); | ||||
|           } | ||||
|         }, 0); | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     window.addEventListener("popstate", handlePopState); | ||||
| 
 | ||||
|     return () => { | ||||
|       isActive = false; | ||||
|       window.removeEventListener("popstate", handlePopState); | ||||
|     }; | ||||
|   }, [open, setOpen, location.pathname]); | ||||
| 
 | ||||
|   return ( | ||||
|     <MobilePageContext.Provider value={{ open, onOpenChange: setOpen }}> | ||||
|       {children} | ||||
|  | ||||
| @ -200,9 +200,9 @@ export function AnnotationSettingsPane({ | ||||
|                       /> | ||||
|                     </FormControl> | ||||
|                     <FormDescription> | ||||
|                       {t( | ||||
|                         "objectLifecycle.annotationSettings.offset.millisecondsToOffset", | ||||
|                       )} | ||||
|                       <Trans ns="views/explore"> | ||||
|                         objectLifecycle.annotationSettings.offset.millisecondsToOffset | ||||
|                       </Trans> | ||||
|                       <div className="mt-2"> | ||||
|                         {t("objectLifecycle.annotationSettings.offset.tips")} | ||||
|                       </div> | ||||
|  | ||||
| @ -37,7 +37,6 @@ import { | ||||
|   MobilePageHeader, | ||||
|   MobilePageTitle, | ||||
| } from "@/components/mobile/MobilePage"; | ||||
| import { useOverlayState } from "@/hooks/use-overlay-state"; | ||||
| import { DownloadVideoButton } from "@/components/button/DownloadVideoButton"; | ||||
| import { TooltipPortal } from "@radix-ui/react-tooltip"; | ||||
| import { LuSearch } from "react-icons/lu"; | ||||
| @ -109,10 +108,7 @@ export default function ReviewDetailDialog({ | ||||
| 
 | ||||
|   // dialog and mobile page
 | ||||
| 
 | ||||
|   const [isOpen, setIsOpen] = useOverlayState( | ||||
|     "reviewPane", | ||||
|     review != undefined, | ||||
|   ); | ||||
|   const [isOpen, setIsOpen] = useState(review != undefined); | ||||
| 
 | ||||
|   const handleOpenChange = useCallback( | ||||
|     (open: boolean) => { | ||||
|  | ||||
| @ -884,7 +884,7 @@ function ObjectDetailsTab({ | ||||
|           <> | ||||
|             <div className="text-sm text-primary/40"></div> | ||||
|             <Textarea | ||||
|               className="h-64" | ||||
|               className="text-md h-64" | ||||
|               placeholder={t("details.description.placeholder")} | ||||
|               value={desc} | ||||
|               onChange={(e) => setDesc(e.target.value)} | ||||
|  | ||||
| @ -241,6 +241,7 @@ export interface CameraConfig { | ||||
|     position: string; | ||||
|     thickness: number; | ||||
|   }; | ||||
|   type: string; | ||||
|   ui: UiConfig; | ||||
|   webui_url: string | null; | ||||
|   zones: { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user