Fix iOS image long pressing

This commit is contained in:
Nicolas Mowen 2024-04-09 15:04:35 -06:00
parent a3f68cc761
commit 9b085ebe74
2 changed files with 62 additions and 6 deletions

View File

@ -13,13 +13,14 @@ import { getIconForLabel } from "@/utils/iconUtil";
import TimeAgo from "../dynamic/TimeAgo"; import TimeAgo from "../dynamic/TimeAgo";
import useSWR from "swr"; import useSWR from "swr";
import { FrigateConfig } from "@/types/frigateConfig"; import { FrigateConfig } from "@/types/frigateConfig";
import { isFirefox, isMobile, isSafari } from "react-device-detect"; import { isFirefox, isIOS, isMobile, isSafari } from "react-device-detect";
import Chip from "@/components/indicators/Chip"; import Chip from "@/components/indicators/Chip";
import { useFormattedTimestamp } from "@/hooks/use-date-utils"; import { useFormattedTimestamp } from "@/hooks/use-date-utils";
import useImageLoaded from "@/hooks/use-image-loaded"; import useImageLoaded from "@/hooks/use-image-loaded";
import { useSwipeable } from "react-swipeable"; import { useSwipeable } from "react-swipeable";
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
import ImageLoadingIndicator from "../indicators/ImageLoadingIndicator"; import ImageLoadingIndicator from "../indicators/ImageLoadingIndicator";
import useContextMenu from "@/hooks/use-contextmenu";
type PreviewPlayerProps = { type PreviewPlayerProps = {
review: ReviewSegment; review: ReviewSegment;
@ -73,6 +74,10 @@ export default function PreviewThumbnailPlayer({
setReviewed(review); setReviewed(review);
}, [review, setReviewed]); }, [review, setReviewed]);
useContextMenu(imgRef, () => {
onClick(review, true);
});
// playback // playback
const relevantPreview = useMemo(() => { const relevantPreview = useMemo(() => {
@ -170,10 +175,6 @@ export default function PreviewThumbnailPlayer({
className="relative size-full cursor-pointer" className="relative size-full cursor-pointer"
onMouseOver={isMobile ? undefined : () => setIsHovered(true)} onMouseOver={isMobile ? undefined : () => setIsHovered(true)}
onMouseLeave={isMobile ? undefined : () => setIsHovered(false)} onMouseLeave={isMobile ? undefined : () => setIsHovered(false)}
onContextMenu={(e) => {
e.preventDefault();
onClick(review, true);
}}
onClick={handleOnClick} onClick={handleOnClick}
{...swipeHandlers} {...swipeHandlers}
> >
@ -196,9 +197,18 @@ export default function PreviewThumbnailPlayer({
<div className={`${imgLoaded ? "visible" : "invisible"}`}> <div className={`${imgLoaded ? "visible" : "invisible"}`}>
<img <img
ref={imgRef} ref={imgRef}
className={`size-full transition-opacity ${ className={`size-full transition-opacity select-none ${
playingBack ? "opacity-0" : "opacity-100" playingBack ? "opacity-0" : "opacity-100"
}`} }`}
style={
isIOS
? {
WebkitUserSelect: "none",
WebkitTouchCallout: "none",
}
: undefined
}
draggable={false}
src={`${apiHost}${review.thumb_path.replace("/media/frigate/", "")}`} src={`${apiHost}${review.thumb_path.replace("/media/frigate/", "")}`}
loading={isSafari ? "eager" : "lazy"} loading={isSafari ? "eager" : "lazy"}
onLoad={() => { onLoad={() => {

View File

@ -0,0 +1,46 @@
import { MutableRefObject, useEffect } from "react";
import { isIOS } from "react-device-detect";
export default function useContextMenu(
ref: MutableRefObject<HTMLDivElement | null>,
callback: () => void,
) {
useEffect(() => {
if (!ref.current) {
return;
}
const elem = ref.current;
if (isIOS) {
let timeoutId: NodeJS.Timeout;
const touchStart = () => {
timeoutId = setTimeout(() => {
callback();
}, 610);
};
const touchClear = () => {
clearTimeout(timeoutId);
};
elem.addEventListener("touchstart", touchStart);
elem.addEventListener("touchmove", touchClear);
elem.addEventListener("touchend", touchClear);
return () => {
elem.removeEventListener("touchstart", touchStart);
elem.removeEventListener("touchmove", touchClear);
elem.removeEventListener("touchend", touchClear);
};
} else {
const context = (e: MouseEvent) => {
e.preventDefault();
callback();
};
elem.addEventListener("contextmenu", context);
return () => {
elem.removeEventListener("contextmenu", context);
};
}
}, [callback, ref]);
}