From 155c2fdff93677c6cfec558b7754ec574d463445 Mon Sep 17 00:00:00 2001
From: AmyangXYZ <amyang.xyz@gmail.com>
Date: Mon, 23 Sep 2024 22:01:49 -0400
Subject: [PATCH] add badge to recorder

---
 src/Video.tsx | 52 +++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 38 insertions(+), 14 deletions(-)

diff --git a/src/Video.tsx b/src/Video.tsx
index 4bb686a..36b80f3 100644
--- a/src/Video.tsx
+++ b/src/Video.tsx
@@ -6,12 +6,24 @@ import {
   HolisticLandmarker,
   HolisticLandmarkerResult,
 } from "@mediapipe/tasks-vision"
-import { IconButton, Tooltip } from "@mui/material"
+import { Badge, BadgeProps, IconButton, Tooltip } from "@mui/material"
 import { Videocam, CloudUpload, Replay, RadioButtonChecked, StopCircle } from "@mui/icons-material"
 import { styled } from "@mui/material/styles"
 
 const defaultVideoSrc = "./video/flash.mp4"
 
+const StyledBadge = styled(Badge)<BadgeProps>(({ theme }) => ({
+  "& .MuiBadge-badge": {
+    right: -3,
+    top: 4,
+    fontSize: ".66rem",
+    minWidth: "12px",
+    height: "12px",
+    border: `1px solid ${theme.palette.background.paper}`,
+    padding: "2px",
+  },
+}))
+
 const VisuallyHiddenInput = styled("input")({
   clip: "rect(0 0 0 0)",
   clipPath: "inset(50%)",
@@ -40,12 +52,16 @@ function Video({
   const [isCameraActive, setIsCameraActive] = useState<boolean>(false)
   const [isRecording, setIsRecording] = useState<boolean>(true)
   const isRecordingRef = useRef<boolean>(true)
+  const [isReplaying, setIsReplaying] = useState<boolean>(false)
   const holisticLandmarkerRef = useRef<HolisticLandmarker | null>(null)
   const [lastMedia, setLastMedia] = useState<string>("VIDEO")
 
   const landmarkHistoryRef = useRef<HolisticLandmarkerResult[]>([])
 
   const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
+    if (landmarkHistoryRef.current) {
+      landmarkHistoryRef.current = []
+    }
     const file = event.target.files?.[0]
     if (file) {
       const url = URL.createObjectURL(file)
@@ -117,8 +133,11 @@ function Video({
   const toggleRecording = () => {
     if (isRecording) {
       setIsRecording(false)
+      isRecordingRef.current = false
     } else {
+      landmarkHistoryRef.current = []
       setIsRecording(true)
+      isRecordingRef.current = true
     }
   }
 
@@ -182,8 +201,9 @@ function Video({
   }, [setPose, setFace, imgRef, videoRef, isRecordingRef])
 
   const replayCallback = () => {
+    setIsReplaying(true)
     let currentIndex = 0
-    const frameInterval = 1000 / 60 // 60 FPS
+    const frameInterval = 1000 / 30 // 30 FPS
 
     const playNextFrame = () => {
       if (currentIndex < landmarkHistoryRef.current.length) {
@@ -203,22 +223,14 @@ function Video({
 
         currentIndex++
         setTimeout(() => requestAnimationFrame(playNextFrame), frameInterval)
+      } else {
+        setIsReplaying(false)
       }
     }
 
     requestAnimationFrame(playNextFrame)
   }
 
-  useEffect(() => {
-    if (isRecording) {
-      landmarkHistoryRef.current = []
-      isRecordingRef.current = true
-    } else {
-      isRecordingRef.current = false
-      // save recorded
-    }
-  }, [isRecording, isRecordingRef])
-
   return (
     <>
       <div className="toolbar">
@@ -240,7 +252,19 @@ function Video({
         </Tooltip>
         <Tooltip title={isRecording ? "Stop recording" : "Record motion capture"}>
           <IconButton className="toolbar-item" onClick={toggleRecording} color="secondary" size="small">
-            {isRecording ? <StopCircle /> : <RadioButtonChecked />}
+            {isRecording ? (
+              <>
+                <StyledBadge badgeContent={landmarkHistoryRef.current.length} color="secondary" max={999}>
+                  <StopCircle />
+                </StyledBadge>
+              </>
+            ) : (
+              <>
+                <StyledBadge badgeContent={landmarkHistoryRef.current.length} color="secondary" max={999}>
+                  <RadioButtonChecked />
+                </StyledBadge>
+              </>
+            )}
           </IconButton>
         </Tooltip>
         <Tooltip title="Replay last capture">
@@ -249,7 +273,7 @@ function Video({
             onClick={replayCallback}
             color="secondary"
             size="small"
-            disabled={isCameraActive}
+            disabled={isCameraActive || isReplaying}
           >
             <Replay />
           </IconButton>