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 const result = await this.download.downloadAsync(); 51 if (result) { 52 this._downloadComplete(); 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 const result = await this.download.resumeAsync(); 77 if (result) { 78 this._downloadComplete(); 79 } 80 } else { 81 this._fetchDownload(); 82 } 83 } catch (e) { 84 console.log(e); 85 } 86 }; 87 88 _downloadComplete = () => { 89 if (this.state.downloadProgress !== 1) { 90 this.setState({ 91 downloadProgress: 1, 92 }); 93 } 94 alert('Download complete!'); 95 }; 96 97 _fetchDownload = async () => { 98 try { 99 const downloadJson = await AsyncStorage.getItem('pausedDownload'); 100 if (downloadJson !== null) { 101 const downloadFromStore = JSON.parse(downloadJson); 102 const callback: FileSystem.DownloadProgressCallback = downloadProgress => { 103 const progress = 104 downloadProgress.totalBytesWritten / downloadProgress.totalBytesExpectedToWrite; 105 this.setState({ 106 downloadProgress: progress, 107 }); 108 }; 109 this.download = new FileSystem.DownloadResumable( 110 downloadFromStore.url, 111 downloadFromStore.fileUri, 112 downloadFromStore.options, 113 callback, 114 downloadFromStore.resumeData 115 ); 116 await this.download.resumeAsync(); 117 if (this.state.downloadProgress === 1) { 118 alert('Download complete!'); 119 } 120 } else { 121 alert('Initiate a download first!'); 122 return; 123 } 124 } catch (e) { 125 console.log(e); 126 } 127 }; 128 129 _getInfo = async () => { 130 if (!this.download) { 131 alert('Initiate a download first!'); 132 return; 133 } 134 try { 135 const info = await FileSystem.getInfoAsync(this.download._fileUri); 136 Alert.alert('File Info:', JSON.stringify(info), [{ text: 'OK', onPress: () => {} }]); 137 } catch (e) { 138 console.log(e); 139 } 140 }; 141 142 _readAsset = async () => { 143 const asset = Asset.fromModule(require('../../assets/index.html')); 144 await asset.downloadAsync(); 145 try { 146 const result = await FileSystem.readAsStringAsync(asset.localUri!); 147 Alert.alert('Result', result); 148 } catch (e) { 149 Alert.alert('Error', e.message); 150 } 151 }; 152 153 _getInfoAsset = async () => { 154 const asset = Asset.fromModule(require('../../assets/index.html')); 155 await asset.downloadAsync(); 156 try { 157 const result = await FileSystem.getInfoAsync(asset.localUri!); 158 Alert.alert('Result', JSON.stringify(result, null, 2)); 159 } catch (e) { 160 Alert.alert('Error', e.message); 161 } 162 }; 163 164 _copyAndReadAsset = async () => { 165 const asset = Asset.fromModule(require('../../assets/index.html')); 166 await asset.downloadAsync(); 167 const tmpFile = FileSystem.cacheDirectory + 'test.html'; 168 try { 169 await FileSystem.copyAsync({ from: asset.localUri!, to: tmpFile }); 170 const result = await FileSystem.readAsStringAsync(tmpFile); 171 Alert.alert('Result', result); 172 } catch (e) { 173 Alert.alert('Error', e.message); 174 } 175 }; 176 177 _alertFreeSpace = async () => { 178 const freeBytes = await FileSystem.getFreeDiskStorageAsync(); 179 alert(`${Math.round(freeBytes / 1024 / 1024)} MB available`); 180 }; 181 182 render() { 183 let progress = null; 184 if (Platform.OS === 'ios') { 185 progress = <ProgressViewIOS style={styles.progress} progress={this.state.downloadProgress} />; 186 } else { 187 progress = ( 188 <ProgressBarAndroid 189 style={styles.progress} 190 styleAttr="Horizontal" 191 indeterminate={false} 192 progress={this.state.downloadProgress} 193 /> 194 ); 195 } 196 return ( 197 <ScrollView style={{ padding: 10 }}> 198 <ListButton onPress={this._download} title="Download file (512KB)" /> 199 <ListButton onPress={this._startDownloading} title="Start Downloading file (5MB)" /> 200 <ListButton onPress={this._pause} title="Pause Download" /> 201 <ListButton onPress={this._resume} title="Resume Download" /> 202 <ListButton onPress={this._getInfo} title="Get Info" /> 203 {progress} 204 <ListButton onPress={this._readAsset} title="Read Asset" /> 205 <ListButton onPress={this._getInfoAsset} title="Get Info Asset" /> 206 <ListButton onPress={this._copyAndReadAsset} title="Copy and Read Asset" /> 207 <ListButton onPress={this._alertFreeSpace} title="Alert free space" /> 208 </ScrollView> 209 ); 210 } 211} 212 213const styles = StyleSheet.create({ 214 progress: { 215 marginHorizontal: 10, 216 marginVertical: 32, 217 }, 218}); 219