mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Layout tweaks (#10365)
* Cleanup review items * Fix spacing * Fix -1 text * Cleanup scroll * Show activity indicator when review items are null * Show no preview text when not found * Add padding to buttons * Simplify comparisons
This commit is contained in:
parent
cac5bccbe7
commit
838ef636f8
@ -212,7 +212,7 @@ function CamerasFilterButton({
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<div className="flex justify-evenly items-center">
|
<div className="p-2 flex justify-evenly items-center">
|
||||||
<Button
|
<Button
|
||||||
variant="select"
|
variant="select"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -312,7 +312,7 @@ function CalendarFilterButton({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<div className="flex justify-center items-center">
|
<div className="p-2 flex justify-center items-center">
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -421,7 +421,7 @@ function GeneralFilterButton({
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<div className="flex justify-evenly items-center">
|
<div className="p-2 flex justify-evenly items-center">
|
||||||
<Button
|
<Button
|
||||||
variant="select"
|
variant="select"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -140,6 +140,11 @@ export default function PreviewVideoPlayer({
|
|||||||
<source src={currentPreview.src} type={currentPreview.type} />
|
<source src={currentPreview.src} type={currentPreview.type} />
|
||||||
)}
|
)}
|
||||||
</video>
|
</video>
|
||||||
|
{cameraPreviews && !currentPreview && (
|
||||||
|
<div className="absolute inset-x-0 top-1/2 -y-translate-1/2 bg-black text-white rounded-2xl align-center text-center">
|
||||||
|
No Preview Found
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ export default function EventView({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!summary) {
|
if (!summary) {
|
||||||
return { alert: 0, detection: 0, significant_motion: 0 };
|
return { alert: -1, detection: -1, significant_motion: -1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter?.showReviewed == 1) {
|
if (filter?.showReviewed == 1) {
|
||||||
@ -106,6 +106,10 @@ export default function EventView({
|
|||||||
// review paging
|
// review paging
|
||||||
|
|
||||||
const reviewItems = useMemo(() => {
|
const reviewItems = useMemo(() => {
|
||||||
|
if (!reviews) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const all: ReviewSegment[] = [];
|
const all: ReviewSegment[] = [];
|
||||||
const alerts: ReviewSegment[] = [];
|
const alerts: ReviewSegment[] = [];
|
||||||
const detections: ReviewSegment[] = [];
|
const detections: ReviewSegment[] = [];
|
||||||
@ -167,7 +171,7 @@ export default function EventView({
|
|||||||
|
|
||||||
const exportReview = useCallback(
|
const exportReview = useCallback(
|
||||||
(id: string) => {
|
(id: string) => {
|
||||||
const review = reviewItems.all?.find((seg) => seg.id == id);
|
const review = reviewItems?.all?.find((seg) => seg.id == id);
|
||||||
|
|
||||||
if (!review) {
|
if (!review) {
|
||||||
return;
|
return;
|
||||||
@ -206,7 +210,9 @@ export default function EventView({
|
|||||||
aria-label="Select alerts"
|
aria-label="Select alerts"
|
||||||
>
|
>
|
||||||
<MdCircle className="size-2 md:mr-[10px] text-severity_alert" />
|
<MdCircle className="size-2 md:mr-[10px] text-severity_alert" />
|
||||||
<div className="hidden md:block">Alerts ∙ {reviewCounts.alert}</div>
|
<div className="hidden md:block">
|
||||||
|
Alerts{` ∙ ${reviewCounts.alert > -1 ? reviewCounts.alert : ""}`}
|
||||||
|
</div>
|
||||||
</ToggleGroupItem>
|
</ToggleGroupItem>
|
||||||
<ToggleGroupItem
|
<ToggleGroupItem
|
||||||
className={`${severity == "detection" ? "" : "text-gray-500"}`}
|
className={`${severity == "detection" ? "" : "text-gray-500"}`}
|
||||||
@ -215,7 +221,8 @@ export default function EventView({
|
|||||||
>
|
>
|
||||||
<MdCircle className="size-2 md:mr-[10px] text-severity_detection" />
|
<MdCircle className="size-2 md:mr-[10px] text-severity_detection" />
|
||||||
<div className="hidden md:block">
|
<div className="hidden md:block">
|
||||||
Detections ∙ {reviewCounts.detection}
|
Detections
|
||||||
|
{` ∙ ${reviewCounts.detection > -1 ? reviewCounts.detection : ""}`}
|
||||||
</div>
|
</div>
|
||||||
</ToggleGroupItem>
|
</ToggleGroupItem>
|
||||||
<ToggleGroupItem
|
<ToggleGroupItem
|
||||||
@ -277,7 +284,7 @@ export default function EventView({
|
|||||||
|
|
||||||
type DetectionReviewProps = {
|
type DetectionReviewProps = {
|
||||||
contentRef: MutableRefObject<HTMLDivElement | null>;
|
contentRef: MutableRefObject<HTMLDivElement | null>;
|
||||||
reviewItems: {
|
reviewItems?: {
|
||||||
all: ReviewSegment[];
|
all: ReviewSegment[];
|
||||||
alert: ReviewSegment[];
|
alert: ReviewSegment[];
|
||||||
detection: ReviewSegment[];
|
detection: ReviewSegment[];
|
||||||
@ -310,10 +317,14 @@ function DetectionReview({
|
|||||||
|
|
||||||
// review data
|
// review data
|
||||||
const currentItems = useMemo(() => {
|
const currentItems = useMemo(() => {
|
||||||
|
if (!reviewItems) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const current = reviewItems[severity];
|
const current = reviewItems[severity];
|
||||||
|
|
||||||
if (!current || current.length == 0) {
|
if (!current || current.length == 0) {
|
||||||
return null;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter?.showReviewed != 1) {
|
if (filter?.showReviewed != 1) {
|
||||||
@ -323,7 +334,7 @@ function DetectionReview({
|
|||||||
}
|
}
|
||||||
// only refresh when severity or filter changes
|
// only refresh when severity or filter changes
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [severity, filter, reviewItems.all.length]);
|
}, [severity, filter, reviewItems?.all.length]);
|
||||||
|
|
||||||
// preview
|
// preview
|
||||||
|
|
||||||
@ -348,7 +359,7 @@ function DetectionReview({
|
|||||||
// timeline interaction
|
// timeline interaction
|
||||||
|
|
||||||
const { alignStartDateToTimeline } = useEventUtils(
|
const { alignStartDateToTimeline } = useEventUtils(
|
||||||
reviewItems.all,
|
reviewItems?.all ?? [],
|
||||||
segmentDuration,
|
segmentDuration,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -441,10 +452,16 @@ function DetectionReview({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{itemsToReview == 0 && (
|
{!currentItems && (
|
||||||
<div className="size-full flex flex-col justify-center items-center">
|
<div className="absolute left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2">
|
||||||
|
<ActivityIndicator />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{currentItems?.length === 0 && (
|
||||||
|
<div className="absolute left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2 flex flex-col justify-center items-center text-center">
|
||||||
<LuFolderCheck className="size-16" />
|
<LuFolderCheck className="size-16" />
|
||||||
There are no {severity.replace(/_/g, " ")} items to review
|
There are no {severity.replace(/_/g, " ")}s to review
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -479,7 +496,7 @@ function DetectionReview({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{(itemsToReview ?? 0) > 0 && (
|
{(currentItems?.length ?? 0) > 0 && (itemsToReview ?? 0) > 0 && (
|
||||||
<div className="col-span-full flex justify-center items-center">
|
<div className="col-span-full flex justify-center items-center">
|
||||||
<Button
|
<Button
|
||||||
className="text-white"
|
className="text-white"
|
||||||
@ -503,7 +520,7 @@ function DetectionReview({
|
|||||||
minimapEndTime={minimapBounds.end}
|
minimapEndTime={minimapBounds.end}
|
||||||
showHandlebar={previewTime != undefined}
|
showHandlebar={previewTime != undefined}
|
||||||
handlebarTime={previewTime}
|
handlebarTime={previewTime}
|
||||||
events={reviewItems.all}
|
events={reviewItems?.all ?? []}
|
||||||
severityType={severity}
|
severityType={severity}
|
||||||
contentRef={contentRef}
|
contentRef={contentRef}
|
||||||
/>
|
/>
|
||||||
@ -514,7 +531,7 @@ function DetectionReview({
|
|||||||
|
|
||||||
type MotionReviewProps = {
|
type MotionReviewProps = {
|
||||||
contentRef: MutableRefObject<HTMLDivElement | null>;
|
contentRef: MutableRefObject<HTMLDivElement | null>;
|
||||||
reviewItems: {
|
reviewItems?: {
|
||||||
all: ReviewSegment[];
|
all: ReviewSegment[];
|
||||||
alert: ReviewSegment[];
|
alert: ReviewSegment[];
|
||||||
detection: ReviewSegment[];
|
detection: ReviewSegment[];
|
||||||
@ -680,7 +697,7 @@ function MotionReview({
|
|||||||
showHandlebar
|
showHandlebar
|
||||||
handlebarTime={currentTime}
|
handlebarTime={currentTime}
|
||||||
setHandlebarTime={setCurrentTime}
|
setHandlebarTime={setCurrentTime}
|
||||||
events={reviewItems.all}
|
events={reviewItems?.all ?? []}
|
||||||
motion_events={motionData ?? []}
|
motion_events={motionData ?? []}
|
||||||
severityType="significant_motion"
|
severityType="significant_motion"
|
||||||
contentRef={contentRef}
|
contentRef={contentRef}
|
||||||
|
@ -366,7 +366,7 @@ export function MobileRecordingView({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={contentRef} className="flex flex-col relative w-full h-full">
|
<div ref={contentRef} className="flex flex-col relative w-full h-full">
|
||||||
<div className="flex justify-evenly items-center">
|
<div className="flex justify-evenly items-center p-2">
|
||||||
<Button className="rounded-lg" onClick={() => navigate(-1)}>
|
<Button className="rounded-lg" onClick={() => navigate(-1)}>
|
||||||
<IoMdArrowRoundBack className="size-5 mr-[10px]" />
|
<IoMdArrowRoundBack className="size-5 mr-[10px]" />
|
||||||
Back
|
Back
|
||||||
|
Loading…
Reference in New Issue
Block a user