Giter Site home page Giter Site logo

expo-cached-image's Introduction

expo-cached-image

Super fast cached image component for react-native applications built with expo

Usage

Add to project

yarn add expo-cached-image

or

npx expo install expo-cached-image

CachedImage

import CachedImage from 'expo-cached-image'

Then it can be referenced in code like this:

<CachedImage
          source={{ 
            uri: `${item.getThumbUrl}`, // (required) -- URI of the image to be cached
            headers: `Authorization: Bearer ${token}`, // (optional)            
            expiresIn: 2_628_288, // 1 month in seconds (optional), if not set -- will never expire and will be managed by the OS
          }}
          cacheKey={`${item.id}-thumb`} // (required) -- key to store image locally
          placeholderContent={( // (optional) -- shows while the image is loading
            <ActivityIndicator // can be any react-native tag
              color={
                CONST.MAIN_COLOR
              }
              size="small"
              style={{
                flex: 1,
                justifyContent: "center",
              }}
            />
          )} 
          resizeMode="contain" // pass-through to <Image /> tag 
          style={              // pass-through to <Image /> tag 
            styles.photoContainer
          }
        />

<CachedImage/> internally uses the <Image/> component from 'react-native', so any properties that apply to the <Image/> can be passed into the <CachedImage/>.

cacheKey is the only property that's <CachedImage/> specific. The same cacheKey value should always be passed for the same source value. This is a little bit of an extra work from application development point of view, but this is how <CachedImage/> achieves it's performance. If not for cacheKey, the component would have to use some Crypto hash, which would add computational overhead. If you are rendering lots of images in a list on a screen -- this component will achieve the best performance.

CacheManager

import { CacheManager } from 'expo-cached-image'

If you have an image on local file system, which you want to add to cache, do this:

  photo.getImgUrl = await CacheManager.addToCache({
    file: `${CONST.PENDING_UPLOADS_FOLDER}${item}`,
    key: `${photo.id}`,
  })

To get local uri of the cached file by key:

  const uri = await CacheManager.getCachedUri({ key: `${item.id}` })

To pre-populate the cache ahead of time from remote URI:

// this is a convinience wrapper for https://docs.expo.dev/versions/latest/sdk/filesystem/#filesystemdownloadasyncuri-fileuri-options
  await CacheManager.downloadAsync({uri: `${item.url}`, key: `${item.id}`})

Sample projects

https://github.com/echowaves/WiSaw

https://www.wisaw.com/

expo-cached-image's People

Contributors

amiralidev avatar dmitryame avatar masayuki0109 avatar shiroyasha9 avatar sprutner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

expo-cached-image's Issues

Cache not working on Android (simulator)

Hey!

Currently, we're implementing this package to cache our images on a social wall. All of this works perfectly on iOS but whenever we launch the app on the Android Simulator, the cached images won't load or cache at all (it seems at least)

We have a custom Image component where we provide the required props like so:

<Image
        resizeMode="cover"
        source={{
          uri,
        }}
        cacheKey={id}
        style={{
          width: imageContainerWidth,
          height: customHeight ?? imageContainerWidth * (height / width),
        }}
      />

And within this Image component we render it as follows:

export const Image = (props: ImageProps) => {
  const { source: rawSource, cacheKey, size } = props
  const source = appendSizeToUrl(rawSource, size)
  // If the source is a number it means it's a client-side "require" for a file
  // So, if the image exists on the client, we don't need to cache it.
  // Also, only cache the image if a cache key has been provided.
  if (!cacheKey || typeof source === "number") {
    return <RNImage {...props} />
  }

  return <ExpoCachedImage {...props} cacheKey={`${cacheKey}`} />
}

RNImage in this case is the default react native image component.
If I remove the cacheKey it, of course, uses the default rn image component, and the images load, but once I provide a cacheKey they will stop working on Android.

Do more people have this issue, or am I missing something here?

Cached Image does not show

