matrix-art

An image gallery for Matrix
git clone git://archive.git.mtrnord.blog/MTRNord/matrix-art.git
Log | Files | Refs | README | LICENSE

asyncImages.tsx (1713B)


      1 // First we need a type of cache to avoid creating resources for images
      2 import { ImgHTMLAttributes } from "react";
      3 import { createResource, Resource } from "./resources";
      4 
      5 // we have already fetched in the past
      6 export const cache = new Map<string, Resource<string>>();
      7 
      8 // then we create our loadImage function, this function receives the source
      9 // of the image and returns a resource
     10 export function loadImage(source: string): Resource<string> {
     11     // here we start getting the resource from the cache
     12     let resource = cache.get(source);
     13     // and if it's there we return it immediately
     14     if (resource) return resource;
     15     // but if it's not we create a new resource
     16     resource = createResource<string>(
     17         () =>
     18             // in our async function we create a promise
     19             new Promise((resolve, reject) => {
     20                 // then create a new image element
     21                 const img = new window.Image();
     22                 // set the src to our source
     23                 img.src = source;
     24                 // and start listening for the load event to resolve the promise
     25                 img.addEventListener("load", () => resolve(source));
     26                 // and also the error event to reject the promise
     27                 img.addEventListener("error", () =>
     28                     reject(new Error(`Failed to load image ${source}`))
     29                 );
     30             })
     31     );
     32     // before finishing we save the new resource in the cache
     33     cache.set(source, resource);
     34     // and return return it
     35     return resource;
     36 }
     37 
     38 export function SuspenseImage(
     39     props: ImgHTMLAttributes<HTMLImageElement>
     40 ): JSX.Element {
     41     loadImage(props.src ?? "undefined").read();
     42     return <img {...props} />;
     43 }