pause / play vid with useInView
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Martti Malmi 2023-12-13 11:37:14 +02:00
parent b199d297ce
commit 1fe6a2a50d

View File

@ -1,8 +1,9 @@
import { ProxyImg } from "@/Element/ProxyImg"; import { ProxyImg } from "@/Element/ProxyImg";
import useImgProxy from "@/Hooks/useImgProxy"; import useImgProxy from "@/Hooks/useImgProxy";
import { IMeta } from "@snort/system"; import { IMeta } from "@snort/system";
import React, { CSSProperties, useMemo, useRef } from "react"; import React, { CSSProperties, useEffect, useMemo, useRef } from "react";
import classNames from "classnames"; import classNames from "classnames";
import { useInView } from "react-intersection-observer";
interface MediaElementProps { interface MediaElementProps {
mime: string; mime: string;
@ -13,17 +14,30 @@ interface MediaElementProps {
export function MediaElement(props: MediaElementProps) { export function MediaElement(props: MediaElementProps) {
const { proxy } = useImgProxy(); const { proxy } = useImgProxy();
const ref = useRef<HTMLImageElement | null>(null); const imageRef = useRef<HTMLImageElement | null>(null);
const { ref: videoContainerRef, inView } = useInView({ threshold: 1 });
const videoRef = useRef<HTMLVideoElement | null>(null);
const autoplay = window.innerWidth >= 768; const autoplay = window.innerWidth >= 768;
useEffect(() => {
if (!autoplay || !videoRef.current) {
return;
}
if (inView) {
videoRef.current.play();
} else {
videoRef.current.pause();
}
}, [inView]);
const style = useMemo(() => { const style = useMemo(() => {
const style = {} as CSSProperties; const style = {} as CSSProperties;
if (props.meta?.height && props.meta.width && ref.current) { if (props.meta?.height && props.meta.width && imageRef.current) {
const scale = ref.current.offsetWidth / props.meta.width; const scale = imageRef.current.offsetWidth / props.meta.width;
style.height = `${props.meta.height * scale}px`; style.height = `${props.meta.height * scale}px`;
} }
return style; return style;
}, [ref.current]); }, [imageRef.current]);
if (props.mime.startsWith("image/")) { if (props.mime.startsWith("image/")) {
return ( return (
@ -34,7 +48,7 @@ export function MediaElement(props: MediaElementProps) {
onClick={props.onMediaClick} onClick={props.onMediaClick}
className={classNames("max-h-[80vh]", { "md:max-h-80": !props.meta })} className={classNames("max-h-[80vh]", { "md:max-h-80": !props.meta })}
style={style} style={style}
ref={ref} ref={imageRef}
/> />
</div> </div>
); );
@ -42,9 +56,9 @@ export function MediaElement(props: MediaElementProps) {
return <audio key={props.url} src={props.url} controls />; return <audio key={props.url} src={props.url} controls />;
} else if (props.mime.startsWith("video/")) { } else if (props.mime.startsWith("video/")) {
return ( return (
<div className="flex justify-center items-center -mx-4 md:mx-0 md:h-80 my-2"> <div ref={videoContainerRef} className="flex justify-center items-center -mx-4 md:mx-0 md:h-80 my-2">
<video <video
autoPlay={autoplay} ref={videoRef}
loop={true} loop={true}
muted={autoplay} muted={autoplay}
key={props.url} key={props.url}