Installed versions:

    "@react-navigation/native": "^6.1.9",
    "@react-navigation/native-stack": "^6.9.17",
    "@rneui/base": "^4.0.0-rc.8",
    "@rneui/themed": "^4.0.0-rc.8",
    "expo": "~50.0.3",
    "expo-cached-image": "^49.0.2",
    "expo-status-bar": "~1.11.1",
    "nativewind": "^2.0.11",
    "react": "18.2.0",
    "react-native": "0.73.2",
    "react-native-safe-area-context": "4.8.2",
    "react-native-screens": "~3.29.0"

I cannot see the image. I changed the cachekey to make sure it's not cached wrongly, but still cannot see anything. I replaced CachedImage with RN Image and the image shows up normally.

With this code, there is nothing:

const Home = ({ navigation }: NativeStackScreenProps<RootStackParamList, 'Home'>) => {
  return <View className="flex-1 items-center justify-center">
              <Button title='Characters' onPress={() => 
              navigation.navigate('CharacterList')}/>
              
              <CachedImage className='w-[100px] h-[100px]' source={{ uri: 'https://genshin.jmp.blue/characters/albedo/icon-big', expiresIn: 0}} cacheKey='test1'/>
        </View>
}
image

However when changed to the normal Image component, it works:

const Home = ({ navigation }: NativeStackScreenProps<RootStackParamList, 'Home'>) => {
  return <View className="flex-1 items-center justify-center">
            <Button title='Characters' onPress={() => 
              navigation.navigate('CharacterList')}/>
              <Image className='w-[100px] h-[100px]' source={{ uri: 'https://genshin.jmp.blue/characters/albedo/icon-big'}}/>
        </View>
}
image

Clear whole cache

Is it planned, that the CacheManager gets the possibility to clear the whole cache?

Cache time

I'd like images to refresh theirselves every hour.
Is there any way to make the caching time based?
Maybe like using JS date function in cacheKey property?

CacheManager.downloadAsync is not a function

Not sure what's going on. I'm trying to load images from a remote url at the top of my app with the below code and im getting a warning that CacheManager.downloadAsync is not a function`.

const useAppIsReady = async (data) => {
  ...
  await CacheManager.downloadAsync({ uri: "google.com", key: "snafwiofhawi" });
  ...
}
Possible Unhandled Promise Rejection (id: 643):
TypeError: _expoCachedImage.CacheManager.downloadAsync is not a function. (In '_expoCachedImage.CacheManager.downloadAsync({   
        uri: "google.com",
        key: "snafwiofhawi"
      })', '_expoCachedImage.CacheManager.downloadAsync' is undefined)
@

Could not find a declaration file

On hovering

import CachedImage from 'expo-cached-image';

Code editor gives this warning:

Could not find a declaration file for module 'expo-cached-image'. 'c:/Projects/thanksapp/node_modules/expo-cached-image/lib/index.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/expo-cached-image` if it exists or add a new declaration (.d.ts) file containing `declare module 'expo-cached-image';`

The component isn't working either.

Wrong react version when install package

When I'm trying to install expo-cached-image with npx expo install expo-cached-image command to my Expo project (latest SDK version 46) I'm getting this error

PS F:\Code\cinema-mobile-app> npx expo install expo-cached-image
› Installing 1 other package using npm
> npm install --save expo-cached-image
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   react@"18.0.0" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer react@"18.2.0" from [email protected]
npm ERR! node_modules/expo-cached-image
npm ERR!   expo-cached-image@"*" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! See C:\Users\as\AppData\Local\npm-cache\eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\as\AppData\Local\npm-cache\_logs\2022-08-17T07_38_33_619Z-debug-0.log

