Skip to content

Commit

Permalink
Fix - Menus animation for mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-dharti-r committed May 17, 2024
1 parent 33eb97a commit 3075e3b
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 171 deletions.
29 changes: 29 additions & 0 deletions website/components/Reel/hook.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useEffect, useState, useRef, RefObject } from 'react';

const useAutoplayVisibility = (): [boolean, RefObject<HTMLDivElement>] => {
const [autoplayEnabled, setAutoplayEnabled] = useState(true);
const ref = useRef<HTMLDivElement>(null);

useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
setAutoplayEnabled(entry.isIntersecting);
},
{ threshold: 0.5 }
);

if (ref.current) {
observer.observe(ref.current);
}

return () => {
if (ref.current) {
observer.unobserve(ref.current);
}
};
}, [ref]);

return [autoplayEnabled, ref];
};

export default useAutoplayVisibility;
52 changes: 5 additions & 47 deletions website/components/Reel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,22 @@ import "swiper/css/effect-fade";
import VideoPlayer from "@/components/VideoPlayer";
import MenuDishSkeleton from "@/components/SkeletonPlaceholders/MenuDish";
import NoDataFound from "../NoDataFound";
import SwiperComponent from "./swiper";
import "swiper/react";
import { useAppSelector } from "@/store/store";

interface ReelProps {
dishesData: any;
isDishesLoading: boolean;
}

const Reels = ({ dishesData, isDishesLoading }: ReelProps) => {
const [screenHeight, setScreenHeight] = useState<number>(0);
const screenHeight = useAppSelector((state) => state.app.screenHeight);

const carouselRef = useRef<HTMLDivElement>(null);
const [numDivsToRender, setNumDivsToRender] = useState(2); // Initial number of dish to render

useEffect(() => {
setScreenHeight(window.innerHeight);

const observerOptions = {
root: null, // The viewport as the root
rootMargin: "0px",
Expand Down Expand Up @@ -59,15 +60,6 @@ const Reels = ({ dishesData, isDishesLoading }: ReelProps) => {
}
};
}

window.addEventListener("resize", () =>
setScreenHeight(window.innerHeight)
);

return () =>
window.removeEventListener("resize", () =>
setScreenHeight(window.innerHeight)
);
}, [carouselRef, numDivsToRender, dishesData?.length]);

return (
Expand Down Expand Up @@ -110,41 +102,7 @@ const Reels = ({ dishesData, isDishesLoading }: ReelProps) => {
classes={"h-full w-full object-cover"}
/>
) : (
<Swiper
modules={[Autoplay, EffectFade]}
slidesPerView={1}
loop={true}
autoplay={true}
effect="fade"
className="w-full"
style={{
height:
screenHeight != 0 ? screenHeight + "px" : "100vh",
}}
>
{data.images.map((data: any, index: any) => (
<div key={"mobile-image-" + index}>
<SwiperSlide>
<div
className="h-full"
style={{
backgroundImage: `url(${data})`,
}}
>
<div className="flex h-full w-full items-center bg-black bg-opacity-20 backdrop-blur-sm">
<Image
src={data}
height={100}
width={100}
alt="menu-dish-image"
className="w-full"
/>
</div>
</div>
</SwiperSlide>
</div>
))}
</Swiper>
<SwiperComponent images={data.images}></SwiperComponent>
)}
<div className="absolute bottom-0 z-[1] flex h-full w-full flex-col gap-3 bg-gradient-to-t from-black/80 via-transparent to-black/60 p-5 pb-10 text-white">
<div className="flex h-full items-end justify-between gap-5 border-b border-white/10 pb-2 text-xl font-bold">
Expand Down
80 changes: 80 additions & 0 deletions website/components/Reel/swiper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import Image from "next/image";
import { Autoplay, EffectFade } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/react";
import SwiperCore from "swiper";

import "swiper/css";
import "swiper/css/effect-fade";

import { useEffect, useRef, useState } from "react";
import useAutoplayVisibility from "./hook";
import { useAppSelector } from "@/store/store";

type SwiperCore = any;

