Added top gradient to property page.

This commit is contained in:
Tom Butcher 2026-01-02 23:54:58 +00:00
parent 96ddbf42fc
commit 093ba1450a

View File

@ -1,3 +1,4 @@
import { useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
import { Layout } from "antd";
import ContentRenderer from "./ContentRenderer";
@ -20,6 +21,96 @@ const PropertyPage = ({ propertyData, visible = true, onClose = () => {} }) => {
const isMobile = useMediaQuery({ maxWidth: 800 });
console.log("Rerender " + propertyData.name, visible);
const mobileImage = isMobile;
const scrollRef = useRef(null);
const [isImageShrunk, setIsImageShrunk] = useState(false);
const [safariBlurToggle, setSafariBlurToggle] = useState(false);
const shrinkDistance = 1;
// Reset scroll position and image state when visible becomes false
useEffect(() => {
if (!visible && scrollRef.current) {
scrollRef.current.scrollTop = 0;
setIsImageShrunk(false);
}
}, [visible]);
// SafariBlurToggle animation when isImageShrunk changes
useEffect(() => {
if (!mobileImage) return;
let animationId;
let timeoutId;
const startTime = Date.now();
const duration = 750; // 0.75 seconds
const animate = () => {
const elapsed = Date.now() - startTime;
if (elapsed < duration) {
setSafariBlurToggle((prev) => !prev);
animationId = requestAnimationFrame(animate);
} else {
// Stop toggling after 0.75s
setSafariBlurToggle(false);
}
};
// Start the animation
animationId = requestAnimationFrame(animate);
return () => {
if (animationId) {
cancelAnimationFrame(animationId);
}
if (timeoutId) {
clearTimeout(timeoutId);
}
};
}, [isImageShrunk, mobileImage]);
useEffect(() => {
if (!scrollRef.current || !mobileImage) return;
const handleScroll = () => {
// Don't shrink image if page is not visible
if (!visible) return;
const el = scrollRef.current;
const scrollTop = el.scrollTop;
const scrollHeight = el.scrollHeight;
const clientHeight = el.clientHeight;
// Check if the container can be scrolled (is overflowing)
const canScroll = scrollHeight > clientHeight;
const shouldShrink = scrollTop > shrinkDistance;
// If container can't be scrolled, keep image shrunk if it's already shrunk
if (!canScroll && isImageShrunk) {
return; // Keep the image shrunk
}
// If container can be scrolled, allow image to un-shrink when at top
if (canScroll) {
if (scrollTop <= shrinkDistance) {
setIsImageShrunk(false);
} else if (shouldShrink) {
setIsImageShrunk(true);
}
} else if (shouldShrink) {
// If container can't be scrolled but we're past threshold, shrink
setIsImageShrunk(true);
}
};
const el = scrollRef.current;
el.addEventListener("scroll", handleScroll);
return () => {
el.removeEventListener("scroll", handleScroll);
};
}, [mobileImage, visible, isImageShrunk]);
return (
<div
className={
@ -42,11 +133,19 @@ const PropertyPage = ({ propertyData, visible = true, onClose = () => {} }) => {
<CloseButton onClick={onClose} />
</div>
{mobileImage && (
<div className="th-page-mobile-image-wrapper">
<div
className={`th-page-mobile-image-wrapper${
visible == false ? ` th-page-mobile-image-wrapper-hidden` : ``
}${isImageShrunk ? ` th-page-mobile-image-wrapper-shrunk` : ``}`}
>
<div
className={`th-top-gradient ${safariBlurToggle ? "refresh" : ""}`}
></div>
<ImageCarousel page={propertyData} className="th-mobile-image" />
</div>
)}
<Content
ref={scrollRef}
className={`th-page-content${
visible == false ? " th-page-content-hidden" : ""
}${isLargeMobile ? " th-page-content-mobile" : ""}`}