mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-10 21:25:24 +03:00
Fix iOS image long pressing
This commit is contained in:
parent
a3f68cc761
commit
9b085ebe74
@ -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={() => {
|
||||||
|
|||||||
46
web/src/hooks/use-contextmenu.ts
Normal file
46
web/src/hooks/use-contextmenu.ts
Normal 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]);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user