smart caching
This commit is contained in:
parent
2a5b10f500
commit
3d08794c93
2 changed files with 61 additions and 6 deletions
29
src/index.js
29
src/index.js
|
@ -1,7 +1,8 @@
|
|||
import React, { PureComponent } from 'react'
|
||||
import { Image, View, PixelRatio, PanResponder } from 'react-native'
|
||||
import Svg, { Polyline, Polygon } from 'react-native-svg'
|
||||
|
||||
import * as FileSystem from 'expo-file-system';
|
||||
import Tile from './tile'
|
||||
import debounce from './debounce'
|
||||
|
||||
const DEBOUNCE_DELAY = 60
|
||||
|
@ -86,10 +87,27 @@ export default class Map extends PureComponent {
|
|||
deltaY: 0,
|
||||
deltaScale: 0,
|
||||
}
|
||||
FileSystem.makeDirectoryAsync(FileSystem.cacheDirectory + 'tiles').catch(NOOP)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.syncToProps()
|
||||
this.gc = setInterval(() => {
|
||||
const time = +(new Date()) / 1000
|
||||
FileSystem.readDirectoryAsync(FileSystem.cacheDirectory + 'tiles').then(list => {
|
||||
list.map(item => {
|
||||
FileSystem.getInfoAsync(FileSystem.cacheDirectory + 'tiles/' + item).then(finfo => {
|
||||
if (time - finfo.modificationTime > 1000 * 60) {
|
||||
FileSystem.deleteAsync(finfo.uri)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.gc)
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
|
@ -465,7 +483,7 @@ export default class Map extends PureComponent {
|
|||
}
|
||||
|
||||
this.setState({
|
||||
pixelDelta: null,
|
||||
pixelDelta: [0, 0],
|
||||
zoomDelta: 0
|
||||
}, NOOP)
|
||||
|
||||
|
@ -538,7 +556,6 @@ export default class Map extends PureComponent {
|
|||
const { oldTiles } = this.state
|
||||
const dprs = [1, PixelRatio.get()]
|
||||
const mapUrl = this.props.provider || providers['wikimedia']
|
||||
|
||||
const {
|
||||
tileMinX,
|
||||
tileMaxX,
|
||||
|
@ -613,10 +630,10 @@ export default class Map extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
return tiles.map(tile => (<Image
|
||||
return tiles.map(tile => (<Tile
|
||||
key={tile.key}
|
||||
source={{ uri: tile.url, cache: 'force-cache' }}
|
||||
resizeMethod={"scale"}
|
||||
tileKey={tile.key}
|
||||
source={tile.url}
|
||||
style={{
|
||||
height: tile.height,
|
||||
width: tile.width,
|
||||
|
|
38
src/tile.js
Normal file
38
src/tile.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
import React, { Component } from "react";
|
||||
import { Image, View, ActivityIndicator } from "react-native";
|
||||
import * as FileSystem from 'expo-file-system';
|
||||
|
||||
export default class Tile extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
loaded: false,
|
||||
uri: '',
|
||||
}
|
||||
}
|
||||
componentDidMount() {
|
||||
this._mounted = true;
|
||||
this.load()
|
||||
}
|
||||
load = async () => {
|
||||
const fileUri = FileSystem.cacheDirectory + 'tiles/' + this.props.tileKey + '.png'
|
||||
let finfo = await FileSystem.getInfoAsync(fileUri)
|
||||
if (!finfo.exists) {
|
||||
finfo = await FileSystem.downloadAsync(this.props.source, fileUri)
|
||||
}
|
||||
if (this._mounted) {
|
||||
this.setState({ loaded: true, uri: finfo.uri })
|
||||
}
|
||||
this.props.onLoad && this.props.onLoad()
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._mounted = false;
|
||||
}
|
||||
render() {
|
||||
if (!this.state.loaded) {
|
||||
return null
|
||||
}
|
||||
return (<Image style={this.props.style} source={{ uri: this.state.uri }} resizeMethod={"scale"} />)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue