mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Add tooltips for review item chips (#10685)
* tooltips for review item chips * use flexbox instead of margins
This commit is contained in:
parent
bc6b4c38b8
commit
6fbd272acf
@ -19,6 +19,7 @@ import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
|||||||
import useImageLoaded from "@/hooks/use-image-loaded";
|
import useImageLoaded from "@/hooks/use-image-loaded";
|
||||||
import { Skeleton } from "../ui/skeleton";
|
import { Skeleton } from "../ui/skeleton";
|
||||||
import { useSwipeable } from "react-swipeable";
|
import { useSwipeable } from "react-swipeable";
|
||||||
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
|
||||||
|
|
||||||
type PreviewPlayerProps = {
|
type PreviewPlayerProps = {
|
||||||
review: ReviewSegment;
|
review: ReviewSegment;
|
||||||
@ -121,7 +122,11 @@ export default function PreviewThumbnailPlayer({
|
|||||||
|
|
||||||
const [hoverTimeout, setHoverTimeout] = useState<NodeJS.Timeout | null>();
|
const [hoverTimeout, setHoverTimeout] = useState<NodeJS.Timeout | null>();
|
||||||
const [playback, setPlayback] = useState(false);
|
const [playback, setPlayback] = useState(false);
|
||||||
const playingBack = useMemo(() => playback, [playback]);
|
const [tooltipHovering, setTooltipHovering] = useState(false);
|
||||||
|
const playingBack = useMemo(
|
||||||
|
() => playback && !tooltipHovering,
|
||||||
|
[playback, tooltipHovering],
|
||||||
|
);
|
||||||
const [isHovered, setIsHovered] = useState(false);
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -129,7 +134,7 @@ export default function PreviewThumbnailPlayer({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHovered) {
|
if (isHovered && !tooltipHovering) {
|
||||||
setHoverTimeout(
|
setHoverTimeout(
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setPlayback(true);
|
setPlayback(true);
|
||||||
@ -149,7 +154,7 @@ export default function PreviewThumbnailPlayer({
|
|||||||
}
|
}
|
||||||
// we know that these deps are correct
|
// we know that these deps are correct
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [isHovered, scrollLock]);
|
}, [isHovered, scrollLock, tooltipHovering]);
|
||||||
|
|
||||||
// date
|
// date
|
||||||
|
|
||||||
@ -196,28 +201,50 @@ export default function PreviewThumbnailPlayer({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<div className="absolute left-0 top-2 z-40">
|
||||||
|
<Tooltip>
|
||||||
|
<div
|
||||||
|
className="flex"
|
||||||
|
onMouseEnter={() => setTooltipHovering(true)}
|
||||||
|
onMouseLeave={() => setTooltipHovering(false)}
|
||||||
|
>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div className="mx-3 pb-1 text-white text-sm">
|
||||||
|
{(review.severity == "alert" ||
|
||||||
|
review.severity == "detection") && (
|
||||||
|
<>
|
||||||
|
<Chip
|
||||||
|
className={`flex items-start justify-between space-x-1 ${playingBack ? "hidden" : ""} bg-gradient-to-br ${review.has_been_reviewed ? "from-green-600 to-green-700 bg-green-600" : "from-gray-400 to-gray-500 bg-gray-500"} z-0`}
|
||||||
|
>
|
||||||
|
{review.data.objects.map((object) => {
|
||||||
|
return getIconForLabel(object, "size-3 text-white");
|
||||||
|
})}
|
||||||
|
{review.data.audio.map((audio) => {
|
||||||
|
return getIconForLabel(audio, "size-3 text-white");
|
||||||
|
})}
|
||||||
|
{review.data.sub_labels?.map((sub) => {
|
||||||
|
return getIconForSubLabel(sub, "size-3 text-white");
|
||||||
|
})}
|
||||||
|
</Chip>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
</div>
|
||||||
|
<TooltipContent className="capitalize">
|
||||||
|
{[
|
||||||
|
...(review.data.objects || []),
|
||||||
|
...(review.data.audio || []),
|
||||||
|
...(review.data.sub_labels || []),
|
||||||
|
]
|
||||||
|
.filter((item) => item !== undefined)
|
||||||
|
.join(", ")}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
{!playingBack && (
|
{!playingBack && (
|
||||||
<>
|
<>
|
||||||
<div className="absolute top-0 inset-x-0 rounded-t-l z-10 w-full h-[30%] bg-gradient-to-b from-black/60 to-transparent pointer-events-none">
|
<div className="absolute top-0 inset-x-0 rounded-t-l z-10 w-full h-[30%] bg-gradient-to-b from-black/60 to-transparent pointer-events-none"></div>
|
||||||
<div className="flex h-full justify-between items-start mx-3 pb-1 text-white text-sm ">
|
|
||||||
{(review.severity == "alert" ||
|
|
||||||
review.severity == "detection") && (
|
|
||||||
<Chip
|
|
||||||
className={`absolute top-2 left-2 flex gap-1 bg-gradient-to-br ${review.has_been_reviewed ? "from-green-600 to-green-700 bg-green-600" : "from-gray-400 to-gray-500 bg-gray-500"} z-0`}
|
|
||||||
>
|
|
||||||
{review.data.objects.map((object) => {
|
|
||||||
return getIconForLabel(object, "size-3 text-white");
|
|
||||||
})}
|
|
||||||
{review.data.audio.map((audio) => {
|
|
||||||
return getIconForLabel(audio, "size-3 text-white");
|
|
||||||
})}
|
|
||||||
{review.data.sub_labels?.map((sub) => {
|
|
||||||
return getIconForSubLabel(sub, "size-3 text-white");
|
|
||||||
})}
|
|
||||||
</Chip>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="absolute bottom-0 inset-x-0 rounded-b-l z-10 w-full h-[20%] bg-gradient-to-t from-black/60 to-transparent pointer-events-none">
|
<div className="absolute bottom-0 inset-x-0 rounded-b-l z-10 w-full h-[20%] bg-gradient-to-t from-black/60 to-transparent pointer-events-none">
|
||||||
<div className="flex h-full justify-between items-end mx-3 pb-1 text-white text-sm">
|
<div className="flex h-full justify-between items-end mx-3 pb-1 text-white text-sm">
|
||||||
<TimeAgo time={review.start_time * 1000} dense />
|
<TimeAgo time={review.start_time * 1000} dense />
|
||||||
|
Loading…
Reference in New Issue
Block a user