diff --git a/src/app/page.tsx b/src/app/page.tsx
index 5a1be64..6a73340 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -36,6 +36,7 @@ import LabelCard from "@components/CardYear";
import ProjectsSection from "@components/ProjectsSection";
import { motion } from "framer-motion";
import { Video } from "../types/Video";
+import Reviews from "@components/Reviews";
// const VIDEOS = [
// "/videos/features/virtual_tour.mp4",
@@ -680,6 +681,7 @@ export default function App() {
+
Проекты
diff --git a/src/components/Histories.tsx b/src/components/Histories.tsx
index e2a9861..aa507d8 100644
--- a/src/components/Histories.tsx
+++ b/src/components/Histories.tsx
@@ -6,8 +6,7 @@ import { Transition } from "react-transition-group";
import { motion } from "framer-motion";
import { Video } from "../types/Video";
-const CARD_COUNT = 3;
-const videos: Video[] = [
+const VIDEOS: Video[] = [
{
id: "1",
value: "/videos/histories/1.mp4",
@@ -52,18 +51,19 @@ const Histories = () => {
});
const [selectedVideo, setSelectedVideo] = useState
(0);
const [_document, setDocument] = useState();
+ const [isVideoFinish, setIsVideoFinish] = useState(false);
function handleOnLeftMove(): void {
if (selectedVideo > 0) {
setSelectedVideo((prev) => prev - 1);
- setOffset((prev) => prev + 1);
+ // setOffset((prev) => prev + 1);
}
}
function handleOnRightMove(): void {
if (selectedVideo < 2) {
setSelectedVideo((prev) => prev + 1);
- setOffset((prev) => prev - 1);
+ // setOffset((prev) => prev - 1);
}
}
@@ -71,7 +71,7 @@ const Histories = () => {
setDocument(document);
setVideoRefs((elRefs) =>
- Array.from({ length: CARD_COUNT }, (_, index) => index).map(
+ Array.from({ length: VIDEOS.length }, (_, index) => index).map(
(_, i) => elRefs[i] || createRef()
)
);
@@ -121,7 +121,7 @@ const Histories = () => {
currentVideoRef.current.currentTime;
setVideoProgress(progress);
- if (progress === 100) {
+ if (97 <= progress) {
clearInterval(interval);
}
}, 1000);
@@ -130,12 +130,19 @@ const Histories = () => {
}, [selectedVideo, videoRefs]);
useEffect(() => {
- if (100 - 3 < videoProgress) {
- if (offset <= -1 * videoRefs.length + 1) {
- setOffset(0);
+ if (100 - 5 < videoProgress) {
+ if (selectedVideo >= videoRefs.length - 1) {
+ // setOffset(0);
+ console.log("first");
setSelectedVideo(0);
+ setVideoProgress(0);
+ const currentVideoRef = videoRefs[selectedVideo];
+ if (currentVideoRef && currentVideoRef.current) {
+ currentVideoRef.current.currentTime = 0;
+ }
} else {
- setOffset((prev) => prev - 1);
+ console.log("second");
+ // setOffset((prev) => prev - 1);
setSelectedVideo((prev) => prev + 1);
}
}
@@ -157,7 +164,7 @@ const Histories = () => {
graff.estate
- {videos.map((item, index) => (
+ {VIDEOS.map((item, index) => (
{
transform: `translateX(${-selectedVideo * cardWidth}px)`,
}}
>
- {videos.map((video, index) => (
+ {VIDEOS.map((video, index) => (
{
{
- {videos[selectedVideo].title}
+ {VIDEOS[selectedVideo].title}
- {videos[selectedVideo].desc}
+ {VIDEOS[selectedVideo].desc}
@@ -251,7 +258,7 @@ const Histories = () => {
style={{ width: `${videoProgress}%` }}
>
- {videos.map((video, index) => (
+ {VIDEOS.map((video, index) => (
{
+ const [isViewportEntered, setIsViewportEntered] = useState
(false);
+
+ function handleViewportEnter() {
+ if (isViewportEntered) return;
+ setIsViewportEntered(true);
+ }
+
+ const [offset, setOffset] = useState(0);
+ const [videoRefs, setVideoRefs] = useState<
+ React.RefObject[]
+ >([]);
+ const [videoProgress, setVideoProgress] = useState(0);
+ const [cardWidth, setCardWidth] = useState(0);
+ const handlers = useSwipeable({
+ onSwipedLeft: handleOnRightMove,
+ onSwipedRight: handleOnLeftMove,
+ trackMouse: true,
+ });
+ const [selectedVideo, setSelectedVideo] = useState(0);
+ const [_document, setDocument] = useState();
+
+ function handleOnLeftMove(): void {
+ if (selectedVideo > 0) {
+ setSelectedVideo((prev) => prev - 1);
+ setOffset((prev) => prev + 1);
+ }
+ }
+
+ function handleOnRightMove(): void {
+ if (selectedVideo < 2) {
+ setSelectedVideo((prev) => prev + 1);
+ setOffset((prev) => prev - 1);
+ }
+ }
+
+ useEffect(() => {
+ setDocument(document);
+
+ setVideoRefs((elRefs) =>
+ Array.from({ length: VIDEOS.length }, (_, index) => index).map(
+ (_, i) => elRefs[i] || createRef()
+ )
+ );
+ }, []);
+
+ useEffect(() => {
+ if (!_document) return;
+
+ const clientWidth = _document.children[0].clientWidth;
+
+ if (clientWidth >= 1600) {
+ setCardWidth(420);
+ } else if (clientWidth >= 1280) {
+ setCardWidth(379);
+ } else if (clientWidth >= 640) {
+ setCardWidth(370);
+ } else {
+ setCardWidth(clientWidth - 16);
+ }
+ }, [_document]);
+
+ useEffect(() => {
+ videoRefs.forEach((video, index) => {
+ if (!video.current) return;
+ if (index === selectedVideo) {
+ video.current.play();
+ } else {
+ video.current.pause();
+ }
+ });
+ }, [videoRefs, selectedVideo, isViewportEntered]);
+
+ useEffect(() => {
+ const currentVideoRef = videoRefs[selectedVideo];
+ if (!currentVideoRef || !currentVideoRef.current) return;
+
+ const progress = Math.round(
+ (100 / currentVideoRef.current.duration) *
+ currentVideoRef.current.currentTime
+ );
+ setVideoProgress(progress);
+
+ const interval = setInterval(() => {
+ if (!currentVideoRef || !currentVideoRef.current) return;
+ const progress =
+ (100 / currentVideoRef.current.duration) *
+ currentVideoRef.current.currentTime;
+
+ setVideoProgress(progress);
+ if (progress === 100) {
+ clearInterval(interval);
+ }
+ }, 1000);
+
+ return () => clearInterval(interval);
+ }, [selectedVideo, videoRefs]);
+
+ useEffect(() => {
+ if (100 - 3 < videoProgress) {
+ if (offset <= -1 * videoRefs.length + 1) {
+ setOffset(0);
+ setSelectedVideo(0);
+ } else {
+ setOffset((prev) => prev - 1);
+ setSelectedVideo((prev) => prev + 1);
+ }
+ }
+ }, [videoProgress]);
+
+ return (
+
+
+
+
+
+
+
+ Отзывы
+
+
клиентов
+
+
+ {VIDEOS.map((item, index) => (
+
+ {(state) => (
+
+
+ {item.title}
+
+
+ {item.desc}
+
+
+ )}
+
+ ))}
+
+
+
+
+
+
+
+ {VIDEOS.map((video, index) => (
+
+ ))}
+
+
+
+
+
+ {VIDEOS[selectedVideo].title}
+
+
+ {VIDEOS[selectedVideo].desc}
+
+
+
+
+ {VIDEOS.map((video, index) => (
+
+ ))}
+
+
+
+
+ );
+};
+
+export default Reviews;