App.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import React, { useEffect, useState, useCallback } from 'react'
  2. import { Text, View, Image, StyleSheet } from 'react-native'
  3. import AsyncStorage from '@react-native-async-storage/async-storage'
  4. import Uppy from '@uppy/core'
  5. import Tus from '@uppy/tus'
  6. import FilePicker from '@uppy/react-native'
  7. import useUppy from '@uppy/react/lib/useUppy'
  8. import FileList from './FileList'
  9. import PauseResumeButton from './PauseResumeButton'
  10. import ProgressBar from './ProgressBar'
  11. import SelectFiles from './SelectFilesButton'
  12. import getTusFileReader from './tusFileReader'
  13. export default function App () {
  14. const [state, _setState] = useState({
  15. progress: 0,
  16. total: 0,
  17. file: null,
  18. uploadURL: null,
  19. isFilePickerVisible: false,
  20. isPaused: false,
  21. uploadStarted: false,
  22. uploadComplete: false,
  23. info: null,
  24. totalProgress: 0,
  25. })
  26. const setState = useCallback((newState) => _setState((oldState) => ({ ...oldState, ...newState })), [])
  27. const uppy = useUppy(() => {
  28. return new Uppy({ autoProceed: true, debug: true })
  29. .use(Tus, {
  30. endpoint: 'https://tusd.tusdemo.net/files/',
  31. urlStorage: AsyncStorage,
  32. fileReader: getTusFileReader,
  33. chunkSize: 10 * 1024 * 1024, // keep the chunk size small to avoid memory exhaustion
  34. })
  35. })
  36. useEffect(() => {
  37. uppy.on('upload-progress', (file, progress) => {
  38. setState({
  39. progress: progress.bytesUploaded,
  40. total: progress.bytesTotal,
  41. totalProgress: uppy.state.totalProgress,
  42. uploadStarted: true,
  43. })
  44. })
  45. uppy.on('upload-success', () => {
  46. // console.log(file.name, response)
  47. })
  48. uppy.on('complete', (result) => {
  49. setState({
  50. status: result.successful[0] ? 'Upload complete ✅' : 'Upload errored ❌',
  51. uploadURL: result.successful[0] ? result.successful[0].uploadURL : null,
  52. uploadComplete: true,
  53. uploadStarted: false,
  54. })
  55. console.log('Upload complete:', result)
  56. })
  57. uppy.on('info-visible', () => {
  58. const { info } = uppy.getState()
  59. setState({
  60. info,
  61. })
  62. console.log('uppy-info:', info)
  63. })
  64. uppy.on('info-hidden', () => {
  65. setState({
  66. info: null,
  67. })
  68. })
  69. }, [setState, uppy])
  70. const showFilePicker = () => {
  71. setState({
  72. isFilePickerVisible: true,
  73. uploadStarted: false,
  74. uploadComplete: false,
  75. })
  76. }
  77. const hideFilePicker = () => {
  78. setState({
  79. isFilePickerVisible: false,
  80. })
  81. }
  82. const togglePauseResume = () => {
  83. if (state.isPaused) {
  84. uppy.resumeAll()
  85. setState({
  86. isPaused: false,
  87. })
  88. } else {
  89. uppy.pauseAll()
  90. setState({
  91. isPaused: true,
  92. })
  93. }
  94. }
  95. return (
  96. <View
  97. style={styles.root}
  98. >
  99. <Text
  100. style={styles.title}
  101. >
  102. Uppy in React Native
  103. </Text>
  104. <View style={{ alignItems: 'center' }}>
  105. <Image
  106. style={styles.logo}
  107. source={require('./assets/uppy-logo.png')}
  108. />
  109. </View>
  110. <SelectFiles showFilePicker={showFilePicker} />
  111. {state.info ? (
  112. <Text
  113. style={{
  114. marginBottom: 10,
  115. marginTop: 10,
  116. color: '#b8006b',
  117. }}
  118. >
  119. {state.info.message}
  120. </Text>
  121. ) : null}
  122. <ProgressBar progress={state.totalProgress} />
  123. <PauseResumeButton
  124. isPaused={state.isPaused}
  125. onPress={togglePauseResume}
  126. uploadStarted={state.uploadStarted}
  127. uploadComplete={state.uploadComplete}
  128. />
  129. {uppy && (
  130. <FilePicker
  131. uppy={uppy}
  132. show={state.isFilePickerVisible}
  133. onRequestClose={hideFilePicker}
  134. companionUrl="http://localhost:3020"
  135. />
  136. )}
  137. {uppy && <FileList uppy={uppy} />}
  138. {state.status && <Text>Status: {state.status}</Text>}
  139. <Text>{state.progress} of {state.total}</Text>
  140. </View>
  141. )
  142. }
  143. const styles = StyleSheet.create({
  144. root: {
  145. paddingTop: 100,
  146. paddingBottom: 20,
  147. paddingLeft: 50,
  148. paddingRight: 50,
  149. flex: 1,
  150. },
  151. title: {
  152. fontSize: 25,
  153. marginBottom: 20,
  154. textAlign: 'center',
  155. },
  156. logo: { width: 80, height: 78, marginBottom: 50 },
  157. })