App.js 4.2 KB

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