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 _alertFreeSpace = async () => { 169 const freeBytes = await FileSystem.getFreeDiskStorageAsync(); 170 alert(`${Math.round(freeBytes / 1024 / 1024)} MB available`); 171 } 172 173 render() { 174 let progress = null; 175 if (Platform.OS === 'ios') { 176 progress = <ProgressViewIOS style={styles.progress} progress={this.state.downloadProgress} />; 177 } else { 178 progress = ( 179 <ProgressBarAndroid 180 style={styles.progress} 181 styleAttr="Horizontal" 182 indeterminate={false} 183 progress={this.state.downloadProgress} 184 /> 185 ); 186 } 187 return ( 188 <ScrollView style={{ padding: 10 }}> 189 <ListButton onPress={this._download} title="Download file (512KB)" /> 190 <ListButton onPress={this._startDownloading} title="Start Downloading file (5MB)" /> 191 <ListButton onPress={this._pause} title="Pause Download" /> 192 <ListButton onPress={this._resume} title="Resume Download" /> 193 <ListButton onPress={this._getInfo} title="Get Info" /> 194 {progress} 195 <ListButton onPress={this._readAsset} title="Read Asset" /> 196 <ListButton onPress={this._getInfoAsset} title="Get Info Asset" /> 197 <ListButton onPress={this._copyAndReadAsset} title="Copy and Read Asset" /> 198 <ListButton onPress={this._alertFreeSpace} title="Alert free space" /> 199 </ScrollView> 200 ); 201 } 202} 203 204const styles = StyleSheet.create({ 205 progress: { 206 marginHorizontal: 10, 207 marginVertical: 32, 208 }, 209}); 210