diff --git a/src/CacheManager.js b/src/CacheManager.js index 5c606b8..217a4d1 100644 --- a/src/CacheManager.js +++ b/src/CacheManager.js @@ -8,19 +8,21 @@ const BASE_DIR = `${FileSystem.cacheDirectory}expo-image-cache/`; export class CacheEntry { uri: string + headers: {[string]: string} | void; path: string; - constructor(uri: string) { + constructor(uri: string, headers?: {[string]: string}) { this.uri = uri; + this.headers = headers; } async getPath(): Promise { - const {uri} = this; + const {uri, headers} = this; const {path, exists, tmpPath} = await getCacheEntry(uri); if (exists) { return path; } - await FileSystem.downloadAsync(uri, tmpPath); + await FileSystem.createDownloadResumable(uri, tmpPath, {headers}).downloadAsync(); await FileSystem.moveAsync({ from: tmpPath, to: path }); return path; } @@ -30,9 +32,9 @@ export default class CacheManager { static entries: { [uri: string]: CacheEntry } = {}; - static get(uri: string): CacheEntry { + static get(uri: string, headers?: {[string]: string}): CacheEntry { if (!CacheManager.entries[uri]) { - CacheManager.entries[uri] = new CacheEntry(uri); + CacheManager.entries[uri] = new CacheEntry(uri, headers); } return CacheManager.entries[uri]; } diff --git a/src/Image.js b/src/Image.js index 6b69abc..dac64a8 100644 --- a/src/Image.js +++ b/src/Image.js @@ -12,13 +12,13 @@ type ImageProps = { style?: ImageStyle, defaultSource?: ImageSourcePropType, preview?: ImageSourcePropType, - uri: string, + source: ImageSourcePropType, transitionDuration?: number, tint?: "dark" | "light" }; type ImageState = { - uri: ?string, + source: ?ImageSourcePropType, intensity: Animated.Value }; @@ -32,29 +32,35 @@ export default class Image extends React.Component { }; state = { - uri: undefined, + source: undefined, intensity: new Animated.Value(100) }; - async load({uri}: ImageProps): Promise { + async load(source: ImageSourcePropType): Promise { + const {uri, headers} = source; if (uri) { - const path = await CacheManager.get(uri).getPath(); + const path = await CacheManager.get(uri, headers).getPath(); if (this.mounted) { - this.setState({ uri: path }); + this.setState({ + source: { + ...source, + uri: path + } + }); } } } componentDidMount() { - this.load(this.props); + this.load(this.props.source); } componentDidUpdate(prevProps: ImageProps, prevState: ImageState) { const {preview, transitionDuration} = this.props; - const {uri, intensity} = this.state; - if (this.props.uri !== prevProps.uri) { - this.load(this.props); - } else if (uri && preview && prevState.uri === undefined) { + const {source, intensity} = this.state; + if (this.props.source !== prevProps.source) { + this.load(this.props.source); + } else if (source && preview && prevState.source === undefined) { Animated.timing(intensity, { duration: transitionDuration, toValue: 0, @@ -69,10 +75,12 @@ export default class Image extends React.Component { render(): React.Node { const {preview, style, defaultSource, tint, ...otherProps} = this.props; - const {uri, intensity} = this.state; + // Prevent overwriting source from state + delete otherProps.source; + const {source, intensity} = this.state; const hasDefaultSource = !!defaultSource; const hasPreview = !!preview; - const isImageReady = !!uri; + const isImageReady = !!source; const opacity = intensity.interpolate({ inputRange: [0, 100], outputRange: [0, 0.5] @@ -109,7 +117,7 @@ export default class Image extends React.Component { { isImageReady && (