hide settings dropdown when fullscreen

This commit is contained in:
Josh Hawkins 2025-11-11 11:05:44 -06:00
parent 0b43c15602
commit 03174adb8b

View File

@ -1030,294 +1030,298 @@ function FrigateCameraFeatures({
disabled={!cameraEnabled || debug || isSnapshotLoading} disabled={!cameraEnabled || debug || isSnapshotLoading}
loading={isSnapshotLoading} loading={isSnapshotLoading}
/> />
<DropdownMenu modal={false}> {!fullscreen && (
<DropdownMenuTrigger> <DropdownMenu modal={false}>
<div <DropdownMenuTrigger>
className={cn( <div
"flex flex-col items-center justify-center rounded-lg bg-secondary p-2 text-secondary-foreground md:p-0", className={cn(
)} "flex flex-col items-center justify-center rounded-lg bg-secondary p-2 text-secondary-foreground md:p-0",
> )}
<FaCog >
className={`text-secondary-foreground" size-5 md:m-[6px]`} <FaCog
/> className={`text-secondary-foreground" size-5 md:m-[6px]`}
</div> />
</DropdownMenuTrigger> </div>
<DropdownMenuContent className="max-w-96"> </DropdownMenuTrigger>
<div className="flex flex-col gap-5 p-4"> <DropdownMenuContent className="max-w-96">
{!isRestreamed && ( <div className="flex flex-col gap-5 p-4">
<div className="flex flex-col gap-2"> {!isRestreamed && (
<Label> <div className="flex flex-col gap-2">
{t("streaming.label", { ns: "components/dialog" })} <Label>
</Label> {t("streaming.label", { ns: "components/dialog" })}
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground"> </Label>
<LuX className="size-4 text-danger" /> <div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
<div> <LuX className="size-4 text-danger" />
{t("streaming.restreaming.disabled", { <div>
ns: "components/dialog", {t("streaming.restreaming.disabled", {
})}
</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", 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="flex flex-col gap-1">
<Label htmlFor="streaming-method">
{t("stream.title")}
</Label>
<Select
value={streamName}
disabled={debug}
onValueChange={(value) => {
setStreamName?.(value);
}}
>
<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> </div>
)} <Popover>
<PopoverTrigger asChild>
{preferredLiveMode != "jsmpeg" && <div className="cursor-pointer p-0">
!debug && <LuInfo className="size-4" />
isRestreamed && ( <span className="sr-only">
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground"> {t("button.info", { ns: "common" })}
{supportsAudioOutput ? ( </span>
<>
<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-80 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-80 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" &&
!debug &&
isRestreamed && (
<div className="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>
<Button </PopoverTrigger>
className={`flex items-center gap-2.5 rounded-lg`} <PopoverContent className="w-80 text-xs">
aria-label={t("stream.lowBandwidth.resetStream")} {t("streaming.restreaming.desc.title", {
variant="outline" ns: "components/dialog",
size="sm" })}
onClick={() => setLowBandwidth(false)} <div className="mt-2 flex items-center text-primary">
> <Link
<MdOutlineRestartAlt className="size-5 text-primary-variant" /> to={getLocaleDocUrl("configuration/live")}
<div className="text-primary-variant"> target="_blank"
{t("stream.lowBandwidth.resetStream")} rel="noopener noreferrer"
</div> className="inline"
</Button> >
</div> {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="flex flex-col gap-1">
<Label htmlFor="streaming-method">
{t("stream.title")}
</Label>
<Select
value={streamName}
disabled={debug}
onValueChange={(value) => {
setStreamName?.(value);
}}
>
<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="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-80 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-80 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" &&
!debug &&
isRestreamed && (
<div className="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"
onClick={() => setLowBandwidth(false)}
>
<MdOutlineRestartAlt className="size-5 text-primary-variant" />
<div className="text-primary-variant">
{t("stream.lowBandwidth.resetStream")}
</div>
</Button>
</div>
)}
</div>
)}
{isRestreamed && (
<div className="flex flex-col gap-1">
<div className="flex items-center justify-between">
<Label
className="mx-0 cursor-pointer text-primary"
htmlFor="backgroundplay"
>
{t("stream.playInBackground.label")}
</Label>
<Switch
className="ml-1"
id="backgroundplay"
disabled={debug}
checked={playInBackground}
onCheckedChange={(checked) =>
setPlayInBackground(checked)
}
/>
</div>
<p className="text-sm text-muted-foreground">
{t("stream.playInBackground.tips")}
</p>
</div> </div>
)} )}
{isRestreamed && (
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<Label <Label
className="mx-0 cursor-pointer text-primary" className="mx-0 cursor-pointer text-primary"
htmlFor="backgroundplay" htmlFor="showstats"
> >
{t("stream.playInBackground.label")} {t("streaming.showStats.label", {
ns: "components/dialog",
})}
</Label> </Label>
<Switch <Switch
className="ml-1" className="ml-1"
id="backgroundplay" id="showstats"
disabled={debug} disabled={debug}
checked={playInBackground} checked={showStats}
onCheckedChange={(checked) => onCheckedChange={(checked) => setShowStats(checked)}
setPlayInBackground(checked)
}
/> />
</div> </div>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{t("stream.playInBackground.tips")} {t("streaming.showStats.desc", {
ns: "components/dialog",
})}
</p> </p>
</div> </div>
)} <div className="flex flex-col gap-1">
<div className="flex flex-col gap-1"> <div className="flex items-center justify-between">
<div className="flex items-center justify-between"> <Label
<Label className="mx-0 cursor-pointer text-primary"
className="mx-0 cursor-pointer text-primary" htmlFor="debug"
htmlFor="showstats" >
> {t("streaming.debugView", {
{t("streaming.showStats.label", { ns: "components/dialog",
ns: "components/dialog", })}
})} </Label>
</Label> <Switch
<Switch className="ml-1"
className="ml-1" id="debug"
id="showstats" checked={debug}
disabled={debug} onCheckedChange={(checked) => setDebug(checked)}
checked={showStats} />
onCheckedChange={(checked) => setShowStats(checked)} </div>
/>
</div>
<p className="text-sm text-muted-foreground">
{t("streaming.showStats.desc", {
ns: "components/dialog",
})}
</p>
</div>
<div className="flex flex-col gap-1">
<div className="flex items-center justify-between">
<Label
className="mx-0 cursor-pointer text-primary"
htmlFor="debug"
>
{t("streaming.debugView", {
ns: "components/dialog",
})}
</Label>
<Switch
className="ml-1"
id="debug"
checked={debug}
onCheckedChange={(checked) => setDebug(checked)}
/>
</div> </div>
</div> </div>
</div> </DropdownMenuContent>
</DropdownMenuContent> </DropdownMenu>
</DropdownMenu> )}
</> </>
); );
} }