App.js 4.0 KB

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