import { cn } from "@/commons"; import { Spinner } from "@/components"; import { settingsQueryOptions } from "@/routes/__root"; import { ArrowLeft, ArrowRight } from "@phosphor-icons/react"; import { useSuspenseQuery } from "@tanstack/react-query"; import { open } from "@tauri-apps/plugin-shell"; import useEmblaCarousel from "embla-carousel-react"; import { useCallback, useEffect, useMemo, useState } from "react"; export function Images({ urls }: { urls: string[] }) { const [slidesInView, setSlidesInView] = useState([]); const [emblaRef, emblaApi] = useEmblaCarousel({ dragFree: true, align: "start", watchSlides: false, }); const settings = useSuspenseQuery(settingsQueryOptions); const imageUrls = useMemo(() => { if (settings.data.resize_service) { let newUrls: string[]; if (urls.length === 1) { newUrls = urls.map((url) => { if (url.includes("_next/")) { return url; } if (url.includes("bsky.network")) { return url; } return `https://wsrv.nl?url=${url}&ll&af&default=1&n=-1`; }); } else { newUrls = urls.map((url) => { if (url.includes("_next/")) { return url; } if (url.includes("bsky.network")) { return url; } return `https://wsrv.nl?url=${url}&ll&af&default=1&n=-1`; }); } return newUrls; } else { return urls; } }, [settings.data.resize_service]); const scrollPrev = useCallback(() => { if (emblaApi) emblaApi.scrollPrev(); }, [emblaApi]); const scrollNext = useCallback(() => { if (emblaApi) emblaApi.scrollNext(); }, [emblaApi]); const updateSlidesInView = useCallback(() => { setSlidesInView((slidesInView) => { if (slidesInView.length === emblaApi?.slideNodes().length) { emblaApi?.off("slidesInView", updateSlidesInView); } const inView = emblaApi ?.slidesInView() .filter((index) => !slidesInView.includes(index)); if (inView) { return slidesInView.concat(inView); } else { return slidesInView; } }); }, [emblaApi]); useEffect(() => { if (emblaApi && urls.length > 1) { updateSlidesInView(); emblaApi.on("slidesInView", updateSlidesInView); emblaApi.on("reInit", updateSlidesInView); } return () => { emblaApi?.off("slidesInView", updateSlidesInView); emblaApi?.off("reInit", updateSlidesInView); }; }, [emblaApi, updateSlidesInView]); if (urls.length === 1) { return (
{urls[0]} urls[0]} onKeyDown={() => urls[0]} />
); } return (
{imageUrls.map((url, index) => ( -1} /> ))}
); } function LazyImage({ url, inView }: { url: string; inView: boolean }) { const [hasLoaded, setHasLoaded] = useState(false); const setLoaded = useCallback(() => { if (inView) setHasLoaded(true); }, [inView, setHasLoaded]); return (
{!hasLoaded ? (
) : null} open(url)} onKeyDown={() => open(url)} onLoad={setLoaded} />
); }