mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
UI tweaks and bugfixes (#10882)
* small tweaks and bugfixes * spacing * simplify
This commit is contained in:
parent
73c093be43
commit
f210c4b6f4
@ -32,7 +32,7 @@ export default function Statusbar() {
|
|||||||
const { potentialProblems } = useStats(stats);
|
const { potentialProblems } = useStats(stats);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="absolute left-0 bottom-0 right-0 w-full h-8 flex justify-between items-center px-4 bg-primary z-10 text-secondary-foreground border-t border-secondary-highlight">
|
<div className="absolute left-0 bottom-0 right-0 w-full h-8 flex justify-between items-center px-4 bg-primary z-10 dark:text-secondary-foreground border-t border-secondary-highlight">
|
||||||
<div className="h-full flex items-center gap-2">
|
<div className="h-full flex items-center gap-2">
|
||||||
{cpuPercent && (
|
{cpuPercent && (
|
||||||
<div className="flex items-center text-sm gap-2">
|
<div className="flex items-center text-sm gap-2">
|
||||||
|
@ -75,6 +75,9 @@ export default function ReviewFilterGroup({
|
|||||||
const cameras = filter?.cameras || Object.keys(config.cameras);
|
const cameras = filter?.cameras || Object.keys(config.cameras);
|
||||||
|
|
||||||
cameras.forEach((camera) => {
|
cameras.forEach((camera) => {
|
||||||
|
if (camera == "birdseye") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const cameraConfig = config.cameras[camera];
|
const cameraConfig = config.cameras[camera];
|
||||||
cameraConfig.objects.track.forEach((label) => {
|
cameraConfig.objects.track.forEach((label) => {
|
||||||
labels.add(label);
|
labels.add(label);
|
||||||
@ -219,24 +222,30 @@ function CamerasFilterButton({
|
|||||||
|
|
||||||
const trigger = (
|
const trigger = (
|
||||||
<Button
|
<Button
|
||||||
className="flex items-center gap-2 capitalize"
|
className={`flex items-center gap-2 capitalize ${selectedCameras?.length ? "bg-selected hover:bg-selected" : ""}`}
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
<FaVideo className="text-secondary-foreground" />
|
<FaVideo
|
||||||
|
className={`${selectedCameras?.length ? "text-primary dark:text-primary-foreground" : "text-secondary-foreground"}`}
|
||||||
|
/>
|
||||||
<div className="hidden md:block text-primary-foreground">
|
<div className="hidden md:block text-primary-foreground">
|
||||||
{selectedCameras == undefined
|
{selectedCameras == undefined
|
||||||
? "All Cameras"
|
? "All Cameras"
|
||||||
: `${selectedCameras.length} Cameras`}
|
: `${selectedCameras.includes("birdseye") ? selectedCameras.length - 1 : selectedCameras.length} Camera${selectedCameras.length !== 1 ? "s" : ""}`}
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
const content = (
|
const content = (
|
||||||
<>
|
<>
|
||||||
<DropdownMenuLabel className="flex justify-center">
|
{isMobile && (
|
||||||
Filter Cameras
|
<>
|
||||||
</DropdownMenuLabel>
|
<DropdownMenuLabel className="flex justify-center">
|
||||||
<DropdownMenuSeparator />
|
Cameras
|
||||||
|
</DropdownMenuLabel>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<div className="h-auto overflow-y-auto overflow-x-hidden">
|
<div className="h-auto overflow-y-auto overflow-x-hidden">
|
||||||
<FilterCheckBox
|
<FilterCheckBox
|
||||||
isChecked={currentCameras == undefined}
|
isChecked={currentCameras == undefined}
|
||||||
@ -382,13 +391,13 @@ function ShowReviewFilter({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className="block md:hidden"
|
className={`block md:hidden ${showReviewedSwitch == 0 ? "bg-selected hover:bg-selected" : "bg-secondary hover:bg-secondary/80"}`}
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
onClick={() => setShowReviewedSwitch(showReviewedSwitch == 0 ? 1 : 0)}
|
onClick={() => setShowReviewedSwitch(showReviewedSwitch == 0 ? 1 : 0)}
|
||||||
>
|
>
|
||||||
<FaCheckCircle
|
<FaCheckCircle
|
||||||
className={`${showReviewedSwitch == 1 ? "text-selected" : "text-muted-foreground"}`}
|
className={`${showReviewedSwitch == 0 ? "fill-primary-foreground" : "text-muted-foreground"}`}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
@ -664,10 +673,11 @@ function ShowMotionOnlyButton({
|
|||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
|
className={`${motionOnlyButton ? "bg-selected hover:bg-selected" : "bg-secondary hover:bg-secondary/80"}`}
|
||||||
onClick={() => setMotionOnlyButton(!motionOnlyButton)}
|
onClick={() => setMotionOnlyButton(!motionOnlyButton)}
|
||||||
>
|
>
|
||||||
<FaRunning
|
<FaRunning
|
||||||
className={`${motionOnlyButton ? "text-selected" : "text-muted-foreground"}`}
|
className={`${motionOnlyButton ? "fill-primary-foreground" : "text-muted-foreground"}`}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -235,7 +235,7 @@ function PreviewVideoPlayer({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`relative rounded-2xl bg-black overflow-hidden ${onClick ? "cursor-pointer" : ""} ${className ?? ""}`}
|
className={`relative rounded-2xl w-full flex justify-center bg-black overflow-hidden ${onClick ? "cursor-pointer" : ""} ${className ?? ""}`}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
@ -464,7 +464,7 @@ function PreviewFramesPlayer({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`relative ${className ?? ""} ${onClick ? "cursor-pointer" : ""}`}
|
className={`relative w-full flex justify-center ${className ?? ""} ${onClick ? "cursor-pointer" : ""}`}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
|
@ -142,7 +142,7 @@ export default function VideoControls({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`px-4 py-2 flex justify-between items-center gap-8 text-white z-50 bg-secondary-foreground/60 dark:bg-secondary/60 rounded-lg ${className ?? ""}`}
|
className={`px-4 py-2 flex justify-between items-center gap-8 text-primary-foreground dark:text-white z-50 bg-secondary-foreground/60 dark:bg-secondary/60 rounded-lg ${className ?? ""}`}
|
||||||
>
|
>
|
||||||
{video && features.volume && (
|
{video && features.volume && (
|
||||||
<div className="flex justify-normal items-center gap-2">
|
<div className="flex justify-normal items-center gap-2">
|
||||||
@ -170,9 +170,9 @@ export default function VideoControls({
|
|||||||
)}
|
)}
|
||||||
<div className="cursor-pointer" onClick={onTogglePlay}>
|
<div className="cursor-pointer" onClick={onTogglePlay}>
|
||||||
{isPlaying ? (
|
{isPlaying ? (
|
||||||
<LuPause className="size-5 fill-white" />
|
<LuPause className="size-5 fill-primary-foreground dark:fill-white" />
|
||||||
) : (
|
) : (
|
||||||
<LuPlay className="size-5 fill-white" />
|
<LuPlay className="size-5 fill-primary-foreground dark:fill-white" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{features.seek && (
|
{features.seek && (
|
||||||
|
@ -853,7 +853,10 @@ function MotionReview({
|
|||||||
onClick={() =>
|
onClick={() =>
|
||||||
onOpenRecording({
|
onOpenRecording({
|
||||||
camera: camera.name,
|
camera: camera.name,
|
||||||
startTime: currentTime,
|
startTime: Math.min(
|
||||||
|
currentTime,
|
||||||
|
Date.now() / 1000 - 30,
|
||||||
|
),
|
||||||
severity: "significant_motion",
|
severity: "significant_motion",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ import MobileCameraDrawer from "@/components/overlay/MobileCameraDrawer";
|
|||||||
import MobileTimelineDrawer from "@/components/overlay/MobileTimelineDrawer";
|
import MobileTimelineDrawer from "@/components/overlay/MobileTimelineDrawer";
|
||||||
import MobileReviewSettingsDrawer from "@/components/overlay/MobileReviewSettingsDrawer";
|
import MobileReviewSettingsDrawer from "@/components/overlay/MobileReviewSettingsDrawer";
|
||||||
import Logo from "@/components/Logo";
|
import Logo from "@/components/Logo";
|
||||||
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
|
|
||||||
const SEGMENT_DURATION = 30;
|
const SEGMENT_DURATION = 30;
|
||||||
|
|
||||||
@ -503,26 +504,30 @@ function Timeline({
|
|||||||
<div className="absolute top-0 inset-x-0 z-20 w-full h-[30px] bg-gradient-to-b from-secondary to-transparent pointer-events-none"></div>
|
<div className="absolute top-0 inset-x-0 z-20 w-full h-[30px] bg-gradient-to-b from-secondary to-transparent pointer-events-none"></div>
|
||||||
<div className="absolute bottom-0 inset-x-0 z-20 w-full h-[30px] bg-gradient-to-t from-secondary to-transparent pointer-events-none"></div>
|
<div className="absolute bottom-0 inset-x-0 z-20 w-full h-[30px] bg-gradient-to-t from-secondary to-transparent pointer-events-none"></div>
|
||||||
{timelineType == "timeline" ? (
|
{timelineType == "timeline" ? (
|
||||||
<MotionReviewTimeline
|
motionData ? (
|
||||||
segmentDuration={30}
|
<MotionReviewTimeline
|
||||||
timestampSpread={15}
|
segmentDuration={30}
|
||||||
timelineStart={timeRange.before}
|
timestampSpread={15}
|
||||||
timelineEnd={timeRange.after}
|
timelineStart={timeRange.before}
|
||||||
showHandlebar={exportRange == undefined}
|
timelineEnd={timeRange.after}
|
||||||
showExportHandles={exportRange != undefined}
|
showHandlebar={exportRange == undefined}
|
||||||
exportStartTime={exportRange?.after}
|
showExportHandles={exportRange != undefined}
|
||||||
exportEndTime={exportRange?.before}
|
exportStartTime={exportRange?.after}
|
||||||
setExportStartTime={setExportStartTime}
|
exportEndTime={exportRange?.before}
|
||||||
setExportEndTime={setExportEndTime}
|
setExportStartTime={setExportStartTime}
|
||||||
handlebarTime={currentTime}
|
setExportEndTime={setExportEndTime}
|
||||||
setHandlebarTime={setCurrentTime}
|
handlebarTime={currentTime}
|
||||||
onlyInitialHandlebarScroll={true}
|
setHandlebarTime={setCurrentTime}
|
||||||
events={mainCameraReviewItems}
|
onlyInitialHandlebarScroll={true}
|
||||||
motion_events={motionData ?? []}
|
events={mainCameraReviewItems}
|
||||||
severityType="significant_motion"
|
motion_events={motionData ?? []}
|
||||||
contentRef={contentRef}
|
severityType="significant_motion"
|
||||||
onHandlebarDraggingChange={(scrubbing) => setScrubbing(scrubbing)}
|
contentRef={contentRef}
|
||||||
/>
|
onHandlebarDraggingChange={(scrubbing) => setScrubbing(scrubbing)}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Skeleton className="size-full" />
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
className={`h-full grid grid-cols-1 gap-4 overflow-auto p-4 bg-secondary ${isDesktop ? "" : "sm:grid-cols-2"}`}
|
className={`h-full grid grid-cols-1 gap-4 overflow-auto p-4 bg-secondary ${isDesktop ? "" : "sm:grid-cols-2"}`}
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
--secondary: hsl(0, 0%, 96%);
|
--secondary: hsl(0, 0%, 96%);
|
||||||
--secondary: 0 0% 96%;
|
--secondary: 0 0% 96%;
|
||||||
|
|
||||||
--secondary-foreground: hsl(0, 0%, 83%);
|
--secondary-foreground: hsl(0, 0%, 70%);
|
||||||
--secondary-foreground: 0 0% 83%;
|
--secondary-foreground: 0 0% 70%;
|
||||||
|
|
||||||
--secondary-highlight: hsl(0, 0%, 94%);
|
--secondary-highlight: hsl(0, 0%, 94%);
|
||||||
--secondary-highlight: 0 0% 94%;
|
--secondary-highlight: 0 0% 94%;
|
||||||
@ -64,7 +64,7 @@
|
|||||||
--input: 0 0% 85%;
|
--input: 0 0% 85%;
|
||||||
|
|
||||||
--ring: hsla(0 0% 25% 0%);
|
--ring: hsla(0 0% 25% 0%);
|
||||||
--ring: 0 0% 25% 0%
|
--ring: 0 0% 25% 0%;
|
||||||
|
|
||||||
--selected: hsl(228, 89%, 63%);
|
--selected: hsl(228, 89%, 63%);
|
||||||
--selected: 228 89% 63%;
|
--selected: 228 89% 63%;
|
||||||
@ -155,7 +155,7 @@
|
|||||||
--input: 0 0% 25%;
|
--input: 0 0% 25%;
|
||||||
|
|
||||||
--ring: hsla(0 0% 25% 0%);
|
--ring: hsla(0 0% 25% 0%);
|
||||||
--ring: 0 0% 25% 0%
|
--ring: 0 0% 25% 0%;
|
||||||
|
|
||||||
--selected: hsl(228, 89%, 63%);
|
--selected: hsl(228, 89%, 63%);
|
||||||
--selected: 228 89% 63%;
|
--selected: 228 89% 63%;
|
||||||
|
Loading…
Reference in New Issue
Block a user