new indicator

This commit is contained in:
Josh Hawkins 2024-03-03 07:27:06 -06:00
parent 8645545ef4
commit fbc55b5e15
4 changed files with 72 additions and 26 deletions

View File

@ -0,0 +1,33 @@
function CameraActivityIndicator() {
return (
<div className="flex items-center justify-center relative z-20">
<div className="flex">
<div className="absolute size-[5px] inset-0 bg-severity_alert-dimmed rounded-full shadow-[0px_0px_10px_0px_#00000024,0px_0px_15px_0px_#00000024] z-20 animate-move"></div>
<div className="flex-1 size-[5px] mr-[2px] bg-severity_alert rounded-full animate-scale1"></div>
<div className="flex-1 size-[5px] mr-[2px] bg-severity_alert rounded-full animate-scale2"></div>
<div className="flex-1 size-[5px] mr-[2px] bg-severity_alert rounded-full animate-scale3"></div>
<div className="flex-1 size-[5px] mr-[2px] bg-severity_alert rounded-full animate-scale4"></div>
</div>
<svg className="hidden" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="goo">
<feGaussianBlur
in="SourceGraphic"
stdDeviation="10"
result="blur"
/>
<feColorMatrix
in="blur"
type="matrix"
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7"
result="goo"
/>
<feBlend in="SourceGraphic" in2="goo" />
</filter>
</defs>
</svg>
</div>
);
}
export default CameraActivityIndicator;

View File

@ -5,14 +5,13 @@ import ActivityIndicator from "../ui/activity-indicator";
import { useEffect, useMemo, useState } from "react";
import MSEPlayer from "./MsePlayer";
import JSMpegPlayer from "./JSMpegPlayer";
import { MdCircle, MdLeakAdd } from "react-icons/md";
import { BsSoundwave } from "react-icons/bs";
import Chip from "../Chip";
import { MdCircle } from "react-icons/md";
import useCameraActivity from "@/hooks/use-camera-activity";
import { useRecordingsState } from "@/api/ws";
import { LivePlayerMode } from "@/types/live";
import useCameraLiveMode from "@/hooks/use-camera-live-mode";
import { isDesktop } from "react-device-detect";
import CameraActivityIndicator from "../CameraActivityIndicator";
type LivePlayerProps = {
className?: string;
@ -159,35 +158,19 @@ export default function LivePlayer({
/>
</div>
<div className="absolute flex left-2 top-2 gap-2">
<Chip
in={activeMotion}
className={`bg-gradient-to-br from-gray-400 to-gray-500 bg-gray-500`}
>
<MdLeakAdd className="size-4 text-motion" />
<div className="hidden md:block ml-1 text-white text-xs">Motion</div>
</Chip>
{cameraConfig.audio.enabled_in_config && (
<Chip
in={activeAudio}
className={`bg-gradient-to-br from-gray-400 to-gray-500 bg-gray-500`}
>
<BsSoundwave className="size-4 text-audio" />
<div className="hidden md:block ml-1 text-white text-xs">Sound</div>
</Chip>
<div className="absolute right-2 bottom-2 w-[40px]">
{(activeMotion ||
(cameraConfig.audio.enabled_in_config && activeAudio)) && (
<CameraActivityIndicator />
)}
</div>
{isDesktop && (
<Chip className="absolute right-2 top-2 bg-gradient-to-br from-gray-400 to-gray-500 bg-gray-500">
<div className="absolute right-2 top-2 size-4">
{recording == "ON" && (
<MdCircle className="size-2 drop-shadow-md shadow-danger text-danger" />
<MdCircle className="size-2 drop-shadow-md shadow-danger text-danger animate-pulse" />
)}
<div className="ml-1 capitalize text-white text-xs">
{cameraConfig.name.replaceAll("_", " ")}
</div>
</Chip>
)}
</div>
);

View File

@ -6,6 +6,7 @@ import ActivityIndicator from "@/components/ui/activity-indicator";
import EventReviewTimeline from "@/components/timeline/EventReviewTimeline";
import { ReviewData, ReviewSegment, ReviewSeverity } from "@/types/review";
import { Button } from "@/components/ui/button";
import CameraActivityIndicator from "@/components/CameraActivityIndicator";
// Color data
const colors = [
@ -174,6 +175,9 @@ function UIPlayground() {
<p className="text-small">
Handlebar is dragging: {isDragging ? "yes" : "no"}
</p>
<div className="w-[40px] my-4">
<CameraActivityIndicator />
</div>
<p>
<Button onClick={handleZoomOut} disabled={zoomLevel === 0}>
Zoom Out

View File

@ -27,6 +27,11 @@ module.exports = {
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
move: "move 3s ease-in-out infinite",
scale1: "scale1 3s ease-in-out infinite",
scale2: "scale2 3s ease-in-out infinite",
scale3: "scale3 3s ease-in-out infinite",
scale4: "scale4 3s ease-in-out infinite",
},
aspectRatio: {
wide: "32 / 9",
@ -96,6 +101,27 @@ module.exports = {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: 0 },
},
move: {
"50%": { left: "calc(100% - 7px)" },
},
scale1: {
"0%, 100%": { transform: "scale(1.3)" },
"10%, 90%": { transform: "scale(1.4)" },
"20%, 80%": { transform: "scale(1)" },
},
scale2: {
"20%, 80%": { transform: "scale(1.4)" },
"10%, 30%, 70%, 90%": { transform: "scale(1)" },
},
scale3: {
"30%, 70%": { transform: "scale(1.4)" },
"20%, 40%, 60%, 80%": { transform: "scale(1)" },
},
scale4: {
"50%": { transform: "scale(1.3)" },
"40%, 60%": { transform: "scale(1.4)" },
"30%, 70%": { transform: "scale(1)" },
},
},
screens: {
xs: "480px",