1import { Asset } from 'expo-asset'; 2import * as FileSystem from 'expo-file-system'; 3import * as Progress from 'expo-progress'; 4import React from 'react'; 5import { Alert, AsyncStorage, ScrollView, StyleSheet } from 'react-native'; 6 7import ListButton from '../components/ListButton'; 8 9interface State { 10 downloadProgress: number; 11} 12 13export default class FileSystemScreen extends React.Component<object, State> { 14 static navigationOptions = { 15 title: 'FileSystem', 16 }; 17 18 readonly state: State = { 19 downloadProgress: 0, 20 }; 21 22 download?: FileSystem.DownloadResumable; 23 24 _download = async () => { 25 const url = 'http://ipv4.download.thinkbroadband.com/256KB.zip'; 26 await FileSystem.downloadAsync(url, FileSystem.documentDirectory + '256KB.zip'); 27 alert('Download complete!'); 28 }; 29 30 _startDownloading = async () => { 31 const url = 'http://ipv4.download.thinkbroadband.com/5MB.zip'; 32 const fileUri = FileSystem.documentDirectory + '5MB.zip'; 33 const callback: FileSystem.DownloadProgressCallback = downloadProgress => { 34 const progress = 35 downloadProgress.totalBytesWritten / downloadProgress.totalBytesExpectedToWrite; 36 this.setState({ 37 downloadProgress: progress, 38 }); 39 }; 40 const options = { md5: true }; 41 this.download = FileSystem.createDownloadResumable(url, fileUri, options, callback); 42 43 try { 44 const result = await this.download.downloadAsync(); 45 if (result) { 46 this._downloadComplete(); 47 } 48 } catch (e) { 49 console.log(e); 50 } 51 }; 52 53 _pause = async () => { 54 if (!this.download) { 55 alert('Initiate a download first!'); 56 return; 57 } 58 try { 59 const downloadSnapshot = await this.download.pauseAsync(); 60 await AsyncStorage.setItem('pausedDownload', JSON.stringify(downloadSnapshot)); 61 alert('Download paused...'); 62 } catch (e) { 63 console.log(e); 64 } 65 }; 66 67 _resume = async () => { 68 try { 69 if (this.download) { 70 const result = await this.download.resumeAsync(); 71 if (result) { 72 this._downloadComplete(); 73 } 74 } else { 75 this._fetchDownload(); 76 } 77 } catch (e) { 78 console.log(e); 79 } 80 }; 81 82 _downloadComplete = () => { 83 if (this.state.downloadProgress !== 1) { 84 this.setState({ 85 downloadProgress: 1, 86 }); 87 } 88 alert('Download complete!'); 89 }; 90 91 _fetchDownload = async () => { 92 try { 93 const downloadJson = await AsyncStorage.getItem('pausedDownload'); 94 if (downloadJson !== null) { 95 const downloadFromStore = JSON.parse(downloadJson); 96 const callback: FileSystem.DownloadProgressCallback = downloadProgress => { 97 const progress = 98 downloadProgress.totalBytesWritten / downloadProgress.totalBytesExpectedToWrite; 99 this.setState({ 100 downloadProgress: progress, 101 }); 102 }; 103 this.download = new FileSystem.DownloadResumable( 104 downloadFromStore.url, 105 downloadFromStore.fileUri, 106 downloadFromStore.options, 107 callback, 108 downloadFromStore.resumeData 109 ); 110 await this.download.resumeAsync(); 111 if (this.state.downloadProgress === 1) { 112 alert('Download complete!'); 113 } 114 } else { 115 alert('Initiate a download first!'); 116 return; 117 } 118 } catch (e) { 119 console.log(e); 120 } 121 }; 122 123 _getInfo = async () => { 124 if (!this.download) { 125 alert('Initiate a download first!'); 126 return; 127 } 128 try { 129 const info = await FileSystem.getInfoAsync(this.download._fileUri); 130 Alert.alert('File Info:', JSON.stringify(info), [{ text: 'OK', onPress: () => {} }]); 131 } catch (e) { 132 console.log(e); 133 } 134 }; 135 136 _readAsset = async () => { 137 const asset = Asset.fromModule(require('../../assets/index.html')); 138 await asset.downloadAsync(); 139 try { 140 const result = await FileSystem.readAsStringAsync(asset.localUri!); 141 Alert.alert('Result', result); 142 } catch (e) { 143 Alert.alert('Error', e.message); 144 } 145 }; 146 147 _getInfoAsset = async () => { 148 const asset = Asset.fromModule(require('../../assets/index.html')); 149 await asset.downloadAsync(); 150 try { 151 const result = await FileSystem.getInfoAsync(asset.localUri!); 152 Alert.alert('Result', JSON.stringify(result, null, 2)); 153 } catch (e) { 154 Alert.alert('Error', e.message); 155 } 156 }; 157 158 _copyAndReadAsset = async () => { 159 const asset = Asset.fromModule(require('../../assets/index.html')); 160 await asset.downloadAsync(); 161 const tmpFile = FileSystem.cacheDirectory + 'test.html'; 162 try { 163 await FileSystem.copyAsync({ from: asset.localUri!, to: tmpFile }); 164 const result = await FileSystem.readAsStringAsync(tmpFile); 165 Alert.alert('Result', result); 166 } catch (e) { 167 Alert.alert('Error', e.message); 168 } 169 }; 170 171 _alertFreeSpace = async () => { 172 const freeBytes = await FileSystem.getFreeDiskStorageAsync(); 173 alert(`${Math.round(freeBytes / 1024 / 1024)} MB available`); 174 }; 175 176 render() { 177 return ( 178 <ScrollView style={{ padding: 10 }}> 179 <ListButton onPress={this._download} title="Download file (512KB)" /> 180 <ListButton onPress={this._startDownloading} title="Start Downloading file (5MB)" /> 181 <ListButton onPress={this._pause} title="Pause Download" /> 182 <ListButton onPress={this._resume} title="Resume Download" /> 183 <ListButton onPress={this._getInfo} title="Get Info" /> 184 <Progress.Bar style={styles.progress} isAnimated progress={this.state.downloadProgress} /> 185 <ListButton onPress={this._readAsset} title="Read Asset" /> 186 <ListButton onPress={this._getInfoAsset} title="Get Info Asset" /> 187 <ListButton onPress={this._copyAndReadAsset} title="Copy and Read Asset" /> 188 <ListButton onPress={this._alertFreeSpace} title="Alert free space" /> 189 </ScrollView> 190 ); 191 } 192} 193 194const styles = StyleSheet.create({ 195 progress: { 196 marginHorizontal: 10, 197 marginVertical: 32, 198 }, 199}); 200