Expo Custom Cached Image Partially Gray (inconsistently on Android) using expo-file-system

66 views Asked by At

I wrote a custom CachedImage component that uses expo-file-system downloadAsync() to get images. Sometimes the images are loading in halfway, with the bottom half just gray. This seems to be only on Android, but is inconsistent so is hard to replicate.

I'm still somewhat new to Expo and React-Native so please let me know if I'm doing something wrong :)

Here's my code for my CachedImage component:

import React, { useEffect, useRef, useState } from 'react';
import { Image, ImageStyle } from 'react-native';
import { Storage } from 'aws-amplify';
import * as FileSystem from 'expo-file-system';

interface Props {
    source: string;
    style?: ImageStyle[] | ImageStyle;
    cacheKey?: string | null
}

export const CachedImage: React.FC<Props> = (props) => {
    const filesystemURI = `${FileSystem.cacheDirectory}${props.cacheKey ?? props.source}`;
    const [imgURI, setImgURI] = useState<string | null>(filesystemURI);
    const componentIsMounted = useRef(true);

    const loadImage = async (fileURI: string, downloadURI?: string) => {
        try {
          // Use the cached image if it exists
          const metadata = await FileSystem.getInfoAsync(fileURI)
          if (!metadata.exists) {
            // download to cache
            if (componentIsMounted.current) {
              setImgURI(null)
              await FileSystem.downloadAsync(
                downloadURI ?? props.source,
                fileURI
              )
            }
            if (componentIsMounted.current) {
              setImgURI(fileURI)
            }
          }
        } catch (err) {
          setImgURI(downloadURI ?? props.source);
        }
      }

    useEffect(() => {
      if (!props.source.includes('https')) {
        Storage.get(props.source!)
          .then(url => {
            loadImage(filesystemURI, url);
          });
      } else {
        loadImage(filesystemURI);
      }
  
      return () => {
        componentIsMounted.current = false;
      }
    }, [])

    return (
        <Image {...props} source={{ uri: imgURI!, cache: 'force-cache' }} />
    )
}

I also found a similar issue, but it didn't have any solutions: expo-file-system .downloadAsync leads to half-gray corrupted images. They have an image that looks like what I'm experiencing.

0

There are 0 answers