Error: npm exited with non-zero code: 1
Error: npm exited with non-zero code: 1
    at ChildProcess.completionListener (F:\Code\cinema-mobile-app\node_modules\@expo\spawn-async\build\spawnAsync.js:52:23)
    at Object.onceWrapper (node:events:640:26)
    at ChildProcess.emit (node:events:520:28)
    at ChildProcess.cp.emit (F:\Code\cinema-mobile-app\node_modules\@expo\spawn-async\node_modules\cross-spawn\lib\enoent.js:34:29)
    at maybeClose (node:internal/child_process:1092:16)
    at Process.ChildProcess._handle.onexit (node:internal/child_process:302:5)
    ...
    at spawnAsync (F:\Code\cinema-mobile-app\node_modules\@expo\spawn-async\build\spawnAsync.js:17:21)
    at NpmPackageManager._runAsync (F:\Code\cinema-mobile-app\node_modules\@expo\package-manager\build\NodePackageManagers.js:133:51)
    at NpmPackageManager.addWithParametersAsync (F:\Code\cinema-mobile-app\node_modules\@expo\package-manager\build\NodePackageManagers.js:75:24)    
    at installPackagesAsync (F:\Code\cinema-mobile-app\node_modules\@expo\cli\build\src\install\installAsync.js:82:26)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

It seems the expo-cached-image package depends on React 18.2.0 although the latest Expo SDK is providing React 18.0.0 only

When npm installing, facing wrong react version in peerDependency

I'm trying to install the package but am facing a peerDependency issue with the React version.

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: xxx
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   react@"18.0.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^18.1.0" from [email protected]
npm ERR! node_modules/expo-cached-image
npm ERR!   expo-cached-image@"^47.1.0" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

I am using SDK 46 which uses React v18.0.0 whereas the project uses React v18.1.0

Not compatible with Expo v49

expo-modules-autolinking@"1.2.0" from [email protected]
  node_modules/expo-cached-image/node_modules/expo
    expo@"^48.0.0" from [email protected]
    node_modules/expo-cached-image
      expo-cached-image@"^48.1.0" from the root project

Failure of expo-doctor traceback determined that this package only support v48

Expected package expo-modules-autolinking@~1.5.0
Found invalid:
  [email protected]
  (for more info, run: npm why expo-modules-autolinking)
Expected package @expo/config-plugins@~7.2.2

doesn't work on expo SDK 45

When the remote url is not yet in the cache, I just get an error that the image could not be found in the cache.

I would expect that <CachedImage/> will automatically fetch the remote url if the cache is found empty.

Instead an empty <CachedImage/> is displayed.

Please let me know if I'm missing something.

Still relevant

Is it still relevant now that FastImage is compatible with EAS build and managed ?

(even though fast image precache is not working well)

I have to reload the app to display the new images.

Good afternoon, I had found this library and I installed it in my expo project and it worked well, but I have an issue, I use the function 'await CacheManager.downloadAsync({uri: ${item.url}, key: ${item.id}}', to preload the image, but when I edit the image and I go to the screen to see the picture the data is reload but the image don't changes I have to reload the complete project to see the image, is there any way to prereload the new image when user reload the data in the screen?

I hope I explained well the issue, sorry for the mistakes I speak Spanish.

Peer Dependency Out of Date for Expo 47

Expo 47 out now using a new RN version, peer dependency needs to be updated

npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: xxx
npm ERR! Found: [email protected]
npm ERR! node_modules/react-native
npm ERR!   react-native@"0.70.5" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react-native@"^0.69.3" from [email protected]
npm ERR! node_modules/expo-cached-image
npm ERR!   expo-cached-image@"46.0.1" from the root project

Images are not shwing on IOS in offline mode.

Hello,
Thanks for the amazing package. This is a time saver. I am having a little issue. I am preloading the image using
await CacheManager.downloadAsync({uri: ${item.url}, key: ${item.id}})

and I am using it to show images. On Android it works in offline mode as well but on iOS event images are there it only shows the placeholder. when I put the device online it starts showing the Images.

Is there anything that I am missing?

Resetting Cache on URI Change

I am not sure if this is a bug or working as intended, but when I use the cacheKey that cache seems to be persisting and ignoring if the URI associated with the cache changes. Is there a way to force the cache reset?

For example, if I update a URI of a cached image and the cacheKey remains the same. I would expect the cache to update to the new image.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.