From d0ee16e634405e008b411ba50ca026c0bc9523e5 Mon Sep 17 00:00:00 2001 From: Marius Reimer Date: Sun, 22 Mar 2020 15:53:36 +0100 Subject: [PATCH] feat: adding e2e tests, build automation and linting (#174) * Added lint-staged with pre-commit hooks to have more consistent code styling. * Integrated the test app into this repository * Added simple end to end tests for the test app * Using Github Actions for CI/CD * Using semantic-release for fully automated version management and package publishing --- .eslintignore | 2 + .eslintrc.js | 4 + .github/PULL_REQUEST_TEMPLATE.md | 37 + .github/workflows/android.yml | 62 + .github/workflows/deploy-release.yml | 28 + .github/workflows/iOS.yml | 40 + .github/workflows/node.yml | 24 + .gitignore | 1 + .prettierrc.js | 6 + CHANGELOG.md | 3 + LICENSE.txt => LICENSE | 0 README.md | 12 +- example/RNBackgroundExample/.buckconfig | 6 + example/RNBackgroundExample/.eslintrc.js | 4 + example/RNBackgroundExample/.flowconfig | 75 + example/RNBackgroundExample/.gitattributes | 1 + example/RNBackgroundExample/.gitignore | 61 + example/RNBackgroundExample/.prettierrc.js | 6 + example/RNBackgroundExample/.watchmanconfig | 1 + example/RNBackgroundExample/App.js | 324 + example/RNBackgroundExample/README.md | 50 + .../RNBackgroundExample/__tests__/App-test.js | 14 + example/RNBackgroundExample/android/app/BUCK | 55 + .../android/app/build.gradle | 210 + .../android/app/build_defs.bzl | 19 + .../android/app/debug.keystore | Bin 0 -> 2257 bytes .../android/app/proguard-rules.pro | 10 + .../com/rnbackgroundexample/DetoxTest.java | 24 + .../android/app/src/debug/AndroidManifest.xml | 8 + .../android/app/src/main/AndroidManifest.xml | 32 + .../com/rnbackgroundexample/MainActivity.java | 15 + .../rnbackgroundexample/MainApplication.java | 74 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3056 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5024 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2096 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2858 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4569 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7098 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6464 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10676 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9250 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15523 bytes .../app/src/main/res/values/strings.xml | 3 + .../app/src/main/res/values/styles.xml | 9 + .../RNBackgroundExample/android/build.gradle | 42 + .../android/gradle.properties | 21 + .../android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 55616 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + example/RNBackgroundExample/android/gradlew | 188 + .../RNBackgroundExample/android/gradlew.bat | 100 + .../android/settings.gradle | 3 + example/RNBackgroundExample/app.json | 4 + example/RNBackgroundExample/babel.config.js | 3 + example/RNBackgroundExample/e2e/config.json | 6 + .../RNBackgroundExample/e2e/firstTest.spec.js | 56 + example/RNBackgroundExample/e2e/init.js | 26 + example/RNBackgroundExample/e2e/server.js | 69 + .../RNBackgroundExample/e2e/start-server.js | 2 + example/RNBackgroundExample/index.js | 9 + example/RNBackgroundExample/ios/Podfile | 53 + example/RNBackgroundExample/ios/Podfile.lock | 356 + .../ios/RNBackgroundExample-tvOS/Info.plist | 53 + .../RNBackgroundExample-tvOSTests/Info.plist | 24 + .../project.pbxproj | 923 +++ .../RNBackgroundExample-tvOS.xcscheme | 129 + .../xcschemes/RNBackgroundExample.xcscheme | 129 + .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../ios/RNBackgroundExample/AppDelegate.h | 15 + .../ios/RNBackgroundExample/AppDelegate.m | 42 + .../Base.lproj/LaunchScreen.xib | 42 + .../AppIcon.appiconset/Contents.json | 38 + .../Images.xcassets/Contents.json | 6 + .../ios/RNBackgroundExample/Info.plist | 65 + .../ios/RNBackgroundExample/main.m | 16 + .../ios/RNBackgroundExampleTests/Info.plist | 24 + .../RNBackgroundExampleTests.m | 72 + example/RNBackgroundExample/metro.config.js | 22 + example/RNBackgroundExample/package.json | 69 + .../scripts/deploy-android.sh | 14 + .../RNBackgroundExample/scripts/deploy-ios.sh | 12 + .../scripts/postinstall.sh | 13 + example/RNBackgroundExample/yarn.lock | 7284 +++++++++++++++++ husky.config.js | 10 + lint-staged.config.js | 3 + package.json | 45 +- react-native-background-upload.podspec | 2 +- index.js => src/index.js | 64 +- yarn.lock | 5440 ++++++++++++ 89 files changed, 16701 insertions(+), 36 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/android.yml create mode 100644 .github/workflows/deploy-release.yml create mode 100644 .github/workflows/iOS.yml create mode 100644 .github/workflows/node.yml create mode 100644 .prettierrc.js create mode 100644 CHANGELOG.md rename LICENSE.txt => LICENSE (100%) create mode 100644 example/RNBackgroundExample/.buckconfig create mode 100644 example/RNBackgroundExample/.eslintrc.js create mode 100644 example/RNBackgroundExample/.flowconfig create mode 100644 example/RNBackgroundExample/.gitattributes create mode 100644 example/RNBackgroundExample/.gitignore create mode 100644 example/RNBackgroundExample/.prettierrc.js create mode 100644 example/RNBackgroundExample/.watchmanconfig create mode 100644 example/RNBackgroundExample/App.js create mode 100644 example/RNBackgroundExample/README.md create mode 100644 example/RNBackgroundExample/__tests__/App-test.js create mode 100644 example/RNBackgroundExample/android/app/BUCK create mode 100644 example/RNBackgroundExample/android/app/build.gradle create mode 100644 example/RNBackgroundExample/android/app/build_defs.bzl create mode 100644 example/RNBackgroundExample/android/app/debug.keystore create mode 100644 example/RNBackgroundExample/android/app/proguard-rules.pro create mode 100644 example/RNBackgroundExample/android/app/src/androidTest/java/com/rnbackgroundexample/DetoxTest.java create mode 100644 example/RNBackgroundExample/android/app/src/debug/AndroidManifest.xml create mode 100644 example/RNBackgroundExample/android/app/src/main/AndroidManifest.xml create mode 100644 example/RNBackgroundExample/android/app/src/main/java/com/rnbackgroundexample/MainActivity.java create mode 100644 example/RNBackgroundExample/android/app/src/main/java/com/rnbackgroundexample/MainApplication.java create mode 100644 example/RNBackgroundExample/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 example/RNBackgroundExample/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 example/RNBackgroundExample/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 example/RNBackgroundExample/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 example/RNBackgroundExample/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 example/RNBackgroundExample/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 example/RNBackgroundExample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 example/RNBackgroundExample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 example/RNBackgroundExample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 example/RNBackgroundExample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 example/RNBackgroundExample/android/app/src/main/res/values/strings.xml create mode 100644 example/RNBackgroundExample/android/app/src/main/res/values/styles.xml create mode 100644 example/RNBackgroundExample/android/build.gradle create mode 100644 example/RNBackgroundExample/android/gradle.properties create mode 100644 example/RNBackgroundExample/android/gradle/wrapper/gradle-wrapper.jar create mode 100644 example/RNBackgroundExample/android/gradle/wrapper/gradle-wrapper.properties create mode 100755 example/RNBackgroundExample/android/gradlew create mode 100644 example/RNBackgroundExample/android/gradlew.bat create mode 100644 example/RNBackgroundExample/android/settings.gradle create mode 100644 example/RNBackgroundExample/app.json create mode 100644 example/RNBackgroundExample/babel.config.js create mode 100644 example/RNBackgroundExample/e2e/config.json create mode 100644 example/RNBackgroundExample/e2e/firstTest.spec.js create mode 100644 example/RNBackgroundExample/e2e/init.js create mode 100644 example/RNBackgroundExample/e2e/server.js create mode 100644 example/RNBackgroundExample/e2e/start-server.js create mode 100644 example/RNBackgroundExample/index.js create mode 100644 example/RNBackgroundExample/ios/Podfile create mode 100644 example/RNBackgroundExample/ios/Podfile.lock create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample-tvOS/Info.plist create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample-tvOSTests/Info.plist create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample.xcodeproj/project.pbxproj create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample.xcodeproj/xcshareddata/xcschemes/RNBackgroundExample-tvOS.xcscheme create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample.xcodeproj/xcshareddata/xcschemes/RNBackgroundExample.xcscheme create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample.xcworkspace/contents.xcworkspacedata create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample/AppDelegate.h create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample/AppDelegate.m create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample/Base.lproj/LaunchScreen.xib create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample/Images.xcassets/AppIcon.appiconset/Contents.json create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample/Images.xcassets/Contents.json create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample/Info.plist create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExample/main.m create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExampleTests/Info.plist create mode 100644 example/RNBackgroundExample/ios/RNBackgroundExampleTests/RNBackgroundExampleTests.m create mode 100644 example/RNBackgroundExample/metro.config.js create mode 100644 example/RNBackgroundExample/package.json create mode 100644 example/RNBackgroundExample/scripts/deploy-android.sh create mode 100644 example/RNBackgroundExample/scripts/deploy-ios.sh create mode 100644 example/RNBackgroundExample/scripts/postinstall.sh create mode 100644 example/RNBackgroundExample/yarn.lock create mode 100644 husky.config.js create mode 100644 lint-staged.config.js rename index.js => src/index.js (75%) create mode 100644 yarn.lock diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..168d4a14 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +example/RNBackgroundExample/node_modules +example/RNBackgroundExample/e2e diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..40c6dcd0 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: '@react-native-community', +}; diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..0d0ca920 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,37 @@ + + +# Summary + + + +## Test Plan + + + +### What's required for testing (prerequisites)? + +### What are the steps to reproduce (after prerequisites)? + +## Compatibility + +| OS | Implemented | +| ------- | :---------: | +| iOS | ✅❌ | +| Android | ✅❌ | + +## Checklist + + + +- [ ] I have tested this on a device and a simulator +- [ ] I added the documentation in `README.md` +- [ ] I updated the typed files (TS and Flow) +- [ ] I've added Detox End-to-End Test(s) +- [ ] I've created a snack to demonstrate the changes: LINK HERE diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml new file mode 100644 index 00000000..0b74ad72 --- /dev/null +++ b/.github/workflows/android.yml @@ -0,0 +1,62 @@ +name: Test Android Example App + +on: [push, pull_request] + +jobs: + react-native-android: + runs-on: macos-latest + if: "!contains(github.event.head_commit.message, '[skip ci]')" + + steps: + - name: Checkout project + uses: actions/checkout@v1 + + - name: Specify node version + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: Use specific Java version for sdkmanager to work + uses: joschi/setup-jdk@v1 + with: + java-version: 'openjdk8' + architecture: 'x64' + + - name: Setup Android emulator + run: | + echo y | sudo $ANDROID_HOME/tools/bin/sdkmanager "system-images;android-28;google_apis;x86" > /dev/null + $ANDROID_HOME/tools/bin/avdmanager -s create avd -n emu -k "system-images;android-28;google_apis;x86" -b "x86" -c 1G -d 7 -f + + - name: Install node_modules + working-directory: example/RNBackgroundExample/ + run: + yarn install --frozen-lockfile + + - name: Deploy + working-directory: example/RNBackgroundExample/ + run: + yarn e2e/deploy/android + + - name: Start Emulator + working-directory: example/RNBackgroundExample/ + timeout-minutes: 5 + run: | + export PATH=$PATH:$ANDROID_HOME/platform-tools + $ANDROID_HOME/emulator/emulator @emu -noaudio -no-boot-anim -netdelay none -accel on -no-snapshot & + adb wait-for-device; adb shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done;'; adb shell wm dismiss-keyguard + + - name: Android test + working-directory: example/RNBackgroundExample/ + timeout-minutes: 8 + run: | + mkdir -p ./artifacts + node e2e/start-server.js & + adb reverse tcp:8080 tcp:8080 + yarn e2e/test/android --record-videos failing + + - uses: actions/upload-artifact@master + name: Provide videos of failed E2E tests + if: failure() + with: + name: android-failing-e2e-videos + path: example/RNBackgroundExample/artifacts diff --git a/.github/workflows/deploy-release.yml b/.github/workflows/deploy-release.yml new file mode 100644 index 00000000..755d439e --- /dev/null +++ b/.github/workflows/deploy-release.yml @@ -0,0 +1,28 @@ +name: Deploy & Release + +on: + push: + branches: + - master + +jobs: + deploy-release: + runs-on: macos-latest + if: "!contains(github.event.head_commit.message, '[skip ci]')" + + steps: + - name: Checkout project + uses: actions/checkout@v1 + + - name: Specify node version + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: Release to NPM + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + yarn install --frozen-lockfile + npx semantic-release diff --git a/.github/workflows/iOS.yml b/.github/workflows/iOS.yml new file mode 100644 index 00000000..a7f2c41e --- /dev/null +++ b/.github/workflows/iOS.yml @@ -0,0 +1,40 @@ +name: Test iOS Example App + +on: [push, pull_request] + +jobs: + react-native-ios: + runs-on: macos-latest + if: "!contains(github.event.head_commit.message, '[skip ci]')" + + steps: + - name: Checkout project + uses: actions/checkout@v1 + + - name: Specify node version + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: Setup Detox + run: | + brew tap wix/brew + brew install applesimutils + + - name: Install node_modules + working-directory: example/RNBackgroundExample/ + run: + yarn install --frozen-lockfile + + - name: Deploy + working-directory: example/RNBackgroundExample/ + run: + yarn deploy/release/ios + + - name: iOS test + working-directory: example/RNBackgroundExample/ + timeout-minutes: 8 + run: | + npx detox clean-framework-cache && npx detox build-framework-cache + node e2e/start-server.js & + yarn e2e/test/ios diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml new file mode 100644 index 00000000..a9bb2b37 --- /dev/null +++ b/.github/workflows/node.yml @@ -0,0 +1,24 @@ +name: Node Environment + +on: [push, pull_request] + +jobs: + node-lint-tests: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[skip ci]')" + + steps: + - name: checkout + uses: actions/checkout@v1 + + - name: setup node + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: install node_modules + run: yarn install --frozen-lockfile + + - name: node lint + run: + yarn lint:ci diff --git a/.gitignore b/.gitignore index e74960bf..0bd27078 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ DerivedData *.ipa *.xcuserstate project.xcworkspace +Pods/ # Android/IntelliJ # diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 00000000..355e7d1e --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + bracketSpacing: true, + jsxBracketSameLine: true, + singleQuote: true, + trailingComma: 'all', +}; diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..f6a050d4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +Since Version > 5.3.0 we follow semantic versioning. + +See the [releases](https://github.com/Vydia/react-native-background-upload/releases) page on GitHub for information regarding each release. diff --git a/LICENSE.txt b/LICENSE similarity index 100% rename from LICENSE.txt rename to LICENSE diff --git a/README.md b/README.md index b7b311ba..8e645a81 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,10 @@ # react-native-background-upload [![npm version](https://badge.fury.io/js/react-native-background-upload.svg)](https://badge.fury.io/js/react-native-background-upload) + + +![GitHub Actions status](https://github.com/Vydia/react-native-background-upload/workflows/iOS/badge.svg) + +![GitHub Actions status](https://github.com/Vydia/react-native-background-upload/workflows/android/badge.svg) + The only React Native http post file uploader with android and iOS background support. If you are uploading large files like videos, use this so your users can background your app during a long upload. NOTE: Use major version 4 with RN 47.0 and greater. If you have RN less than 47, use 3.0. To view all available versions: @@ -79,7 +85,7 @@ No further actions required. ## 3. Expo -To use this library with [Expo](https://expo.io) one must first detach (eject) the project and follow [step 2](#2-link-native-code) instructions. Additionally on iOS there is a must to add a Header Search Path to other dependencies which are managed using Pods. To do so one has to add `$(SRCROOT)/../../../ios/Pods/Headers/Public` to Header Search Path in `VydiaRNFileUploader` module using XCode. +To use this library with [Expo](https://expo.io) one must first detach (eject) the project and follow [step 2](#2-link-native-code) instructions. Additionally on iOS there is a must to add a Header Search Path to other dependencies which are managed using Pods. To do so one has to add `$(SRCROOT)/../../../ios/Pods/Headers/Public` to Header Search Path in `VydiaRNFileUploader` module using XCode. # Usage @@ -146,7 +152,7 @@ All top-level methods are available as named exports or methods on the default e ### startUpload(options) -The primary method you will use, this starts the upload process. +The primary method you will use, this starts the upload process. Returns a promise with the string ID of the upload. Will reject if there is a connection problem, the file doesn't exist, or there is some other problem. @@ -292,7 +298,7 @@ Is there an example/sandbox app to test out this package? > Yes, there is a simple react native app that comes with an [express](https://github.com/expressjs/express) server where you can see react-native-background-upload in action and try things out in an isolated local environment. -[ReactNativeBackgroundUploadExample](https://github.com/Vydia/ReactNativeBackgroundUploadExample) +[RNBackgroundExample](https://github.com/Vydia/react-native-background-upload/blob/master/example/RNBackgroundExample) Does it support iOS camera roll assets? diff --git a/example/RNBackgroundExample/.buckconfig b/example/RNBackgroundExample/.buckconfig new file mode 100644 index 00000000..934256cb --- /dev/null +++ b/example/RNBackgroundExample/.buckconfig @@ -0,0 +1,6 @@ + +[android] + target = Google Inc.:Google APIs:23 + +[maven_repositories] + central = https://repo1.maven.org/maven2 diff --git a/example/RNBackgroundExample/.eslintrc.js b/example/RNBackgroundExample/.eslintrc.js new file mode 100644 index 00000000..40c6dcd0 --- /dev/null +++ b/example/RNBackgroundExample/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: '@react-native-community', +}; diff --git a/example/RNBackgroundExample/.flowconfig b/example/RNBackgroundExample/.flowconfig new file mode 100644 index 00000000..4afc766a --- /dev/null +++ b/example/RNBackgroundExample/.flowconfig @@ -0,0 +1,75 @@ +[ignore] +; We fork some components by platform +.*/*[.]android.js + +; Ignore "BUCK" generated dirs +/\.buckd/ + +; Ignore polyfills +node_modules/react-native/Libraries/polyfills/.* + +; These should not be required directly +; require from fbjs/lib instead: require('fbjs/lib/warning') +node_modules/warning/.* + +; Flow doesn't support platforms +.*/Libraries/Utilities/LoadingView.js + +[untyped] +.*/node_modules/@react-native-community/cli/.*/.* + +[include] + +[libs] +node_modules/react-native/Libraries/react-native/react-native-interface.js +node_modules/react-native/flow/ + +[options] +emoji=true + +esproposal.optional_chaining=enable +esproposal.nullish_coalescing=enable + +module.file_ext=.js +module.file_ext=.json +module.file_ext=.ios.js + +munge_underscores=true + +module.name_mapper='^react-native$' -> '/node_modules/react-native/Libraries/react-native/react-native-implementation' +module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' +module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub' + +suppress_type=$FlowIssue +suppress_type=$FlowFixMe +suppress_type=$FlowFixMeProps +suppress_type=$FlowFixMeState + +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) +suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ +suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError + +[lints] +sketchy-null-number=warn +sketchy-null-mixed=warn +sketchy-number=warn +untyped-type-import=warn +nonstrict-import=warn +deprecated-type=warn +unsafe-getters-setters=warn +inexact-spread=warn +unnecessary-invariant=warn +signature-verification-failure=warn +deprecated-utility=error + +[strict] +deprecated-type +nonstrict-import +sketchy-null +unclear-type +unsafe-getters-setters +untyped-import +untyped-type-import + +[version] +^0.105.0 diff --git a/example/RNBackgroundExample/.gitattributes b/example/RNBackgroundExample/.gitattributes new file mode 100644 index 00000000..d42ff183 --- /dev/null +++ b/example/RNBackgroundExample/.gitattributes @@ -0,0 +1 @@ +*.pbxproj -text diff --git a/example/RNBackgroundExample/.gitignore b/example/RNBackgroundExample/.gitignore new file mode 100644 index 00000000..f69d912c --- /dev/null +++ b/example/RNBackgroundExample/.gitignore @@ -0,0 +1,61 @@ +# OSX +# +.DS_Store + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate + +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml + +# node.js +# +node_modules/ +npm-debug.log +yarn-error.log + +# BUCK +buck-out/ +\.buckd/ +*.keystore +!debug.keystore + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/ + +*/fastlane/report.xml +*/fastlane/Preview.html +*/fastlane/screenshots + +# Bundle artifact +*.jsbundle + +artifacts/ + +# CocoaPods +/ios/Pods/ diff --git a/example/RNBackgroundExample/.prettierrc.js b/example/RNBackgroundExample/.prettierrc.js new file mode 100644 index 00000000..5c4de1a4 --- /dev/null +++ b/example/RNBackgroundExample/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + bracketSpacing: false, + jsxBracketSameLine: true, + singleQuote: true, + trailingComma: 'all', +}; diff --git a/example/RNBackgroundExample/.watchmanconfig b/example/RNBackgroundExample/.watchmanconfig new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/example/RNBackgroundExample/.watchmanconfig @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/example/RNBackgroundExample/App.js b/example/RNBackgroundExample/App.js new file mode 100644 index 00000000..0f3ea77d --- /dev/null +++ b/example/RNBackgroundExample/App.js @@ -0,0 +1,324 @@ +/** + * Sample React Native App + * https://github.com/facebook/react-native + * + * @format + * @flow + */ + +import React, {useState} from 'react'; +import { + Alert, + SafeAreaView, + StyleSheet, + ScrollView, + View, + Text, + StatusBar, + Button, + Platform, + TouchableOpacity, +} from 'react-native'; + +import {Header, Colors} from 'react-native/Libraries/NewAppScreen'; + +import Upload from 'react-native-background-upload'; + +import ImagePicker from 'react-native-image-picker'; + +import RNFS from 'react-native-fs'; + +const url10SecDelayPut = 'http://localhost:8080/10secDelay'; +const url5secDelayFail = 'http://localhost:8080/5secDelayFail'; + +const path = RNFS.TemporaryDirectoryPath + '/test.json'; +const prefix = Platform.OS === 'ios' ? 'file://' : ''; + +const commonOptions = { + url: '', + path: prefix + path, + method: 'PUT', + type: 'raw', + // only supported on Android + notification: { + enabled: true, + }, +}; + +RNFS.writeFile(path, ''); + +const App: () => React$Node = () => { + const [delay10Completed, set10SecDelayCompleted] = useState(false); + const [delay5Completed, set5SecDelayCompleted] = useState(false); + + const [isImagePickerShowing, setIsImagePickerShowing] = useState(false); + const [uploadId, setUploadId] = useState(null); + const [progress, setProgress] = useState(null); + + const onPressUpload = options => { + if (isImagePickerShowing) { + return; + } + + setIsImagePickerShowing(true); + + const imagePickerOptions = { + takePhotoButtonTitle: null, + title: 'Upload Media', + chooseFromLibraryButtonTitle: 'Choose From Library', + }; + + ImagePicker.showImagePicker(imagePickerOptions, response => { + let didChooseVideo = true; + + console.log('ImagePicker response: ', response); + const {customButton, didCancel, error, path, uri} = response; + + if (didCancel) { + didChooseVideo = false; + } + + if (error) { + console.warn('ImagePicker error:', response); + didChooseVideo = false; + } + + // TODO: Should this happen higher? + setIsImagePickerShowing(false); + + if (!didChooseVideo) { + return; + } + + let finalPath = Platform.OS === 'android' ? path : uri; + + if (finalPath) { + // Video is stored locally on the device + Upload.getFileInfo(finalPath).then(metadata => { + const uploadOpts = Object.assign( + { + path: finalPath, + method: 'POST', + headers: { + 'content-type': metadata.mimeType, // server requires a content-type header + }, + }, + options, + ); + + Upload.startUpload(uploadOpts) + .then(uploadId => { + console.log( + `Upload started with options: ${JSON.stringify(uploadOpts)}`, + ); + setUploadId(uploadId); + setProgress(0); + Upload.addListener('progress', uploadId, data => { + if (data.progress % 5 === 0) { + setProgress(+data.progress); + } + console.log(`Progress: ${data.progress}%`); + }); + Upload.addListener('error', uploadId, data => { + console.log(`Error: ${data.error}%`); + }); + Upload.addListener('completed', uploadId, data => { + console.log('Completed!'); + }); + }) + .catch(function(err) { + setUploadId(null); + setProgress(null); + console.log('Upload error!', err); + }); + }); + } else { + // Video is stored in google cloud + Alert.alert('Video not found'); + } + }); + }; + + return ( + <> + + + +
+ {global.HermesInternal == null ? null : ( + + Engine: Hermes + + )} + + + { + const options = { + ...commonOptions, + url: url10SecDelayPut, + }; + + Upload.startUpload(options) + .then(uploadId => { + setUploadId(uploadId); + + Upload.addListener( + 'completed', + uploadId, + ({responseCode}) => { + console.warn({responseCode}); + + if (responseCode <= 299) { + set10SecDelayCompleted(true); + } + }, + ); + }) + .catch(err => { + console.warn(err.message); + }); + }}> + 10 Sec Delay Success + + + {delay10Completed && ( + + Finished!!! + + )} + + + { + const options = { + ...commonOptions, + url: url5secDelayFail, + }; + + Upload.startUpload(options) + .then(uploadId => { + setUploadId(uploadId); + + Upload.addListener( + 'completed', + uploadId, + ({responseCode}) => { + if (responseCode === 502) { + set5SecDelayCompleted(true); + } + }, + ); + + Upload.addListener( + 'error', + uploadId, + ({responseCode}) => { + if (responseCode === 502) { + set5SecDelayCompleted(true); + } + }, + ); + }) + .catch(err => { + console.warn(err.message); + }); + }}> + 5 Sec Delay Error + + + {delay5Completed && ( + + Finished!!! + + )} + +