Photoswipe throws error in e-commerce gallery when I fetch image url from api without width and height

Viewed 13

I'm building e-shop and I'm trying to implement Photoswipe plugin to gallery. Everything works perfect, when I'm fetching data from vendure.io cms, because imgs have widht and height. Problem comes, when I fetch imgs from API, because I fetch only image url, but not the width and weight of the image.
Have someone any tips/tricks/quick replacement? || Has anyone encountered something similar? Everytime when I click on img and try to open lightbox with fetched img from external API, it throws error:

Unhandled Runtime Error

TypeError: can't access property "x", p2 is undefined

.next\static\chunks\src_photoswipe_ts.js (510:0) @ _equalizePoints

  508 |     
  509 |     _equalizePoints = function(p1, p2) {
> 510 |         p1.x = p2.x;
  511 |         p1.y = p2.y;
  512 |         if(p2.id) {
  513 |             p1.id = p2.id;

    function ProductGallery(props: ProductGalleryProps) {
  const { layout, images } = props;
  if (!images) {
    return <BlockLoader />;
  } else {
    const direction = useDirection();
    const [state, setState] = useState({ currentIndex: 0, transition: false });
    const imagesRefs = useRef<Array<HTMLImageElement | null>>([]);
    const slickFeaturedRef = useRef<Slick>(null);
    const createGalleryRef = useRef<Promise<CreateGalleryFn> | null>(null);
    const galleryRef = useRef<PhotoSwipe<PhotoSwipeUIDefault.Options> | null>(
      null
    );
    const getIndexDependOnDirRef = useRef<((index: number) => number) | null>(
      null
    );
    const unmountedRef = useRef(false);

    const getIndexDependOnDir = useCallback(
      (index: number) => {
        // we need to invert index id direction === 'rtl' due to react-slick bug
        if (direction === "rtl") {
          return images.length - 1 - index;
        }

        return index;
      },
      [direction, images]
    );

    const openPhotoswipe = (index: number) => {
      if (!createGalleryRef.current) {
        return;
      }

      const items = imagesRefs.current.map((tag, index) => {
        if (!tag) {
          throw Error("Image ref is null");
        }

        const width = images[index].width;

        const height = images[index].height;

        return {
          src: images[index].source,
          msrc: images[index].source,
          w: width,
          h: height,
        };
      });

      if (direction === "rtl") {
        items.reverse();
      }

      // noinspection JSUnusedGlobalSymbols
      const options: PhotoSwipe.Options = {
        getThumbBoundsFn: (index) => {
          // IMPORTANT: Inside this function, we can use variables and functions only through ref.
          if (!getIndexDependOnDirRef.current) {
            return { x: 0, y: 0, w: 0 };
          }

          const dirDependentIndex = getIndexDependOnDirRef.current(index);
          const tag = imagesRefs.current[dirDependentIndex];

          if (!tag) {
            return { x: 0, y: 0, w: 0 };
          }

          const width = tag.naturalWidth;
          const height = tag.naturalHeight;
          const rect = tag.getBoundingClientRect();
          const ration = Math.min(rect.width / width, rect.height / height);
          const fitWidth = width * ration;
          const fitHeight = height * ration;

          return {
            x: rect.left + (rect.width - fitWidth) / 2 + window.pageXOffset,
            y: rect.top + (rect.height - fitHeight) / 2 + window.pageYOffset,
            w: fitWidth,
          };
        },
        index: getIndexDependOnDir(index),
        bgOpacity: 0.9,
        history: false,
      };

      createGalleryRef.current.then((createGallery) => {
        // IMPORTANT: Inside this function, we can use variables and functions only through ref.

        if (unmountedRef.current) {
          return;
        }

        galleryRef.current = createGallery(items as any, options);
        galleryRef.current.listen("beforeChange", () => {
          if (galleryRef.current && slickFeaturedRef.current) {
            slickFeaturedRef.current.slickGoTo(
              galleryRef.current.getCurrentIndex(),
              true
            );
          }
        });
        galleryRef.current.listen("destroy", () => {
          galleryRef.current = null;
        });

        galleryRef.current.init();
      });
    };

Used technologies: Next.js. Vendure.io, Typescript, GraphQL

0 Answers
Related