App.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // import * as Expo from 'expo'
  2. import React from 'react'
  3. import {
  4. Text,
  5. View,
  6. AsyncStorage,
  7. Image
  8. // Linking
  9. } from 'react-native'
  10. import Uppy from '@uppy/core'
  11. import Tus from '@uppy/tus'
  12. import UppyFilePicker from './react-native/file-picker'
  13. import FileList from './FileList'
  14. import PauseResumeButton from './PauseResumeButton'
  15. import ProgressBar from './ProgressBar'
  16. import SelectFiles from './SelectFilesButton'
  17. // import uppyLogo from './assets/uppy-logo.png'
  18. function hashCode (str) {
  19. // from https://stackoverflow.com/a/8831937/151666
  20. var hash = 0
  21. if (str.length === 0) {
  22. return hash
  23. }
  24. for (var i = 0; i < str.length; i++) {
  25. var char = str.charCodeAt(i)
  26. hash = ((hash << 5) - hash) + char
  27. hash = hash & hash // Convert to 32bit integer
  28. }
  29. return hash
  30. }
  31. function customFingerprint (file, options) {
  32. let exifHash = 'noexif'
  33. if (file.exif) {
  34. exifHash = hashCode(JSON.stringify(file.exif))
  35. }
  36. // console.log(exifHash)
  37. const fingerprint = ['tus', file.name || 'noname', file.size || 'nosize', exifHash].join('/')
  38. console.log(fingerprint)
  39. return fingerprint
  40. }
  41. export default class App extends React.Component {
  42. constructor () {
  43. super()
  44. this.state = {
  45. progress: 0,
  46. total: 0,
  47. file: null,
  48. uploadURL: null,
  49. isFilePickerVisible: false,
  50. isPaused: false,
  51. uploadStarted: false,
  52. uploadComplete: false,
  53. info: null
  54. }
  55. this.isReactNative = (typeof navigator !== 'undefined' &&
  56. typeof navigator.product === 'string' &&
  57. navigator.product.toLowerCase() === 'reactnative')
  58. this.showFilePicker = this.showFilePicker.bind(this)
  59. this.hideFilePicker = this.hideFilePicker.bind(this)
  60. this.togglePauseResume = this.togglePauseResume.bind(this)
  61. console.log('Is this React Native?', this.isReactNative)
  62. this.uppy = Uppy({ autoProceed: true, debug: true })
  63. this.uppy.use(Tus, {
  64. endpoint: 'https://master.tus.io/files/',
  65. urlStorage: AsyncStorage,
  66. fingerprint: customFingerprint
  67. })
  68. this.uppy.on('upload-progress', (file, progress) => {
  69. this.setState({
  70. progress: progress.bytesUploaded,
  71. total: progress.bytesTotal,
  72. uploadStarted: true
  73. })
  74. })
  75. this.uppy.on('upload-success', (file, response) => {
  76. console.log(file.name, response)
  77. })
  78. this.uppy.on('complete', (result) => {
  79. this.setState({
  80. status: 'Upload complete ✅',
  81. uploadURL: result.successful[0].uploadURL,
  82. uploadComplete: true,
  83. uploadStarted: false
  84. })
  85. console.log('Upload complete:', result)
  86. })
  87. this.uppy.on('info-visible', () => {
  88. const info = this.uppy.getState().info
  89. this.setState({
  90. info: info
  91. })
  92. console.log('uppy-info:', info)
  93. })
  94. this.uppy.on('info-hidden', () => {
  95. this.setState({
  96. info: null
  97. })
  98. })
  99. }
  100. showFilePicker () {
  101. this.setState({
  102. isFilePickerVisible: true,
  103. uploadStarted: false,
  104. uploadComplete: false
  105. })
  106. }
  107. hideFilePicker () {
  108. this.setState({
  109. isFilePickerVisible: false
  110. })
  111. }
  112. togglePauseResume () {
  113. if (this.state.isPaused) {
  114. this.uppy.resumeAll()
  115. this.setState({
  116. isPaused: false
  117. })
  118. } else {
  119. this.uppy.pauseAll()
  120. this.setState({
  121. isPaused: true
  122. })
  123. }
  124. }
  125. render () {
  126. return (
  127. <View style={{
  128. paddingTop: 100,
  129. paddingLeft: 50,
  130. paddingRight: 50,
  131. flex: 1
  132. }}>
  133. <Text style={{
  134. fontSize: 25,
  135. marginBottom: 20,
  136. textAlign: 'center'
  137. }}>Uppy in React Native</Text>
  138. <View style={{alignItems: 'center'}}>
  139. <Image
  140. style={{width: 80, height: 78, marginBottom: 50}}
  141. source={require('./assets/uppy-logo.png')}
  142. />
  143. </View>
  144. <SelectFiles showFilePicker={this.showFilePicker} />
  145. {this.state.info
  146. ? <Text style={{
  147. marginBottom: 10,
  148. marginTop: 10,
  149. color: '#b8006b'}}>{this.state.info.message}</Text>
  150. : null
  151. }
  152. <ProgressBar
  153. progress={this.state.progress}
  154. total={this.state.total}
  155. />
  156. <PauseResumeButton
  157. isPaused={this.state.isPaused}
  158. onPress={this.togglePauseResume}
  159. uploadStarted={this.state.uploadStarted}
  160. uploadComplete={this.state.uploadComplete} />
  161. <UppyFilePicker
  162. show={this.state.isFilePickerVisible}
  163. uppy={this.uppy}
  164. onRequestClose={this.hideFilePicker}
  165. serverUrl="http://localhost:3020" />
  166. <FileList uppy={this.uppy} />
  167. {/* <Text>{this.state.status ? 'Status: ' + this.state.status : null}</Text>
  168. <Text>{this.state.progress} of {this.state.total}</Text> */}
  169. </View>
  170. )
  171. }
  172. }