const SwiperComponent = ({ images }: { images: any }) => {
const [autoplayEnabled, ref] = useAutoplayVisibility();
const screenHeight = useAppSelector((state) => state.app.screenHeight);

const swiperRef = useRef<SwiperCore | null>(null);

useEffect(() => {
if (swiperRef.current) {
if (autoplayEnabled) {
swiperRef.current.autoplay.start();
} else {
swiperRef.current.autoplay.stop();
}
}
}, [autoplayEnabled]);

return (
<div ref={ref} className={`${autoplayEnabled}`}>
<Swiper
onSwiper={(swiper) => {
swiperRef.current = swiper;
if (autoplayEnabled) {
swiper.autoplay.start();
}
}}
modules={[Autoplay, EffectFade]}
slidesPerView={1}
loop={true}
autoplay={{
delay: 3000,
disableOnInteraction: false,
}}
effect="fade"
className="w-full"
style={{
height: screenHeight != 0 ? screenHeight + "px" : "100vh",
}}
>
{images.map((imageUrl: any, index: any) => (
<>
<SwiperSlide key={"mobile-image-" + index}>
<div
className="h-full"
style={{
backgroundImage: `url(${imageUrl})`,
}}
>
<div className="flex h-full w-full items-center bg-black bg-opacity-20 backdrop-blur-sm">
<Image
src={imageUrl}
height={100}
width={100}
alt="menu-dish-image"
className="w-full"
/>
</div>
</div>
</SwiperSlide>
</>
))}
</Swiper>
</div>
);
};

export default SwiperComponent;
4 changes: 3 additions & 1 deletion website/pages/category/restaurant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ const Restaurant = ({
"-" +
btoa(item.id.toString())
}
className={`w-full absolute bottom-[4.75rem] xs:bottom-14 md:bottom-[5.25rem] group cursor-pointer ${!isPageReset ? "animated-fade-y" : ""}`}
className={`w-full absolute bottom-[4.75rem] xs:bottom-14 md:bottom-[5.25rem] group cursor-pointer ${
!isPageReset ? "animated-fade-y" : ""
}`}
>
<p className="w-full bg-black bg-opacity-40 py-2 pl-5 text-xl font-extrabold capitalize text-white dark:border-white sm:text-2xl">
{item.name}
Expand Down
15 changes: 8 additions & 7 deletions website/pages/restaurants/[restaurant]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
setRestaurantsState,
} from "@/store/restaurant/slice";
import withScrollRestoration from "@/components/withScrollRestoration";
import { setScreenHeightState } from "@/store/slice";

const RestaurantMenu = () => {
const router = useRouter();
Expand All @@ -33,7 +34,7 @@ const RestaurantMenu = () => {
?.toString()
.substring(restaurant?.lastIndexOf("-") + 1);

const [screenHeight, setScreenHeight] = useState<number>(0);
const screenHeight = useAppSelector((state) => state.app.screenHeight);

const dispatch = useAppDispatch();
const isPageReset = useAppSelector((state) => state.app.isPageReset);
Expand All @@ -57,7 +58,7 @@ const RestaurantMenu = () => {
const [menuData, setMenuData] = useState<any[]>([]);

useEffect(() => {
setScreenHeight(window.innerHeight);
dispatch(setScreenHeightState(window.innerHeight));

const fetchRestaurantData = async () => {
if (suffix) {
Expand Down Expand Up @@ -174,15 +175,15 @@ const RestaurantMenu = () => {
}
}

window.addEventListener("resize", () =>
setScreenHeight(window.innerHeight)
);
window.addEventListener("resize", () => {
dispatch(setScreenHeightState(window.innerHeight));
});

return () =>
window.removeEventListener("resize", () =>
setScreenHeight(window.innerHeight)
dispatch(setScreenHeightState(window.innerHeight))
);
}, [suffix]);
}, [suffix, dispatch]);

const resizableRestaurantDivRef = useRef<HTMLDivElement>(null);
const [scrolled, setScrolled] = useState(false);
Expand Down
Loading

0 comments on commit 3075e3b

Please sign in to comment.