App.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. // eslint-disable-next-line global-require
  108. source={require('./assets/uppy-logo.png')}
  109. />
  110. </View>
  111. <SelectFiles showFilePicker={showFilePicker} />
  112. {state.info ? (
  113. <Text
  114. style={{
  115. marginBottom: 10,
  116. marginTop: 10,
  117. color: '#b8006b',
  118. }}
  119. >
  120. {state.info.message}
  121. </Text>
  122. ) : null}
  123. <ProgressBar progress={state.totalProgress} />
  124. <PauseResumeButton
  125. isPaused={state.isPaused}
  126. onPress={togglePauseResume}
  127. uploadStarted={state.uploadStarted}
  128. uploadComplete={state.uploadComplete}
  129. />
  130. {uppy && (
  131. <FilePicker
  132. uppy={uppy}
  133. show={state.isFilePickerVisible}
  134. onRequestClose={hideFilePicker}
  135. companionUrl="http://localhost:3020"
  136. />
  137. )}
  138. {uppy && <FileList uppy={uppy} />}
  139. {state.status && <Text>Status: {state.status}</Text>}
  140. <Text>{state.progress} of {state.total}</Text>
  141. </View>
  142. )
  143. }
  144. const styles = StyleSheet.create({
  145. root: {
  146. paddingTop: 100,
  147. paddingBottom: 20,
  148. paddingLeft: 50,
  149. paddingRight: 50,
  150. flex: 1,
  151. },
  152. title: {
  153. fontSize: 25,
  154. marginBottom: 20,
  155. textAlign: 'center',
  156. },
  157. logo: { width: 80, height: 78, marginBottom: 50 },
  158. })