import _ from "lodash"; import React, { useRef, useState, useEffect } from "react"; import { Link } from "react-router-dom"; import * as GQL from "src/core/generated-graphql"; import { StashService } from "src/core/StashService"; import { VideoHoverHook } from "src/hooks"; import { TextUtils, NavUtils } from "src/utils"; interface IWallItemProps { scene?: GQL.SlimSceneDataFragment; sceneMarker?: GQL.SceneMarkerDataFragment; origin?: string; onOverlay: (show: boolean) => void; clickHandler?: ( item: GQL.SlimSceneDataFragment | GQL.SceneMarkerDataFragment ) => void; } export const WallItem: React.FC = ( props: IWallItemProps ) => { const [videoPath, setVideoPath] = useState(); const [previewPath, setPreviewPath] = useState(""); const [screenshotPath, setScreenshotPath] = useState(""); const [title, setTitle] = useState(""); const [tags, setTags] = useState([]); const config = StashService.useConfiguration(); const videoHoverHook = VideoHoverHook.useVideoHover({ resetOnMouseLeave: true }); const showTextContainer = config.data?.configuration.interface.wallShowTitle ?? true; function onMouseEnter() { VideoHoverHook.onMouseEnter(videoHoverHook); if (!videoPath || videoPath === "") { if (props.sceneMarker) { setVideoPath(props.sceneMarker.stream || ""); } else if (props.scene) { setVideoPath(props.scene.paths.preview || ""); } } props.onOverlay(true); } const debouncedOnMouseEnter = useRef(_.debounce(onMouseEnter, 500)); function onMouseLeave() { VideoHoverHook.onMouseLeave(videoHoverHook); setVideoPath(""); debouncedOnMouseEnter.current.cancel(); props.onOverlay(false); } function onClick() { if (props.clickHandler === undefined) { return; } if (props.scene !== undefined) { props.clickHandler(props.scene); } else if (props.sceneMarker !== undefined) { props.clickHandler(props.sceneMarker); } } let linkSrc: string = "#"; if (props.clickHandler) { if (props.scene) { linkSrc = `/scenes/${props.scene.id}`; } else if (props.sceneMarker) { linkSrc = NavUtils.makeSceneMarkerUrl(props.sceneMarker); } } function onTransitionEnd(event: React.TransitionEvent) { const target = event.currentTarget; if (target.classList.contains("double-scale") && target.parentElement) { target.parentElement.style.zIndex = "10"; } else if (target.parentElement) { target.parentElement.style.zIndex = ""; } } useEffect(() => { if (props.sceneMarker) { setPreviewPath(props.sceneMarker.preview); setTitle( `${props.sceneMarker!.title} - ${TextUtils.secondsToTimestamp( props.sceneMarker.seconds )}` ); const thisTags = props.sceneMarker.tags.map(tag => ( {tag.name} )); thisTags.unshift( {props.sceneMarker.primary_tag.name} ); setTags(thisTags); } else if (props.scene) { setPreviewPath(props.scene.paths.webp || ""); setScreenshotPath(props.scene.paths.screenshot || ""); setTitle(props.scene.title || ""); // tags = props.scene.tags.map((tag) => ({tag.name})); } }, [props.sceneMarker, props.scene]); function previewNotFound() { if (previewPath !== screenshotPath) { setPreviewPath(screenshotPath); } } const className = ["scene-wall-item-container"]; if (videoHoverHook.isHovering.current) { className.push("double-scale"); } const style: React.CSSProperties = {}; if (props.origin) { style.transformOrigin = props.origin; } return (
debouncedOnMouseEnter.current()} onMouseMove={() => debouncedOnMouseEnter.current()} onMouseLeave={onMouseLeave} > onClick()} to={linkSrc}>
); };