smart caching

This commit is contained in:
Alexander NeonXP Kiryukhin 2019-06-09 20:54:31 +03:00
parent 2a5b10f500
commit 3d08794c93
2 changed files with 61 additions and 6 deletions

View file

@ -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
View 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"} />)
}
}