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