mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	
							parent
							
								
									402f5fa142
								
							
						
					
					
						commit
						16f1c575d7
					
				| @ -116,7 +116,7 @@ export default function Statusbar() { | ||||
|           ); | ||||
|         })} | ||||
|       </div> | ||||
|       <div className="flex h-full items-center gap-2 max-w-[50%] overflow-x-auto no-scrollbar"> | ||||
|       <div className="no-scrollbar flex h-full max-w-[50%] items-center gap-2 overflow-x-auto"> | ||||
|         {Object.entries(messages).length === 0 ? ( | ||||
|           <div className="flex items-center gap-2 text-sm"> | ||||
|             <FaCheck className="size-3 text-green-500" /> | ||||
| @ -129,7 +129,7 @@ export default function Statusbar() { | ||||
|                 const message = ( | ||||
|                   <div | ||||
|                     key={text} | ||||
|                     className={`flex items-center gap-2 text-sm whitespace-nowrap ${link ? "cursor-pointer hover:underline" : ""}`} | ||||
|                     className={`flex items-center gap-2 whitespace-nowrap text-sm ${link ? "cursor-pointer hover:underline" : ""}`} | ||||
|                   > | ||||
|                     <IoIosWarning | ||||
|                       className={`size-5 ${color || "text-danger"}`} | ||||
|  | ||||
| @ -34,55 +34,51 @@ export default function AccountSettings({ className }: AccountSettingsProps) { | ||||
|   const MenuItem = isDesktop ? DropdownMenuItem : DialogClose; | ||||
| 
 | ||||
|   return ( | ||||
|     <div className={className}> | ||||
|       <Container> | ||||
|         <Trigger asChild> | ||||
|           <a href="#"> | ||||
|             <Tooltip> | ||||
|               <TooltipTrigger asChild> | ||||
|                 <div | ||||
|                   className={cn( | ||||
|                     "flex flex-col items-center justify-center", | ||||
|                     isDesktop | ||||
|                       ? "cursor-pointer rounded-lg bg-secondary text-secondary-foreground hover:bg-muted" | ||||
|                       : "text-secondary-foreground", | ||||
|                     className, | ||||
|                   )} | ||||
|                 > | ||||
|                   <VscAccount className="size-5 md:m-[6px]" /> | ||||
|                 </div> | ||||
|               </TooltipTrigger> | ||||
|               <TooltipPortal> | ||||
|                 <TooltipContent side="right"> | ||||
|                   <p>Account</p> | ||||
|                 </TooltipContent> | ||||
|               </TooltipPortal> | ||||
|             </Tooltip> | ||||
|           </a> | ||||
|         </Trigger> | ||||
|         <Content | ||||
|           className={ | ||||
|             isDesktop ? "mr-5 w-72" : "max-h-[75dvh] overflow-hidden p-2" | ||||
|           } | ||||
|         > | ||||
|           <div className="w-full flex-col overflow-y-auto overflow-x-hidden"> | ||||
|             <DropdownMenuLabel> | ||||
|               Current User: {profile?.username || "anonymous"} | ||||
|             </DropdownMenuLabel> | ||||
|             <DropdownMenuSeparator className={isDesktop ? "mt-3" : "mt-1"} /> | ||||
|             <MenuItem | ||||
|               className={ | ||||
|                 isDesktop ? "cursor-pointer" : "flex items-center p-2 text-sm" | ||||
|               } | ||||
|     <Container> | ||||
|       <Trigger asChild> | ||||
|         <Tooltip> | ||||
|           <TooltipTrigger asChild> | ||||
|             <div | ||||
|               className={cn( | ||||
|                 "flex flex-col items-center justify-center", | ||||
|                 isDesktop | ||||
|                   ? "cursor-pointer rounded-lg bg-secondary text-secondary-foreground hover:bg-muted" | ||||
|                   : "text-secondary-foreground", | ||||
|                 className, | ||||
|               )} | ||||
|             > | ||||
|               <a className="flex" href={logoutUrl}> | ||||
|                 <LuLogOut className="mr-2 size-4" /> | ||||
|                 <span>Logout</span> | ||||
|               </a> | ||||
|             </MenuItem> | ||||
|           </div> | ||||
|         </Content> | ||||
|       </Container> | ||||
|     </div> | ||||
|               <VscAccount className="size-5 md:m-[6px]" /> | ||||
|             </div> | ||||
|           </TooltipTrigger> | ||||
|           <TooltipPortal> | ||||
|             <TooltipContent side="right"> | ||||
|               <p>Account</p> | ||||
|             </TooltipContent> | ||||
|           </TooltipPortal> | ||||
|         </Tooltip> | ||||
|       </Trigger> | ||||
|       <Content | ||||
|         className={ | ||||
|           isDesktop ? "mr-5 w-72" : "max-h-[75dvh] overflow-hidden p-2" | ||||
|         } | ||||
|       > | ||||
|         <div className="w-full flex-col overflow-y-auto overflow-x-hidden"> | ||||
|           <DropdownMenuLabel> | ||||
|             Current User: {profile?.username || "anonymous"} | ||||
|           </DropdownMenuLabel> | ||||
|           <DropdownMenuSeparator className={isDesktop ? "mt-3" : "mt-1"} /> | ||||
|           <MenuItem | ||||
|             className={ | ||||
|               isDesktop ? "cursor-pointer" : "flex items-center p-2 text-sm" | ||||
|             } | ||||
|           > | ||||
|             <a className="flex" href={logoutUrl}> | ||||
|               <LuLogOut className="mr-2 size-4" /> | ||||
|               <span>Logout</span> | ||||
|             </a> | ||||
|           </MenuItem> | ||||
|         </div> | ||||
|       </Content> | ||||
|     </Container> | ||||
|   ); | ||||
| } | ||||
|  | ||||
| @ -116,22 +116,20 @@ export default function GeneralSettings({ className }: GeneralSettingsProps) { | ||||
|       <div className={className}> | ||||
|         <Container> | ||||
|           <Trigger asChild> | ||||
|             <a href="#"> | ||||
|               <Tooltip> | ||||
|                 <TooltipTrigger asChild> | ||||
|                   <div | ||||
|                     className={`flex flex-col items-center justify-center ${isDesktop ? "cursor-pointer rounded-lg bg-secondary text-secondary-foreground hover:bg-muted" : "text-secondary-foreground"}`} | ||||
|                   > | ||||
|                     <LuSettings className="size-5 md:m-[6px]" /> | ||||
|                   </div> | ||||
|                 </TooltipTrigger> | ||||
|                 <TooltipPortal> | ||||
|                   <TooltipContent side="right"> | ||||
|                     <p>Settings</p> | ||||
|                   </TooltipContent> | ||||
|                 </TooltipPortal> | ||||
|               </Tooltip> | ||||
|             </a> | ||||
|             <Tooltip> | ||||
|               <TooltipTrigger asChild> | ||||
|                 <div | ||||
|                   className={`flex flex-col items-center justify-center ${isDesktop ? "cursor-pointer rounded-lg bg-secondary text-secondary-foreground hover:bg-muted" : "text-secondary-foreground"}`} | ||||
|                 > | ||||
|                   <LuSettings className="size-5 md:m-[6px]" /> | ||||
|                 </div> | ||||
|               </TooltipTrigger> | ||||
|               <TooltipPortal> | ||||
|                 <TooltipContent side="right"> | ||||
|                   <p>Settings</p> | ||||
|                 </TooltipContent> | ||||
|               </TooltipPortal> | ||||
|             </Tooltip> | ||||
|           </Trigger> | ||||
|           <Content | ||||
|             className={ | ||||
|  | ||||
| @ -15,7 +15,7 @@ import { | ||||
| } from "@/context/statusbar-provider"; | ||||
| import { Link } from "react-router-dom"; | ||||
| import { cn } from "@/lib/utils"; | ||||
| import { isMobile } from "react-device-detect"; | ||||
| import { isIOS, isMobile } from "react-device-detect"; | ||||
| import { isPWA } from "@/utils/isPWA"; | ||||
| 
 | ||||
| function Bottombar() { | ||||
| @ -25,7 +25,7 @@ function Bottombar() { | ||||
|     <div | ||||
|       className={cn( | ||||
|         "absolute inset-x-4 bottom-0 flex h-16 flex-row justify-between", | ||||
|         isPWA | ||||
|         isPWA && isIOS | ||||
|           ? "portrait:items-start portrait:pt-1 landscape:items-center" | ||||
|           : "items-center", | ||||
|         isMobile && !isPWA && "h-12 landscape:md:h-16", | ||||
|  | ||||
| @ -82,10 +82,10 @@ export default function PreviewPlayer({ | ||||
|   } | ||||
| 
 | ||||
|   return ( | ||||
|     <div className="size-full flex items-center justify-center rounded-lg text-white md:rounded-2xl"> | ||||
|     <div className="flex size-full items-center justify-center rounded-lg text-white md:rounded-2xl"> | ||||
|       No Preview Found | ||||
|     </div> | ||||
|   ) | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export abstract class PreviewController { | ||||
|  | ||||
| @ -51,7 +51,7 @@ export default function useStats(stats: FrigateStats | undefined) { | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       if (config.cameras[name].enabled && (cam["camera_fps"] == 0)) { | ||||
|       if (config.cameras[name].enabled && cam["camera_fps"] == 0) { | ||||
|         problems.push({ | ||||
|           text: `${capitalizeFirstLetter(name.replaceAll("_", " "))} is offline`, | ||||
|           color: "text-danger", | ||||
|  | ||||
| @ -101,7 +101,9 @@ export default function LiveCameraView({ camera }: LiveCameraViewProps) { | ||||
|     return ( | ||||
|       cameraMetadata.producers.find( | ||||
|         (prod) => | ||||
|           prod.medias && prod.medias.find((media) => media.includes("audio, sendonly")) != undefined, | ||||
|           prod.medias && | ||||
|           prod.medias.find((media) => media.includes("audio, sendonly")) != | ||||
|             undefined, | ||||
|       ) != undefined | ||||
|     ); | ||||
|   }, [cameraMetadata]); | ||||
| @ -113,10 +115,12 @@ export default function LiveCameraView({ camera }: LiveCameraViewProps) { | ||||
|     return ( | ||||
|       cameraMetadata.producers.find( | ||||
|         (prod) => | ||||
|           prod.medias && prod.medias.find((media) => media.includes("audio, recvonly")) != undefined, | ||||
|           prod.medias && | ||||
|           prod.medias.find((media) => media.includes("audio, recvonly")) != | ||||
|             undefined, | ||||
|       ) != undefined | ||||
|     ); | ||||
|   }, [cameraMetadata]) | ||||
|   }, [cameraMetadata]); | ||||
| 
 | ||||
|   // click overlay for ptzs
 | ||||
| 
 | ||||
| @ -351,14 +355,16 @@ export default function LiveCameraView({ camera }: LiveCameraViewProps) { | ||||
|                   onClick={() => setMic(!mic)} | ||||
|                 /> | ||||
|               )} | ||||
|               {supportsAudioOutput && <CameraFeatureToggle | ||||
|                 className="p-2 md:p-0" | ||||
|                 variant={fullscreen ? "overlay" : "primary"} | ||||
|                 Icon={audio ? GiSpeaker : GiSpeakerOff} | ||||
|                 isActive={audio} | ||||
|                 title={`${audio ? "Disable" : "Enable"} Camera Audio`} | ||||
|                 onClick={() => setAudio(!audio)} | ||||
|               />} | ||||
|               {supportsAudioOutput && ( | ||||
|                 <CameraFeatureToggle | ||||
|                   className="p-2 md:p-0" | ||||
|                   variant={fullscreen ? "overlay" : "primary"} | ||||
|                   Icon={audio ? GiSpeaker : GiSpeakerOff} | ||||
|                   isActive={audio} | ||||
|                   title={`${audio ? "Disable" : "Enable"} Camera Audio`} | ||||
|                   onClick={() => setAudio(!audio)} | ||||
|                 /> | ||||
|               )} | ||||
|               <FrigateCameraFeatures | ||||
|                 camera={camera.name} | ||||
|                 audioDetectEnabled={camera.audio.enabled_in_config} | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user