pixel alignment, better outlines, and more figma matching

This commit is contained in:
Josh Hawkins 2024-03-31 23:29:19 -05:00
parent 0a71e7fb88
commit 298b9fc13f
4 changed files with 41 additions and 37 deletions

View File

@ -31,7 +31,7 @@ function App() {
{isMobile && <Bottombar />} {isMobile && <Bottombar />}
<div <div
id="pageRoot" id="pageRoot"
className={`absolute top-0 right-0 overflow-hidden ${isMobile ? "left-0 bottom-16" : "left-12 bottom-8"}`} className={`absolute top-0 right-0 overflow-hidden ${isMobile ? "left-0 bottom-16" : "left-[52px] bottom-8"}`}
> >
<Suspense> <Suspense>
<Routes> <Routes>

View File

@ -170,24 +170,20 @@ export function EventSegment({
const segmentClick = useCallback(() => { const segmentClick = useCallback(() => {
if (contentRef.current && startTimestamp) { if (contentRef.current && startTimestamp) {
const element = contentRef.current.querySelector( const element = contentRef.current.querySelector(
`[data-segment-start="${startTimestamp - segmentDuration}"]`, `[data-segment-start="${startTimestamp - segmentDuration}"] .review-item-ring`,
); );
if (element instanceof HTMLElement) { if (element instanceof HTMLElement) {
scrollIntoView(element, { scrollIntoView(element, {
scrollMode: "if-needed", scrollMode: "if-needed",
behavior: "smooth", behavior: "smooth",
}); });
element.classList.add( element.classList.add(`outline-severity_${severityType}`);
`outline-severity_${severityType}`, element.classList.remove("outline-transparent");
`shadow-severity_${severityType}`,
);
element.classList.add("outline-3");
element.classList.remove("outline-0");
// Remove the classes after a short timeout // Remove the classes after a short timeout
setTimeout(() => { setTimeout(() => {
element.classList.remove("outline-3"); element.classList.remove(`outline-severity_${severityType}`);
element.classList.add("outline-0"); element.classList.add("outline-transparent");
}, 3000); }, 3000);
} }

View File

@ -206,12 +206,12 @@ export default function EventView({
return ( return (
<div className="py-2 flex flex-col size-full"> <div className="py-2 flex flex-col size-full">
<div className="h-11 px-2 relative flex justify-between items-center"> <div className="h-11 mb-2 pl-3 pr-2 relative flex justify-between items-center">
{isMobile && ( {isMobile && (
<Logo className="absolute inset-x-1/2 -translate-x-1/2 h-8" /> <Logo className="absolute inset-x-1/2 -translate-x-1/2 h-8" />
)} )}
<ToggleGroup <ToggleGroup
className="*:px-3 *:py-4 *:rounded-2xl" className="*:px-3 *:py-4 *:rounded-md"
type="single" type="single"
size="sm" size="sm"
value={severity} value={severity}
@ -518,7 +518,7 @@ function DetectionReview({
)} )}
<div <div
className="w-full m-2 p-1 grid sm:grid-cols-2 md:grid-cols-3 3xl:grid-cols-4 gap-2 md:gap-4" className="w-full mx-2 px-1 grid sm:grid-cols-2 md:grid-cols-3 3xl:grid-cols-4 gap-2 md:gap-4"
ref={contentRef} ref={contentRef}
> >
{currentItems && {currentItems &&
@ -533,7 +533,7 @@ function DetectionReview({
data-segment-start={ data-segment-start={
alignStartDateToTimeline(value.start_time) - segmentDuration alignStartDateToTimeline(value.start_time) - segmentDuration
} }
className={`review-item outline outline-offset-1 rounded-lg shadow-none transition-all my-1 md:my-0 ${selected ? `outline-3 outline-severity_${value.severity} shadow-severity_${value.severity}` : "outline-0 duration-500"}`} className="review-item relative rounded-lg"
> >
<div className="aspect-video rounded-lg overflow-hidden"> <div className="aspect-video rounded-lg overflow-hidden">
<PreviewThumbnailPlayer <PreviewThumbnailPlayer
@ -545,6 +545,9 @@ function DetectionReview({
onClick={onSelectReview} onClick={onSelectReview}
/> />
</div> </div>
<div
className={`review-item-ring pointer-events-none z-10 absolute rounded-lg inset-0 size-full -outline-offset-[2.8px] outline outline-3 ${selected ? `outline-severity_${value.severity} shadow-severity_${value.severity}` : "outline-transparent duration-500"}`}
/>
</div> </div>
); );
})} })}
@ -563,7 +566,7 @@ function DetectionReview({
)} )}
</div> </div>
</div> </div>
<div className="w-[65px] md:w-[110px] mt-2 flex flex-row"> <div className="w-[65px] md:w-[110px] flex flex-row">
<div className="w-[55px] md:w-[100px] overflow-y-auto no-scrollbar"> <div className="w-[55px] md:w-[100px] overflow-y-auto no-scrollbar">
<EventReviewTimeline <EventReviewTimeline
segmentDuration={segmentDuration} segmentDuration={segmentDuration}
@ -809,7 +812,7 @@ function MotionReview({
<div className="flex flex-1 flex-wrap content-start gap-2 md:gap-4 overflow-y-auto no-scrollbar"> <div className="flex flex-1 flex-wrap content-start gap-2 md:gap-4 overflow-y-auto no-scrollbar">
<div <div
ref={contentRef} ref={contentRef}
className="w-full m-2 p-1 grid sm:grid-cols-2 xl:grid-cols-3 3xl:grid-cols-4 gap-2 md:gap-4 overflow-auto no-scrollbar" className="w-full mx-2 px-1 grid sm:grid-cols-2 xl:grid-cols-3 3xl:grid-cols-4 gap-2 md:gap-4 overflow-auto no-scrollbar"
> >
{reviewCameras.map((camera) => { {reviewCameras.map((camera) => {
let grow; let grow;
@ -823,30 +826,35 @@ function MotionReview({
} }
const detectionType = getDetectionType(camera.name); const detectionType = getDetectionType(camera.name);
return ( return (
<PreviewPlayer <div className={`relative ${grow}`}>
key={camera.name} <PreviewPlayer
className={`${detectionType ? `outline outline-3 outline-offset-1 outline-severity_${detectionType}` : "outline-0 shadow-none"} rounded-2xl ${grow}`} key={camera.name}
camera={camera.name} className={`rounded-2xl ${grow}`}
timeRange={currentTimeRange} camera={camera.name}
startTime={previewStart} timeRange={currentTimeRange}
cameraPreviews={relevantPreviews || []} startTime={previewStart}
isScrubbing={scrubbing} cameraPreviews={relevantPreviews || []}
onControllerReady={(controller) => { isScrubbing={scrubbing}
videoPlayersRef.current[camera.name] = controller; onControllerReady={(controller) => {
}} videoPlayersRef.current[camera.name] = controller;
onClick={() => }}
onOpenRecording({ onClick={() =>
camera: camera.name, onOpenRecording({
startTime: currentTime, camera: camera.name,
severity: "significant_motion", startTime: currentTime,
}) severity: "significant_motion",
} })
/> }
/>
<div
className={`review-item-ring pointer-events-none z-10 absolute rounded-lg inset-0 size-full -outline-offset-[2.8px] outline outline-3 ${detectionType ? `outline-severity_${detectionType} shadow-severity_${detectionType}` : "outline-transparent duration-500"}`}
/>
</div>
); );
})} })}
</div> </div>
</div> </div>
<div className="w-[55px] md:w-[100px] mt-2 overflow-y-auto no-scrollbar"> <div className="w-[55px] md:w-[100px] overflow-y-auto no-scrollbar">
<MotionReviewTimeline <MotionReviewTimeline
segmentDuration={segmentDuration} segmentDuration={segmentDuration}
timestampSpread={15} timestampSpread={15}

View File

@ -243,7 +243,7 @@ export function RecordingView({
<div ref={contentRef} className="size-full pt-2 flex flex-col"> <div ref={contentRef} className="size-full pt-2 flex flex-col">
<Toaster /> <Toaster />
<div <div
className={`w-full h-11 px-2 relative flex items-center justify-between`} className={`w-full h-11 mb-2 px-2 relative flex items-center justify-between`}
> >
{isMobile && ( {isMobile && (
<Logo className="absolute inset-x-1/2 -translate-x-1/2 h-8" /> <Logo className="absolute inset-x-1/2 -translate-x-1/2 h-8" />