mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	UI tweaks (#9996)
* various tweaks * update debounce time * scroll to top with new events
This commit is contained in:
		
							parent
							
								
									fc94fcb2ac
								
							
						
					
					
						commit
						7d18c2c03d
					
				| @ -187,14 +187,7 @@ export function EventReviewTimeline({ | |||||||
| 
 | 
 | ||||||
|       setCurrentTimeSegment(alignedHandlebarTime); |       setCurrentTimeSegment(alignedHandlebarTime); | ||||||
|     } |     } | ||||||
|   }, [ |   }, []); | ||||||
|     handlebarTime, |  | ||||||
|     segmentDuration, |  | ||||||
|     showHandlebar, |  | ||||||
|     timelineDuration, |  | ||||||
|     timelineStart, |  | ||||||
|     alignDateToTimeline, |  | ||||||
|   ]); |  | ||||||
| 
 | 
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     generateSegments(); |     generateSegments(); | ||||||
|  | |||||||
| @ -186,14 +186,20 @@ export function EventSegment({ | |||||||
| 
 | 
 | ||||||
|   const firstMinimapSegmentRef = useRef<HTMLDivElement>(null); |   const firstMinimapSegmentRef = useRef<HTMLDivElement>(null); | ||||||
| 
 | 
 | ||||||
|  |   let debounceTimer: ReturnType<typeof setTimeout>; | ||||||
|  | 
 | ||||||
|  |   function debounceScrollIntoView(element: HTMLElement) { | ||||||
|  |     clearTimeout(debounceTimer); | ||||||
|  |     debounceTimer = setTimeout(() => { | ||||||
|  |       element.scrollIntoView({ behavior: "smooth", block: "center" }); | ||||||
|  |     }, 100); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     // Check if the first segment is out of view
 |     // Check if the first segment is out of view
 | ||||||
|     const firstSegment = firstMinimapSegmentRef.current; |     const firstSegment = firstMinimapSegmentRef.current; | ||||||
|     if (firstSegment && showMinimap && isFirstSegmentInMinimap) { |     if (firstSegment && showMinimap && isFirstSegmentInMinimap) { | ||||||
|       firstSegment.scrollIntoView({ |       debounceScrollIntoView(firstSegment); | ||||||
|         behavior: "smooth", |  | ||||||
|         block: "center", |  | ||||||
|       }); |  | ||||||
|     } |     } | ||||||
|   }, [showMinimap, isFirstSegmentInMinimap, events, segmentDuration]); |   }, [showMinimap, isFirstSegmentInMinimap, events, segmentDuration]); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -113,7 +113,10 @@ function useDraggableHandler({ | |||||||
|             } |             } | ||||||
|           }); |           }); | ||||||
|           if (setHandlebarTime) { |           if (setHandlebarTime) { | ||||||
|             setHandlebarTime(timelineStart - segmentIndex * segmentDuration); |             setHandlebarTime( | ||||||
|  |               timelineStart - | ||||||
|  |                 (newHandlePosition / segmentHeight) * segmentDuration | ||||||
|  |             ); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @ -132,10 +135,10 @@ function useDraggableHandler({ | |||||||
|     // TODO: determine when we want to do this
 |     // TODO: determine when we want to do this
 | ||||||
|     const handlebar = scrollTimeRef.current; |     const handlebar = scrollTimeRef.current; | ||||||
|     if (handlebar && showHandlebar) { |     if (handlebar && showHandlebar) { | ||||||
|       // handlebar.scrollIntoView({
 |       handlebar.scrollIntoView({ | ||||||
|       //   behavior: "smooth",
 |         behavior: "smooth", | ||||||
|       //   block: "center",
 |         block: "center", | ||||||
|       // });
 |       }); | ||||||
|     } |     } | ||||||
|   }, []); |   }, []); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -102,7 +102,7 @@ function UIPlayground() { | |||||||
|   const contentRef = useRef<HTMLDivElement>(null); |   const contentRef = useRef<HTMLDivElement>(null); | ||||||
|   const [mockEvents, setMockEvents] = useState<ReviewSegment[]>([]); |   const [mockEvents, setMockEvents] = useState<ReviewSegment[]>([]); | ||||||
|   const [handlebarTime, setHandlebarTime] = useState( |   const [handlebarTime, setHandlebarTime] = useState( | ||||||
|     Math.floor(Date.now() / 1000) - 7 * 60 |     Math.floor(Date.now() / 1000) - 15 * 60 | ||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
|   const onSelect = useCallback(({ items }: { items: string[] }) => { |   const onSelect = useCallback(({ items }: { items: string[] }) => { | ||||||
| @ -217,7 +217,16 @@ function UIPlayground() { | |||||||
|               <Heading as="h4" className="my-5"> |               <Heading as="h4" className="my-5"> | ||||||
|                 Timeline |                 Timeline | ||||||
|               </Heading> |               </Heading> | ||||||
|               <p className="text-small">Handlebar timestamp: {handlebarTime}</p> |               <p className="text-small"> | ||||||
|  |                 Handlebar timestamp: {handlebarTime} -  | ||||||
|  |                 {new Date(handlebarTime * 1000).toLocaleTimeString([], { | ||||||
|  |                   hour: "2-digit", | ||||||
|  |                   minute: "2-digit", | ||||||
|  |                   month: "short", | ||||||
|  |                   day: "2-digit", | ||||||
|  |                   second: "2-digit", | ||||||
|  |                 })} | ||||||
|  |               </p> | ||||||
|               <p className="text-small"> |               <p className="text-small"> | ||||||
|                 Handlebar is dragging: {isDragging ? "yes" : "no"} |                 Handlebar is dragging: {isDragging ? "yes" : "no"} | ||||||
|               </p> |               </p> | ||||||
|  | |||||||
| @ -247,25 +247,40 @@ export default function DesktopEventView({ | |||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
| 
 | 
 | ||||||
|       {hasUpdate && ( |  | ||||||
|         <Button |  | ||||||
|           className="absolute top-14 left-[50%] -translate-x-[50%] z-30 bg-gray-400 text-white" |  | ||||||
|           variant="secondary" |  | ||||||
|           onClick={() => { |  | ||||||
|             setHasUpdate(false); |  | ||||||
|             pullLatestData(); |  | ||||||
|           }} |  | ||||||
|         > |  | ||||||
|           <LuRefreshCcw className="w-4 h-4 mr-2" /> |  | ||||||
|           New Items To Review |  | ||||||
|         </Button> |  | ||||||
|       )} |  | ||||||
| 
 |  | ||||||
|       <div className="flex h-full overflow-hidden"> |       <div className="flex h-full overflow-hidden"> | ||||||
|         <div |         <div | ||||||
|           ref={contentRef} |           ref={contentRef} | ||||||
|           className="flex flex-1 flex-wrap content-start gap-2 overflow-y-auto no-scrollbar" |           className="flex flex-1 flex-wrap content-start gap-2 overflow-y-auto no-scrollbar" | ||||||
|         > |         > | ||||||
|  |           {hasUpdate && ( | ||||||
|  |             <div className="absolute w-full z-30"> | ||||||
|  |               <div className="flex justify-center items-center mr-[100px]"> | ||||||
|  |                 <Button | ||||||
|  |                   className={`${ | ||||||
|  |                     hasUpdate | ||||||
|  |                       ? "animate-in slide-in-from-top duration-500" | ||||||
|  |                       : "invisible" | ||||||
|  |                   }  text-center mt-5 mx-auto bg-gray-400 text-white`}
 | ||||||
|  |                   variant="secondary" | ||||||
|  |                   onClick={() => { | ||||||
|  |                     setHasUpdate(false); | ||||||
|  |                     pullLatestData(); | ||||||
|  |                     if (contentRef.current) { | ||||||
|  |                       contentRef.current.scrollTo({ | ||||||
|  |                         top: 0, | ||||||
|  |                         behavior: "smooth", | ||||||
|  |                       }); | ||||||
|  |                     } | ||||||
|  |                   }} | ||||||
|  |                 > | ||||||
|  |                   <LuRefreshCcw className="w-4 h-4 mr-2" /> | ||||||
|  |                   New Items To Review | ||||||
|  |                 </Button> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           )} | ||||||
|  | 
 | ||||||
|  |           <div className="w-full mr-4 md:grid md:grid-cols-3 3xl:grid-cols-4 gap-4 overflow-y-auto no-scrollbar"> | ||||||
|             {currentItems ? ( |             {currentItems ? ( | ||||||
|               currentItems.map((value, segIdx) => { |               currentItems.map((value, segIdx) => { | ||||||
|                 const lastRow = segIdx == reviewItems[severity].length - 1; |                 const lastRow = segIdx == reviewItems[severity].length - 1; | ||||||
| @ -284,7 +299,7 @@ export default function DesktopEventView({ | |||||||
|                     ref={lastRow ? lastReviewRef : minimapRef} |                     ref={lastRow ? lastReviewRef : minimapRef} | ||||||
|                     data-start={value.start_time} |                     data-start={value.start_time} | ||||||
|                   > |                   > | ||||||
|                   <div className="h-[234px] aspect-video rounded-lg overflow-hidden"> |                     <div className="aspect-video rounded-lg overflow-hidden"> | ||||||
|                       <PreviewThumbnailPlayer |                       <PreviewThumbnailPlayer | ||||||
|                         review={value} |                         review={value} | ||||||
|                         relevantPreview={relevantPreview} |                         relevantPreview={relevantPreview} | ||||||
| @ -300,6 +315,7 @@ export default function DesktopEventView({ | |||||||
|               <div ref={lastReviewRef} /> |               <div ref={lastReviewRef} /> | ||||||
|             )} |             )} | ||||||
|           </div> |           </div> | ||||||
|  |         </div> | ||||||
|         <div className="md:w-[100px] overflow-y-auto no-scrollbar"> |         <div className="md:w-[100px] overflow-y-auto no-scrollbar"> | ||||||
|           <EventReviewTimeline |           <EventReviewTimeline | ||||||
|             segmentDuration={60} |             segmentDuration={60} | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user