├── .gitignore ├── Libraries.txt ├── README.md ├── android ├── .gitignore ├── app │ ├── .gitignore │ ├── build.gradle │ ├── capacitor.build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── getcapacitor │ │ │ └── myapp │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ │ └── ocr_blobs │ │ │ │ ├── deu.traineddata │ │ │ │ ├── eng.traineddata │ │ │ │ └── osd.traineddata │ │ ├── java │ │ │ └── io │ │ │ │ └── scanbot │ │ │ │ └── example │ │ │ │ └── sdk │ │ │ │ └── capacitor │ │ │ │ └── ionic │ │ │ │ └── react │ │ │ │ └── MainActivity.java │ │ └── res │ │ │ ├── drawable-land-hdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-mdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-xhdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-xxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-land-xxxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-hdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-mdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-xhdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-xxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-port-xxxhdpi │ │ │ └── splash.png │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable │ │ │ ├── ic_launcher_background.xml │ │ │ └── splash.png │ │ │ ├── layout │ │ │ └── activity_main.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── values │ │ │ ├── ic_launcher_background.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ │ └── xml │ │ │ └── file_paths.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── getcapacitor │ │ └── myapp │ │ └── ExampleUnitTest.java ├── build.gradle ├── capacitor.settings.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── variables.gradle ├── capacitor.config.json ├── ionic.config.json ├── ios ├── .gitignore └── App │ ├── App.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── App.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── App │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── AppIcon-20x20@1x.png │ │ │ ├── AppIcon-20x20@2x-1.png │ │ │ ├── AppIcon-20x20@2x.png │ │ │ ├── AppIcon-20x20@3x.png │ │ │ ├── AppIcon-29x29@1x.png │ │ │ ├── AppIcon-29x29@2x-1.png │ │ │ ├── AppIcon-29x29@2x.png │ │ │ ├── AppIcon-29x29@3x.png │ │ │ ├── AppIcon-40x40@1x.png │ │ │ ├── AppIcon-40x40@2x-1.png │ │ │ ├── AppIcon-40x40@2x.png │ │ │ ├── AppIcon-40x40@3x.png │ │ │ ├── AppIcon-512@2x.png │ │ │ ├── AppIcon-60x60@2x.png │ │ │ ├── AppIcon-60x60@3x.png │ │ │ ├── AppIcon-76x76@1x.png │ │ │ ├── AppIcon-76x76@2x.png │ │ │ ├── AppIcon-83.5x83.5@2x.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── Splash.imageset │ │ │ ├── Contents.json │ │ │ ├── splash-2732x2732-1.png │ │ │ ├── splash-2732x2732-2.png │ │ │ └── splash-2732x2732.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ └── Info.plist │ ├── Podfile │ └── Resources │ └── ScanbotSDKOCRData.bundle │ ├── deu.traineddata │ ├── eng.traineddata │ └── osd.traineddata ├── package-lock.json ├── package.json ├── public ├── assets │ ├── icon │ │ ├── favicon.png │ │ └── icon.png │ └── shapes.svg ├── index.html └── manifest.json ├── src ├── App.test.tsx ├── App.tsx ├── index.tsx ├── pages │ ├── BarcodeListView.tsx │ ├── Home.tsx │ ├── ImageEditView.tsx │ ├── ImagePreview.tsx │ └── styles │ │ └── ImageEditView.css ├── react-app-env.d.ts ├── reportWebVitals.ts ├── service-worker.ts ├── serviceWorkerRegistration.ts ├── services │ └── ScanbotSDKService.tsx ├── setupTests.ts ├── theme │ └── variables.css └── utils │ ├── BarcodeRepository.tsx │ └── ImageRepository.tsx └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Specifies intentionally untracked files to ignore when using Git 2 | # http://git-scm.com/docs/gitignore 3 | 4 | *~ 5 | *.sw[mnpcod] 6 | .tmp 7 | *.tmp 8 | *.tmp.* 9 | UserInterfaceState.xcuserstate 10 | $RECYCLE.BIN/ 11 | 12 | *.log 13 | log.txt 14 | 15 | 16 | /.sourcemaps 17 | /.versions 18 | /coverage 19 | 20 | # Ionic 21 | /.ionic 22 | /www 23 | /platforms 24 | /plugins 25 | 26 | # Compiled output 27 | /dist 28 | /tmp 29 | /out-tsc 30 | /bazel-out 31 | /build 32 | 33 | # Node 34 | /node_modules 35 | npm-debug.log 36 | yarn-error.log 37 | 38 | # IDEs and editors 39 | .idea/ 40 | .project 41 | .classpath 42 | .c9/ 43 | *.launch 44 | .settings/ 45 | *.sublime-project 46 | *.sublime-workspace 47 | 48 | # Visual Studio Code 49 | .vscode/* 50 | !.vscode/settings.json 51 | !.vscode/tasks.json 52 | !.vscode/launch.json 53 | !.vscode/extensions.json 54 | .history/* 55 | 56 | 57 | # Miscellaneous 58 | .sass-cache/ 59 | /connect.lock 60 | /coverage 61 | /libpeerconnection.log 62 | testem.log 63 | /typings 64 | 65 | # System files 66 | Thumbs.db 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scanbot Barcode & Document Scanning Example App for Capacitor with Ionic 2 | 3 | This example app shows how to integrate the [Scanbot Barcode Scanner SDK](https://scanbot.io/developer/ionic-barcode-scanner/), [Scanbot Document Scanner SDK](https://scanbot.io/developer/ionic-document-scanner/), and [Scanbot Data Capture SDK](https://scanbot.io/developer/ionic-data-capture/) for Capacitor. 4 | 5 | The Scanbot SDK Cordova Plugin is available as an [npm package](https://www.npmjs.com/package/cordova-plugin-scanbot-sdk). 6 | 7 | For more details about the Scanbot SDK Cordova Plugin please refer to the [documentation](https://docs.scanbot.io/document-scanner-sdk/cordova/). 8 | 9 | ## What is the Scanbot SDK? 10 | 11 | The Scanbot SDK lets you integrate barcode & document scanning, as well as data extraction functionalities, into your mobile apps and website. It contains different modules that are licensable for an annual fixed price. For more details, visit our website https://scanbot.io. 12 | 13 | 14 | ## Trial License 15 | 16 | The Scanbot SDK will run without a license for one minute per session! 17 | 18 | After the trial period has expired, all SDK functions and UI components will stop working. You have to restart the app to get another one-minute trial period. 19 | 20 | To try the Scanbot SDK without a one-minute limit, you can get a free “no-strings-attached” trial license. Please submit the [Trial License Form](https://scanbot.io/trial/) on our website. 21 | 22 | ## Free Developer Support 23 | 24 | We provide free "no-strings-attached" developer support for the implementation & testing of the Scanbot SDK. 25 | If you encounter technical issues with integrating the Scanbot SDK or need advice on choosing the appropriate 26 | framework or features, please visit our [Support Page](https://docs.scanbot.io/support/). 27 | 28 | ## Documentation 29 | 👉 [Scanbot SDK documentation](https://docs.scanbot.io/document-scanner-sdk/cordova/introduction/) 30 | 31 | ## How to run this app 32 | 33 | ### Requirements 34 | 35 | - [Node.js v12](https://nodejs.org) or higher, with NPM v6.9 or higher 36 | - For Android Apps: 37 | * Latest [Android Studio](https://developer.android.com/studio/) with Android SDK installed 38 | - For iOS Apps: 39 | * Mac with latest version of [Xcode](https://developer.apple.com/xcode/) 40 | * [CocoaPods](https://cocoapods.org) 41 | 42 | Please check the full [requirements for Capacitor](https://capacitorjs.com/docs/getting-started/environment-setup). 43 | 44 | ### Install 45 | 46 | Install the node modules of this project: 47 | 48 | ``` 49 | cd scanbot-sdk-example-ionic-react/ 50 | npm install 51 | ``` 52 | 53 | ### Build 54 | 55 | Build the web assets and sync with the Capacitor native projects: 56 | 57 | ``` 58 | npm run build 59 | npx cap sync 60 | ``` 61 | 62 | ### Run 63 | 64 | Connect an Android or iOS device via USB and run the app from IDE or Command Line Interface (CLI). 65 | 66 | 67 | #### IDE 68 | Open the native projects in corresponding IDEs (Android Studio or Xcode) and hit the "Run" button: 69 | 70 | ``` 71 | npx cap open android 72 | npx cap open ios 73 | ``` 74 | 75 | #### CLI 76 | Or alternatively run the projects via CLI (Android or iOS): 77 | 78 | ``` 79 | npx cap run android 80 | npx cap run ios 81 | ``` 82 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | # Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore 2 | 3 | # Built application files 4 | *.apk 5 | *.aar 6 | *.ap_ 7 | *.aab 8 | 9 | # Files for the ART/Dalvik VM 10 | *.dex 11 | 12 | # Java class files 13 | *.class 14 | 15 | # Generated files 16 | bin/ 17 | gen/ 18 | out/ 19 | # Uncomment the following line in case you need and you don't have the release build type files in your app 20 | # release/ 21 | 22 | # Gradle files 23 | .gradle/ 24 | build/ 25 | 26 | # Local configuration file (sdk path, etc) 27 | local.properties 28 | 29 | # Proguard folder generated by Eclipse 30 | proguard/ 31 | 32 | # Log Files 33 | *.log 34 | 35 | # Android Studio Navigation editor temp files 36 | .navigation/ 37 | 38 | # Android Studio captures folder 39 | captures/ 40 | 41 | # IntelliJ 42 | *.iml 43 | .idea/workspace.xml 44 | .idea/tasks.xml 45 | .idea/gradle.xml 46 | .idea/assetWizardSettings.xml 47 | .idea/dictionaries 48 | .idea/libraries 49 | # Android Studio 3 in .gitignore file. 50 | .idea/caches 51 | .idea/modules.xml 52 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 53 | .idea/navEditor.xml 54 | 55 | # Keystore files 56 | # Uncomment the following lines if you do not want to check your keystore files in. 57 | #*.jks 58 | #*.keystore 59 | 60 | # External native build folder generated in Android Studio 2.2 and later 61 | .externalNativeBuild 62 | .cxx/ 63 | 64 | # Google Services (e.g. APIs or Firebase) 65 | # google-services.json 66 | 67 | # Freeline 68 | freeline.py 69 | freeline/ 70 | freeline_project_description.json 71 | 72 | # fastlane 73 | fastlane/report.xml 74 | fastlane/Preview.html 75 | fastlane/screenshots 76 | fastlane/test_output 77 | fastlane/readme.md 78 | 79 | # Version control 80 | vcs.xml 81 | 82 | # lint 83 | lint/intermediates/ 84 | lint/generated/ 85 | lint/outputs/ 86 | lint/tmp/ 87 | # lint/reports/ 88 | 89 | # Android Profiling 90 | *.hprof 91 | 92 | # Cordova plugins for Capacitor 93 | capacitor-cordova-android-plugins 94 | 95 | # Copied web assets 96 | app/src/main/assets/public 97 | 98 | # Generated Config files 99 | app/src/main/assets/capacitor.config.json 100 | app/src/main/assets/capacitor.plugins.json 101 | app/src/main/res/xml/config.xml 102 | -------------------------------------------------------------------------------- /android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build/* 2 | !/build/.npmkeep 3 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.compileSdkVersion 5 | defaultConfig { 6 | applicationId "io.scanbot.example.sdk.capacitor.ionic.react" 7 | minSdkVersion rootProject.ext.minSdkVersion 8 | targetSdkVersion rootProject.ext.targetSdkVersion 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 12 | aaptOptions { 13 | // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. 14 | // Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61 15 | ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~' 16 | } 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | } 25 | 26 | repositories { 27 | flatDir{ 28 | dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs' 29 | } 30 | } 31 | 32 | dependencies { 33 | implementation fileTree(include: ['*.jar'], dir: 'libs') 34 | implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" 35 | implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion" 36 | implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion" 37 | implementation project(':capacitor-android') 38 | testImplementation "junit:junit:$junitVersion" 39 | androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" 40 | androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" 41 | implementation project(':capacitor-cordova-android-plugins') 42 | } 43 | 44 | apply from: 'capacitor.build.gradle' 45 | 46 | try { 47 | def servicesJSON = file('google-services.json') 48 | if (servicesJSON.text) { 49 | apply plugin: 'com.google.gms.google-services' 50 | } 51 | } catch(Exception e) { 52 | logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work") 53 | } 54 | -------------------------------------------------------------------------------- /android/app/capacitor.build.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | 3 | android { 4 | compileOptions { 5 | sourceCompatibility JavaVersion.VERSION_11 6 | targetCompatibility JavaVersion.VERSION_11 7 | } 8 | } 9 | 10 | apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" 11 | dependencies { 12 | implementation project(':capacitor-app') 13 | implementation project(':capacitor-camera') 14 | implementation project(':capacitor-haptics') 15 | implementation project(':capacitor-keyboard') 16 | implementation project(':capacitor-status-bar') 17 | 18 | } 19 | apply from: "../../node_modules/cordova-plugin-scanbot-sdk/src/android/build-extras-sb.gradle" 20 | 21 | if (hasProperty('postBuildExtras')) { 22 | postBuildExtras() 23 | } 24 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import android.content.Context; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | import androidx.test.platform.app.InstrumentationRegistry; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * @see Testing documentation 15 | */ 16 | @RunWith(AndroidJUnit4.class) 17 | public class ExampleInstrumentedTest { 18 | 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 23 | 24 | assertEquals("com.getcapacitor.app", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 33 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /android/app/src/main/assets/ocr_blobs/deu.traineddata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/assets/ocr_blobs/deu.traineddata -------------------------------------------------------------------------------- /android/app/src/main/assets/ocr_blobs/eng.traineddata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/assets/ocr_blobs/eng.traineddata -------------------------------------------------------------------------------- /android/app/src/main/assets/ocr_blobs/osd.traineddata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/assets/ocr_blobs/osd.traineddata -------------------------------------------------------------------------------- /android/app/src/main/java/io/scanbot/example/sdk/capacitor/ionic/react/MainActivity.java: -------------------------------------------------------------------------------- 1 | package io.scanbot.example.sdk.capacitor.ionic.react; 2 | 3 | import com.getcapacitor.BridgeActivity; 4 | 5 | public class MainActivity extends BridgeActivity {} 6 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/drawable-land-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/drawable-land-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/drawable-land-xhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/drawable-land-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/drawable-land-xxxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/drawable-port-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/drawable-port-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/drawable-port-xhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/drawable-port-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/drawable-port-xxxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/drawable/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ScanbotIonicReactJs 4 | ScanbotIonicReactJs 5 | io.scanbot.example.sdk.capacitor.ionic.react 6 | io.scanbot.example.sdk.capacitor.ionic.react 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 17 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /android/app/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | 14 | @Test 15 | public void addition_isCorrect() throws Exception { 16 | assertEquals(4, 2 + 2); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | mavenCentral() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:7.2.1' 11 | classpath 'com.google.gms:google-services:4.3.13' 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | apply from: "variables.gradle" 19 | 20 | allprojects { 21 | repositories { 22 | google() 23 | mavenCentral() 24 | } 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /android/capacitor.settings.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | include ':capacitor-android' 3 | project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') 4 | 5 | include ':capacitor-app' 6 | project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android') 7 | 8 | include ':capacitor-camera' 9 | project(':capacitor-camera').projectDir = new File('../node_modules/@capacitor/camera/android') 10 | 11 | include ':capacitor-haptics' 12 | project(':capacitor-haptics').projectDir = new File('../node_modules/@capacitor/haptics/android') 13 | 14 | include ':capacitor-keyboard' 15 | project(':capacitor-keyboard').projectDir = new File('../node_modules/@capacitor/keyboard/android') 16 | 17 | include ':capacitor-status-bar' 18 | project(':capacitor-status-bar').projectDir = new File('../node_modules/@capacitor/status-bar/android') 19 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | 19 | # AndroidX package structure to make it clearer which packages are bundled with the 20 | # Android operating system, and which are packaged with your app's APK 21 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 22 | android.useAndroidX=true 23 | # Automatically convert third-party libraries to use AndroidX 24 | android.enableJetifier=true 25 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | include ':capacitor-cordova-android-plugins' 3 | project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') 4 | 5 | apply from: 'capacitor.settings.gradle' -------------------------------------------------------------------------------- /android/variables.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | minSdkVersion = 22 3 | compileSdkVersion = 32 4 | targetSdkVersion = 32 5 | androidxActivityVersion = '1.4.0' 6 | androidxAppCompatVersion = '1.4.2' 7 | androidxCoordinatorLayoutVersion = '1.2.0' 8 | androidxCoreVersion = '1.8.0' 9 | androidxFragmentVersion = '1.4.1' 10 | coreSplashScreenVersion = '1.0.0-rc01' 11 | androidxWebkitVersion = '1.4.0' 12 | junitVersion = '4.13.2' 13 | androidxJunitVersion = '1.1.3' 14 | androidxEspressoCoreVersion = '3.4.0' 15 | cordovaAndroidVersion = '10.1.1' 16 | } -------------------------------------------------------------------------------- /capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "io.scanbot.example.sdk.capacitor.ionic.react", 3 | "appName": "ScanbotIonicReactJs", 4 | "webDir": "build", 5 | "bundledWebRuntime": false 6 | } 7 | -------------------------------------------------------------------------------- /ionic.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scanbot-example-ionic-capacitor-react", 3 | "integrations": { 4 | "capacitor": {} 5 | }, 6 | "type": "react" 7 | } 8 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | App/build 2 | App/Pods 3 | App/Podfile.lock 4 | App/App/public 5 | DerivedData 6 | xcuserdata 7 | 8 | # Cordova plugins for Capacitor 9 | capacitor-cordova-ios-plugins 10 | 11 | # Generated Config files 12 | App/App/capacitor.config.json 13 | App/App/config.xml 14 | -------------------------------------------------------------------------------- /ios/App/App.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2FAD9763203C412B000D30F8 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; }; 11 | 50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; }; 12 | 504EC3081FED79650016851F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; }; 13 | 504EC30D1FED79650016851F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30B1FED79650016851F /* Main.storyboard */; }; 14 | 504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; }; 15 | 504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; }; 16 | 50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; }; 17 | 72DBA9AC2A4F0F570065640B /* ScanbotSDKOCRData.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 72DBA9AB2A4F0F570065640B /* ScanbotSDKOCRData.bundle */; }; 18 | A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = ""; }; 23 | 50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = ""; }; 24 | 504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 504EC3071FED79650016851F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 26 | 504EC30C1FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 27 | 504EC30E1FED79650016851F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 28 | 504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 29 | 504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 30 | 50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = ""; }; 31 | 72DBA9AB2A4F0F570065640B /* ScanbotSDKOCRData.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = ScanbotSDKOCRData.bundle; path = resources/ScanbotSDKOCRData.bundle; sourceTree = ""; }; 32 | AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = ""; }; 34 | FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = ""; }; 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | 504EC3011FED79650016851F /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */, 43 | ); 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | /* End PBXFrameworksBuildPhase section */ 47 | 48 | /* Begin PBXGroup section */ 49 | 27E2DDA53C4D2A4D1A88CE4A /* Frameworks */ = { 50 | isa = PBXGroup; 51 | children = ( 52 | AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */, 53 | ); 54 | name = Frameworks; 55 | sourceTree = ""; 56 | }; 57 | 504EC2FB1FED79650016851F = { 58 | isa = PBXGroup; 59 | children = ( 60 | 72DBA9AB2A4F0F570065640B /* ScanbotSDKOCRData.bundle */, 61 | 504EC3061FED79650016851F /* App */, 62 | 504EC3051FED79650016851F /* Products */, 63 | 7F8756D8B27F46E3366F6CEA /* Pods */, 64 | 27E2DDA53C4D2A4D1A88CE4A /* Frameworks */, 65 | ); 66 | sourceTree = ""; 67 | }; 68 | 504EC3051FED79650016851F /* Products */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 504EC3041FED79650016851F /* App.app */, 72 | ); 73 | name = Products; 74 | sourceTree = ""; 75 | }; 76 | 504EC3061FED79650016851F /* App */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 50379B222058CBB4000EE86E /* capacitor.config.json */, 80 | 504EC3071FED79650016851F /* AppDelegate.swift */, 81 | 504EC30B1FED79650016851F /* Main.storyboard */, 82 | 504EC30E1FED79650016851F /* Assets.xcassets */, 83 | 504EC3101FED79650016851F /* LaunchScreen.storyboard */, 84 | 504EC3131FED79650016851F /* Info.plist */, 85 | 2FAD9762203C412B000D30F8 /* config.xml */, 86 | 50B271D01FEDC1A000F3C39B /* public */, 87 | ); 88 | path = App; 89 | sourceTree = ""; 90 | }; 91 | 7F8756D8B27F46E3366F6CEA /* Pods */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */, 95 | AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */, 96 | ); 97 | name = Pods; 98 | sourceTree = ""; 99 | }; 100 | /* End PBXGroup section */ 101 | 102 | /* Begin PBXNativeTarget section */ 103 | 504EC3031FED79650016851F /* App */ = { 104 | isa = PBXNativeTarget; 105 | buildConfigurationList = 504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */; 106 | buildPhases = ( 107 | 6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */, 108 | 504EC3001FED79650016851F /* Sources */, 109 | 504EC3011FED79650016851F /* Frameworks */, 110 | 504EC3021FED79650016851F /* Resources */, 111 | 9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */, 112 | AE98080F240842D017FDE6C6 /* [CP] Copy Pods Resources */, 113 | ); 114 | buildRules = ( 115 | ); 116 | dependencies = ( 117 | ); 118 | name = App; 119 | productName = App; 120 | productReference = 504EC3041FED79650016851F /* App.app */; 121 | productType = "com.apple.product-type.application"; 122 | }; 123 | /* End PBXNativeTarget section */ 124 | 125 | /* Begin PBXProject section */ 126 | 504EC2FC1FED79650016851F /* Project object */ = { 127 | isa = PBXProject; 128 | attributes = { 129 | LastSwiftUpdateCheck = 0920; 130 | LastUpgradeCheck = 0920; 131 | TargetAttributes = { 132 | 504EC3031FED79650016851F = { 133 | CreatedOnToolsVersion = 9.2; 134 | LastSwiftMigration = 1100; 135 | ProvisioningStyle = Automatic; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */; 140 | compatibilityVersion = "Xcode 8.0"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 504EC2FB1FED79650016851F; 148 | productRefGroup = 504EC3051FED79650016851F /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 504EC3031FED79650016851F /* App */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 504EC3021FED79650016851F /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */, 163 | 50B271D11FEDC1A000F3C39B /* public in Resources */, 164 | 504EC30F1FED79650016851F /* Assets.xcassets in Resources */, 165 | 50379B232058CBB4000EE86E /* capacitor.config.json in Resources */, 166 | 504EC30D1FED79650016851F /* Main.storyboard in Resources */, 167 | 2FAD9763203C412B000D30F8 /* config.xml in Resources */, 168 | 72DBA9AC2A4F0F570065640B /* ScanbotSDKOCRData.bundle in Resources */, 169 | ); 170 | runOnlyForDeploymentPostprocessing = 0; 171 | }; 172 | /* End PBXResourcesBuildPhase section */ 173 | 174 | /* Begin PBXShellScriptBuildPhase section */ 175 | 6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */ = { 176 | isa = PBXShellScriptBuildPhase; 177 | buildActionMask = 2147483647; 178 | files = ( 179 | ); 180 | inputPaths = ( 181 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 182 | "${PODS_ROOT}/Manifest.lock", 183 | ); 184 | name = "[CP] Check Pods Manifest.lock"; 185 | outputPaths = ( 186 | "$(DERIVED_FILE_DIR)/Pods-App-checkManifestLockResult.txt", 187 | ); 188 | runOnlyForDeploymentPostprocessing = 0; 189 | shellPath = /bin/sh; 190 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 191 | showEnvVarsInLog = 0; 192 | }; 193 | 9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */ = { 194 | isa = PBXShellScriptBuildPhase; 195 | buildActionMask = 2147483647; 196 | files = ( 197 | ); 198 | inputPaths = ( 199 | ); 200 | name = "[CP] Embed Pods Frameworks"; 201 | outputPaths = ( 202 | ); 203 | runOnlyForDeploymentPostprocessing = 0; 204 | shellPath = /bin/sh; 205 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-App/Pods-App-frameworks.sh\"\n"; 206 | showEnvVarsInLog = 0; 207 | }; 208 | AE98080F240842D017FDE6C6 /* [CP] Copy Pods Resources */ = { 209 | isa = PBXShellScriptBuildPhase; 210 | buildActionMask = 2147483647; 211 | files = ( 212 | ); 213 | inputPaths = ( 214 | ); 215 | name = "[CP] Copy Pods Resources"; 216 | outputPaths = ( 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | shellPath = /bin/sh; 220 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-App/Pods-App-resources.sh\"\n"; 221 | showEnvVarsInLog = 0; 222 | }; 223 | /* End PBXShellScriptBuildPhase section */ 224 | 225 | /* Begin PBXSourcesBuildPhase section */ 226 | 504EC3001FED79650016851F /* Sources */ = { 227 | isa = PBXSourcesBuildPhase; 228 | buildActionMask = 2147483647; 229 | files = ( 230 | 504EC3081FED79650016851F /* AppDelegate.swift in Sources */, 231 | ); 232 | runOnlyForDeploymentPostprocessing = 0; 233 | }; 234 | /* End PBXSourcesBuildPhase section */ 235 | 236 | /* Begin PBXVariantGroup section */ 237 | 504EC30B1FED79650016851F /* Main.storyboard */ = { 238 | isa = PBXVariantGroup; 239 | children = ( 240 | 504EC30C1FED79650016851F /* Base */, 241 | ); 242 | name = Main.storyboard; 243 | sourceTree = ""; 244 | }; 245 | 504EC3101FED79650016851F /* LaunchScreen.storyboard */ = { 246 | isa = PBXVariantGroup; 247 | children = ( 248 | 504EC3111FED79650016851F /* Base */, 249 | ); 250 | name = LaunchScreen.storyboard; 251 | sourceTree = ""; 252 | }; 253 | /* End PBXVariantGroup section */ 254 | 255 | /* Begin XCBuildConfiguration section */ 256 | 504EC3141FED79650016851F /* Debug */ = { 257 | isa = XCBuildConfiguration; 258 | buildSettings = { 259 | ALWAYS_SEARCH_USER_PATHS = NO; 260 | CLANG_ANALYZER_NONNULL = YES; 261 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 262 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 263 | CLANG_CXX_LIBRARY = "libc++"; 264 | CLANG_ENABLE_MODULES = YES; 265 | CLANG_ENABLE_OBJC_ARC = YES; 266 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 267 | CLANG_WARN_BOOL_CONVERSION = YES; 268 | CLANG_WARN_COMMA = YES; 269 | CLANG_WARN_CONSTANT_CONVERSION = YES; 270 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 271 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 272 | CLANG_WARN_EMPTY_BODY = YES; 273 | CLANG_WARN_ENUM_CONVERSION = YES; 274 | CLANG_WARN_INFINITE_RECURSION = YES; 275 | CLANG_WARN_INT_CONVERSION = YES; 276 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 277 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 278 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 279 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 280 | CLANG_WARN_STRICT_PROTOTYPES = YES; 281 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 282 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 283 | CLANG_WARN_UNREACHABLE_CODE = YES; 284 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 285 | CODE_SIGN_IDENTITY = "iPhone Developer"; 286 | COPY_PHASE_STRIP = NO; 287 | DEBUG_INFORMATION_FORMAT = dwarf; 288 | ENABLE_STRICT_OBJC_MSGSEND = YES; 289 | ENABLE_TESTABILITY = YES; 290 | GCC_C_LANGUAGE_STANDARD = gnu11; 291 | GCC_DYNAMIC_NO_PIC = NO; 292 | GCC_NO_COMMON_BLOCKS = YES; 293 | GCC_OPTIMIZATION_LEVEL = 0; 294 | GCC_PREPROCESSOR_DEFINITIONS = ( 295 | "DEBUG=1", 296 | "$(inherited)", 297 | ); 298 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 299 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 300 | GCC_WARN_UNDECLARED_SELECTOR = YES; 301 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 302 | GCC_WARN_UNUSED_FUNCTION = YES; 303 | GCC_WARN_UNUSED_VARIABLE = YES; 304 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 305 | MTL_ENABLE_DEBUG_INFO = YES; 306 | ONLY_ACTIVE_ARCH = YES; 307 | SDKROOT = iphoneos; 308 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 309 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 310 | }; 311 | name = Debug; 312 | }; 313 | 504EC3151FED79650016851F /* Release */ = { 314 | isa = XCBuildConfiguration; 315 | buildSettings = { 316 | ALWAYS_SEARCH_USER_PATHS = NO; 317 | CLANG_ANALYZER_NONNULL = YES; 318 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 319 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 320 | CLANG_CXX_LIBRARY = "libc++"; 321 | CLANG_ENABLE_MODULES = YES; 322 | CLANG_ENABLE_OBJC_ARC = YES; 323 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 324 | CLANG_WARN_BOOL_CONVERSION = YES; 325 | CLANG_WARN_COMMA = YES; 326 | CLANG_WARN_CONSTANT_CONVERSION = YES; 327 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 328 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 329 | CLANG_WARN_EMPTY_BODY = YES; 330 | CLANG_WARN_ENUM_CONVERSION = YES; 331 | CLANG_WARN_INFINITE_RECURSION = YES; 332 | CLANG_WARN_INT_CONVERSION = YES; 333 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 334 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 336 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 337 | CLANG_WARN_STRICT_PROTOTYPES = YES; 338 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 339 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 340 | CLANG_WARN_UNREACHABLE_CODE = YES; 341 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 342 | CODE_SIGN_IDENTITY = "iPhone Developer"; 343 | COPY_PHASE_STRIP = NO; 344 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 345 | ENABLE_NS_ASSERTIONS = NO; 346 | ENABLE_STRICT_OBJC_MSGSEND = YES; 347 | GCC_C_LANGUAGE_STANDARD = gnu11; 348 | GCC_NO_COMMON_BLOCKS = YES; 349 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 350 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 351 | GCC_WARN_UNDECLARED_SELECTOR = YES; 352 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 353 | GCC_WARN_UNUSED_FUNCTION = YES; 354 | GCC_WARN_UNUSED_VARIABLE = YES; 355 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 356 | MTL_ENABLE_DEBUG_INFO = NO; 357 | SDKROOT = iphoneos; 358 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 359 | VALIDATE_PRODUCT = YES; 360 | }; 361 | name = Release; 362 | }; 363 | 504EC3171FED79650016851F /* Debug */ = { 364 | isa = XCBuildConfiguration; 365 | baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */; 366 | buildSettings = { 367 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 368 | CODE_SIGN_STYLE = Automatic; 369 | CURRENT_PROJECT_VERSION = 1; 370 | DEVELOPMENT_TEAM = FRUPYT6KB3; 371 | INFOPLIST_FILE = App/Info.plist; 372 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 373 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 374 | MARKETING_VERSION = 1.0; 375 | OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; 376 | PRODUCT_BUNDLE_IDENTIFIER = io.scanbot.example.sdk.capacitor.ionic.react; 377 | PRODUCT_NAME = "$(TARGET_NAME)"; 378 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 379 | SWIFT_VERSION = 5.0; 380 | TARGETED_DEVICE_FAMILY = "1,2"; 381 | }; 382 | name = Debug; 383 | }; 384 | 504EC3181FED79650016851F /* Release */ = { 385 | isa = XCBuildConfiguration; 386 | baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */; 387 | buildSettings = { 388 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 389 | CODE_SIGN_STYLE = Automatic; 390 | CURRENT_PROJECT_VERSION = 1; 391 | DEVELOPMENT_TEAM = FRUPYT6KB3; 392 | INFOPLIST_FILE = App/Info.plist; 393 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 394 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 395 | MARKETING_VERSION = 1.0; 396 | PRODUCT_BUNDLE_IDENTIFIER = io.scanbot.example.sdk.capacitor.ionic.react; 397 | PRODUCT_NAME = "$(TARGET_NAME)"; 398 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; 399 | SWIFT_VERSION = 5.0; 400 | TARGETED_DEVICE_FAMILY = "1,2"; 401 | }; 402 | name = Release; 403 | }; 404 | /* End XCBuildConfiguration section */ 405 | 406 | /* Begin XCConfigurationList section */ 407 | 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */ = { 408 | isa = XCConfigurationList; 409 | buildConfigurations = ( 410 | 504EC3141FED79650016851F /* Debug */, 411 | 504EC3151FED79650016851F /* Release */, 412 | ); 413 | defaultConfigurationIsVisible = 0; 414 | defaultConfigurationName = Release; 415 | }; 416 | 504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */ = { 417 | isa = XCConfigurationList; 418 | buildConfigurations = ( 419 | 504EC3171FED79650016851F /* Debug */, 420 | 504EC3181FED79650016851F /* Release */, 421 | ); 422 | defaultConfigurationIsVisible = 0; 423 | defaultConfigurationName = Release; 424 | }; 425 | /* End XCConfigurationList section */ 426 | }; 427 | rootObject = 504EC2FC1FED79650016851F /* Project object */; 428 | } 429 | -------------------------------------------------------------------------------- /ios/App/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/App/App.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/App/App/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Capacitor 3 | 4 | @UIApplicationMain 5 | class AppDelegate: UIResponder, UIApplicationDelegate { 6 | 7 | var window: UIWindow? 8 | 9 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 10 | // Override point for customization after application launch. 11 | return true 12 | } 13 | 14 | func applicationWillResignActive(_ application: UIApplication) { 15 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 16 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 17 | } 18 | 19 | func applicationDidEnterBackground(_ application: UIApplication) { 20 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 21 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 22 | } 23 | 24 | func applicationWillEnterForeground(_ application: UIApplication) { 25 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 26 | } 27 | 28 | func applicationDidBecomeActive(_ application: UIApplication) { 29 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 30 | } 31 | 32 | func applicationWillTerminate(_ application: UIApplication) { 33 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 34 | } 35 | 36 | func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { 37 | // Called when the app was launched with a url. Feel free to add additional processing here, 38 | // but if you want the App API to support tracking app url opens, make sure to keep this call 39 | return ApplicationDelegateProxy.shared.application(app, open: url, options: options) 40 | } 41 | 42 | func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { 43 | // Called when the app was launched with an activity, including Universal Links. 44 | // Feel free to add additional processing here, but if you want the App API to support 45 | // tracking app url opens, make sure to keep this call 46 | return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler) 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "AppIcon-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "AppIcon-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "AppIcon-29x29@2x-1.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "AppIcon-29x29@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "AppIcon-40x40@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "AppIcon-40x40@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "AppIcon-60x60@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "AppIcon-60x60@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "20x20", 53 | "idiom" : "ipad", 54 | "filename" : "AppIcon-20x20@1x.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "AppIcon-20x20@2x-1.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "AppIcon-29x29@1x.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "AppIcon-29x29@2x.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "AppIcon-40x40@1x.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "AppIcon-40x40@2x-1.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "AppIcon-76x76@1x.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "AppIcon-76x76@2x.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "AppIcon-83.5x83.5@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "1024x1024", 107 | "idiom" : "ios-marketing", 108 | "filename" : "AppIcon-512@2x.png", 109 | "scale" : "1x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "xcode" 115 | } 116 | } -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "splash-2732x2732-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "splash-2732x2732-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "splash-2732x2732.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png -------------------------------------------------------------------------------- /ios/App/App/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /ios/App/App/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ios/App/App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ScanbotIonicReactJs 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | NSCameraUsageDescription 30 | Scan Documents, QR-/Barcodes, MRZ, etc. 31 | NSPhotoLibraryAddUsageDescription 32 | This app needs to access your photo library in order to import images 33 | NSPhotoLibraryUsageDescription 34 | This app needs to access your photo library in order to import images 35 | UIRequiredDeviceCapabilities 36 | 37 | armv7 38 | 39 | UISupportedInterfaceOrientations 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationLandscapeLeft 43 | UIInterfaceOrientationLandscapeRight 44 | 45 | UISupportedInterfaceOrientations~ipad 46 | 47 | UIInterfaceOrientationPortrait 48 | UIInterfaceOrientationPortraitUpsideDown 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /ios/App/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers' 2 | 3 | platform :ios, '13.0' 4 | use_frameworks! 5 | 6 | # workaround to avoid Xcode caching of Pods that requires 7 | # Product -> Clean Build Folder after new Cordova plugins installed 8 | # Requires CocoaPods 1.6 or newer 9 | install! 'cocoapods', :disable_input_output_paths => true 10 | 11 | def capacitor_pods 12 | pod 'Capacitor', :path => '../../node_modules/@capacitor/ios' 13 | pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios' 14 | pod 'CapacitorApp', :path => '../../node_modules/@capacitor/app' 15 | pod 'CapacitorCamera', :path => '../../node_modules/@capacitor/camera' 16 | pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics' 17 | pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard' 18 | pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar' 19 | pod 'CordovaPluginsStatic', :path => '../capacitor-cordova-ios-plugins' 20 | end 21 | 22 | target 'App' do 23 | capacitor_pods 24 | # Add your Pods here 25 | end 26 | 27 | post_install do |installer| 28 | assertDeploymentTarget(installer) 29 | end 30 | -------------------------------------------------------------------------------- /ios/App/Resources/ScanbotSDKOCRData.bundle/deu.traineddata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/Resources/ScanbotSDKOCRData.bundle/deu.traineddata -------------------------------------------------------------------------------- /ios/App/Resources/ScanbotSDKOCRData.bundle/eng.traineddata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/Resources/ScanbotSDKOCRData.bundle/eng.traineddata -------------------------------------------------------------------------------- /ios/App/Resources/ScanbotSDKOCRData.bundle/osd.traineddata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/ios/App/Resources/ScanbotSDKOCRData.bundle/osd.traineddata -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scanbot-example-ionic-capacitor-react", 3 | "version": "0.0.1", 4 | "private": true, 5 | "dependencies": { 6 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11", 7 | "@capacitor/android": "4.6.1", 8 | "@capacitor/app": "4.1.1", 9 | "@capacitor/camera": "^4.1.4", 10 | "@capacitor/core": "4.6.1", 11 | "@capacitor/haptics": "4.1.0", 12 | "@capacitor/ios": "4.6.1", 13 | "@capacitor/keyboard": "4.1.0", 14 | "@capacitor/status-bar": "4.1.1", 15 | "@ionic/react": "^6.0.0", 16 | "@ionic/react-router": "^6.0.0", 17 | "@testing-library/jest-dom": "^5.11.9", 18 | "@testing-library/react": "^13.3.0", 19 | "@testing-library/user-event": "^12.6.3", 20 | "@types/jest": "^26.0.20", 21 | "@types/node": "^12.19.15", 22 | "@types/react": "^18.0.17", 23 | "@types/react-dom": "^18.0.6", 24 | "@types/react-router": "^5.1.11", 25 | "@types/react-router-dom": "^5.1.7", 26 | "cordova-plugin-scanbot-sdk": "^4.17.3", 27 | "history": "^4.9.0", 28 | "ionicons": "^6.0.3", 29 | "react": "^18.2.0", 30 | "react-dom": "^18.2.0", 31 | "react-router": "^5.2.0", 32 | "react-router-dom": "^5.2.0", 33 | "typescript": "^4.1.3", 34 | "web-vitals": "^0.2.4", 35 | "workbox-background-sync": "^5.1.4", 36 | "workbox-broadcast-update": "^5.1.4", 37 | "workbox-cacheable-response": "^5.1.4", 38 | "workbox-core": "^5.1.4", 39 | "workbox-expiration": "^5.1.4", 40 | "workbox-google-analytics": "^5.1.4", 41 | "workbox-navigation-preload": "^5.1.4", 42 | "workbox-precaching": "^5.1.4", 43 | "workbox-range-requests": "^5.1.4", 44 | "workbox-routing": "^5.1.4", 45 | "workbox-strategies": "^5.1.4", 46 | "workbox-streams": "^5.1.4" 47 | }, 48 | "scripts": { 49 | "start": "react-scripts start", 50 | "build": "react-scripts build", 51 | "test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(@ionic/react|@ionic/react-router|@ionic/core|@stencil/core|ionicons)/)'", 52 | "eject": "react-scripts eject" 53 | }, 54 | "eslintConfig": { 55 | "extends": [ 56 | "react-app", 57 | "react-app/jest" 58 | ] 59 | }, 60 | "browserslist": { 61 | "production": [ 62 | ">0.2%", 63 | "not dead", 64 | "not op_mini all" 65 | ], 66 | "development": [ 67 | "last 1 chrome version", 68 | "last 1 firefox version", 69 | "last 1 safari version" 70 | ] 71 | }, 72 | "devDependencies": { 73 | "@capacitor/cli": "4.6.1", 74 | "react-scripts": "5.0.1" 75 | }, 76 | "description": "An Ionic project" 77 | } 78 | -------------------------------------------------------------------------------- /public/assets/icon/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/public/assets/icon/favicon.png -------------------------------------------------------------------------------- /public/assets/icon/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doo/scanbot-sdk-example-ionic-react/92003c7087248ba847b9d33486cbbdfb63d468fe/public/assets/icon/icon.png -------------------------------------------------------------------------------- /public/assets/shapes.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ionic App 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Ionic App", 3 | "name": "My Ionic App", 4 | "icons": [ 5 | { 6 | "src": "assets/icon/favicon.png", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "assets/icon/icon.png", 12 | "type": "image/png", 13 | "sizes": "512x512", 14 | "purpose": "maskable" 15 | } 16 | ], 17 | "start_url": ".", 18 | "display": "standalone", 19 | "theme_color": "#ffffff", 20 | "background_color": "#ffffff" 21 | } 22 | -------------------------------------------------------------------------------- /src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders without crashing', () => { 6 | const { baseElement } = render(); 7 | expect(baseElement).toBeDefined(); 8 | }); 9 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import { Redirect, Route } from 'react-router-dom'; 2 | import { IonApp, IonRouterOutlet, setupIonicReact } from '@ionic/react'; 3 | import { IonReactRouter } from '@ionic/react-router'; 4 | import Home from './pages/Home'; 5 | import ImagePreview from './pages/ImagePreview'; 6 | import ImageEditView from './pages/ImageEditView'; 7 | 8 | /* Core CSS required for Ionic components to work properly */ 9 | import '@ionic/react/css/core.css'; 10 | 11 | /* Basic CSS for apps built with Ionic */ 12 | import '@ionic/react/css/normalize.css'; 13 | import '@ionic/react/css/structure.css'; 14 | import '@ionic/react/css/typography.css'; 15 | 16 | /* Optional CSS utils that can be commented out */ 17 | import '@ionic/react/css/padding.css'; 18 | import '@ionic/react/css/float-elements.css'; 19 | import '@ionic/react/css/text-alignment.css'; 20 | import '@ionic/react/css/text-transformation.css'; 21 | import '@ionic/react/css/flex-utils.css'; 22 | import '@ionic/react/css/display.css'; 23 | 24 | /* Theme variables */ 25 | import './theme/variables.css'; 26 | 27 | /* Scanbot SDK */ 28 | import { ScanbotSDKConfiguration } from 'cordova-plugin-scanbot-sdk'; 29 | 30 | /* Scanbot SDK Service */ 31 | import { ScanbotSDKService } from './services/ScanbotSDKService'; 32 | import React from "react"; 33 | import BarcodeListView from "./pages/BarcodeListView"; 34 | 35 | setupIonicReact(); 36 | 37 | /* 38 | * TODO add the license key here. 39 | * Please note: The Scanbot SDK will run without a license key for one minute per session! 40 | * After the trial period has expired all Scanbot SDK functions as well as the UI components will stop working 41 | * or may be terminated. You can get a free "no-strings-attached" trial license key. 42 | * Please submit the trial license form (https://scanbot.io/trial/) on our website by using 43 | * the app identifier "io.scanbot.example.sdk.capacitor.ionic.react" of this example app. 44 | */ 45 | const SDK_LICENSE_KEY = ''; 46 | 47 | // initialize Scanbot SDK 48 | const initializeSdk = async () => { 49 | const config: ScanbotSDKConfiguration = { 50 | loggingEnabled: true, 51 | licenseKey: SDK_LICENSE_KEY, 52 | }; 53 | try { 54 | await ScanbotSDKService.SDK.initializeSdk(config) 55 | .then(result => console.log(JSON.stringify(result))) 56 | .catch(err => console.error('Scanbot SDK initialization error: ' + JSON.stringify(err))); 57 | } 58 | catch (e) { 59 | console.error('Scanbot SDK initialization error: ' + JSON.stringify(e)); 60 | } 61 | } 62 | 63 | const App: React.FC = () => { 64 | 65 | initializeSdk().then(); 66 | 67 | return ( 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | ); 90 | } 91 | 92 | export default App; 93 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import App from './App'; 4 | import * as serviceWorkerRegistration from './serviceWorkerRegistration'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const container = document.getElementById('root'); 8 | const root = createRoot(container!); 9 | root.render( 10 | 11 | 12 | 13 | ); 14 | 15 | // If you want your app to work offline and load faster, you can change 16 | // unregister() to register() below. Note this comes with some pitfalls. 17 | // Learn more about service workers: https://cra.link/PWA 18 | serviceWorkerRegistration.unregister(); 19 | 20 | // If you want to start measuring performance in your app, pass a function 21 | // to log results (for example: reportWebVitals(console.log)) 22 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 23 | reportWebVitals(); 24 | -------------------------------------------------------------------------------- /src/pages/BarcodeListView.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | IonContent, 4 | IonHeader, 5 | IonPage, 6 | IonTitle, 7 | IonToolbar, 8 | IonBackButton, 9 | IonButtons, 10 | IonList, 11 | IonItem, 12 | IonLabel, 13 | } from '@ionic/react'; 14 | 15 | import {BarcodeRepository} from "../utils/BarcodeRepository"; 16 | 17 | const BarcodeListView: React.FC = () => { 18 | let barcodes = BarcodeRepository.getBarcodes(); 19 | 20 | return ( 21 | 22 | 23 | 24 | 25 | 26 | 27 | Display Barcodes 28 | 29 | 30 | 31 | 32 | 33 | {barcodes.map((barcode) => ( 34 | 35 | 36 |

{barcode.text}

37 |

{barcode.type}

38 |
39 |
40 | ))} 41 |
42 |
43 |
44 | ); 45 | }; 46 | 47 | export default BarcodeListView; -------------------------------------------------------------------------------- /src/pages/Home.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | IonContent, 4 | IonHeader, 5 | IonPage, 6 | IonToolbar, 7 | IonItemGroup, 8 | IonItemDivider, 9 | IonItem, 10 | IonLabel, 11 | useIonAlert, 12 | useIonLoading, 13 | isPlatform, 14 | IonTitle, 15 | } from '@ionic/react'; 16 | 17 | import { Camera, CameraResultType, CameraSource } from '@capacitor/camera'; 18 | 19 | import { useHistory } from 'react-router'; 20 | 21 | import { ImageResultsRepository } from '../utils/ImageRepository'; 22 | import { BarcodeRepository } from '../utils/BarcodeRepository'; 23 | 24 | /* Scanbot SDK Service */ 25 | import { ScanbotSDKService } from '../services/ScanbotSDKService'; 26 | 27 | import { 28 | DocumentScannerConfiguration, 29 | BarcodeScannerConfiguration, 30 | BatchBarcodeScannerConfiguration, 31 | MrzScannerConfiguration, 32 | CheckRecognizerConfiguration, 33 | HealthInsuranceCardScannerConfiguration, 34 | TextDataScannerStep, 35 | DataScannerConfiguration, 36 | LicensePlateScannerConfiguration, 37 | GenericDocumentRecognizerConfiguration, 38 | BarcodeResultField, 39 | FinderDocumentScannerConfiguration, 40 | } from 'cordova-plugin-scanbot-sdk'; 41 | 42 | const Home: React.FC = () => { 43 | const history = useHistory(); 44 | const [presentAlert] = useIonAlert(); 45 | const [present, dismiss] = useIonLoading(); 46 | 47 | // ----------------- 48 | // Document Scanner 49 | // ----------------- 50 | const startDocumentScanner = async () => { 51 | if (!(await ScanbotSDKService.checkLicense())) { return; } 52 | 53 | const configs: DocumentScannerConfiguration = { 54 | cameraPreviewMode: 'FIT_IN', 55 | interfaceOrientation: 'PORTRAIT', 56 | pageCounterButtonTitle: '%d Page(s)', 57 | multiPageEnabled: true, 58 | ignoreBadAspectRatio: true, 59 | topBarBackgroundColor: '#c8193c', 60 | bottomBarBackgroundColor: '#c8193c', 61 | // see further configs ... 62 | }; 63 | try { 64 | const documentScannerResults = await ScanbotSDKService.SDK.UI.startDocumentScanner({ uiConfigs: configs }); 65 | if (documentScannerResults.status === 'CANCELED') { 66 | await presentAlert({ 67 | header: 'Information', 68 | message: 'Document scanner has been canceled.', 69 | buttons: ['OK'], 70 | }); 71 | return; 72 | } 73 | await ImageResultsRepository.INSTANCE.addPages(documentScannerResults.pages); 74 | history.push("/imagepreview"); 75 | } 76 | catch (error) { 77 | console.error(error); 78 | } 79 | } 80 | 81 | // ------------------------ 82 | // Finder Document Scanner 83 | // ------------------------ 84 | const startFinderDocumentScanner = async () => { 85 | if (!(await ScanbotSDKService.checkLicense())) { return; } 86 | 87 | const configs: FinderDocumentScannerConfiguration = { 88 | // Customize colors, text resources, behavior, etc.. 89 | cameraPreviewMode: 'FILL_IN', 90 | interfaceOrientation: 'PORTRAIT', 91 | ignoreBadAspectRatio: true, 92 | topBarBackgroundColor: '#c8193c', 93 | finderEnabled: true, 94 | finderAspectRatio: { width: 4, height: 3 } 95 | // see further configs ... 96 | }; 97 | try { 98 | const finderDocumentScannerResults = await ScanbotSDKService.SDK.UI.startFinderDocumentScanner({ uiConfigs: configs }); 99 | if (finderDocumentScannerResults.status === 'CANCELED') { 100 | await presentAlert({ 101 | header: 'Information', 102 | message: 'Document scanner has been canceled.', 103 | buttons: ['OK'], 104 | }); 105 | return; 106 | } 107 | 108 | await ImageResultsRepository.INSTANCE.addPages([finderDocumentScannerResults.page]); 109 | history.push("/imagepreview"); 110 | } 111 | catch (error) { 112 | console.error(error); 113 | } 114 | } 115 | 116 | // __________________ 117 | // Barcode Scanner 118 | // __________________ 119 | const startBarcodeScanner = async () => { 120 | if (!(await ScanbotSDKService.checkLicense())) { return; } 121 | 122 | const configs: BarcodeScannerConfiguration = { 123 | // Customize colors, text resources, behavior, etc.. 124 | finderTextHint: 'Please align the barcode or QR code in the frame above to scan it.', 125 | interfaceOrientation: 'PORTRAIT', 126 | finderLineColor: '#0000ff', 127 | barcodeFormats: BarcodeRepository.getAcceptedTypes(), // optional filter for specific barcode types 128 | // see further configs ... 129 | }; 130 | try { 131 | const barcodeScannerResults = await ScanbotSDKService.SDK.UI.startBarcodeScanner({ uiConfigs: configs }); 132 | if (barcodeScannerResults.status === 'CANCELED') { 133 | await presentAlert({ 134 | header: 'Information', 135 | message: 'Barcode scanner has been canceled.', 136 | buttons: ['OK'], 137 | }) 138 | return; 139 | } 140 | let barcodeString: string = ''; 141 | barcodeScannerResults.barcodes!.forEach(barcode => { 142 | barcodeString += (barcode.type + ' : ' + barcode.text + '\r\n'); 143 | }); 144 | await presentAlert({ 145 | header: 'Barcode Results', 146 | message: barcodeString, 147 | buttons: ['OK'], 148 | }) 149 | } 150 | catch (error) { 151 | console.error(error); 152 | } 153 | } 154 | 155 | // --------------------- 156 | // BatchBarcode Scanner 157 | // --------------------- 158 | const startBatchBarcodeScanner = async () => { 159 | if (!(await ScanbotSDKService.checkLicense())) { return; } 160 | 161 | const configs: BatchBarcodeScannerConfiguration = { 162 | // Customize colors, text resources, behavior, etc.. 163 | finderTextHint: 'Please align the barcode or QR code in the frame above to scan it.', 164 | interfaceOrientation: 'PORTRAIT', 165 | finderLineColor: '#0000ff', 166 | barcodeFormats: BarcodeRepository.getAcceptedTypes(), // optional filter for specific barcode types 167 | // see further configs ... 168 | }; 169 | try { 170 | const batchBarcodeScannerResults = await ScanbotSDKService.SDK.UI.startBatchBarcodeScanner({ uiConfigs: configs }); 171 | if (batchBarcodeScannerResults.status === 'CANCELED') { 172 | await presentAlert({ 173 | header: 'Information', 174 | message: 'BatchBarcode scanner has been canceled.', 175 | buttons: ['OK'], 176 | }); 177 | return; 178 | } 179 | await BarcodeRepository.addBarcodes(batchBarcodeScannerResults.barcodes!); 180 | history.push("/barcoderesultview"); 181 | } 182 | catch (error) { 183 | console.error(error); 184 | } 185 | } 186 | 187 | // ------------------------------ 188 | // Detect barcodes from an image 189 | // ------------------------------ 190 | const detectBarcodeFromImage = async () => { 191 | if (!(await ScanbotSDKService.checkLicense())) { return; } 192 | 193 | try { 194 | const image = await Camera.getPhoto({ 195 | resultType: CameraResultType.Uri, 196 | source: CameraSource.Photos, 197 | }); 198 | 199 | const originalImageFileUri = image.path!; 200 | await present({ 201 | message: 'Detecting barcodes...', 202 | spinner: 'circles' 203 | }); 204 | const result = await ScanbotSDKService.SDK.detectBarcodesOnImage({ imageFileUri: originalImageFileUri }); 205 | 206 | if (result.status === 'CANCELED') { 207 | await dismiss(); 208 | await presentAlert({ 209 | header: 'Information', 210 | message: 'Barcode detection process canceled.', 211 | buttons: ['OK'], 212 | }); 213 | return; 214 | } 215 | else if (result.barcodes?.length === 0) { 216 | await dismiss(); 217 | await presentAlert({ 218 | header: 'Information', 219 | message: 'No barcodes detected.', 220 | buttons: ['OK'], 221 | }); 222 | return; 223 | } 224 | await dismiss(); 225 | await BarcodeRepository.addBarcodes(result.barcodes!); 226 | history.push("/barcoderesultview"); 227 | } 228 | catch (error) { 229 | console.error(error); 230 | } 231 | } 232 | 233 | // ------------------------------------- 234 | // Detect barcodes from multiple images 235 | // ------------------------------------- 236 | const detectBarcodeFromImages = async () => { 237 | if (!(await ScanbotSDKService.checkLicense())) { return; } 238 | 239 | try { 240 | const barcodes: BarcodeResultField[] = []; 241 | const originalImageFileUrls: string[] = []; 242 | const pickedImageResults = await Camera.pickImages({ 243 | quality: 80, 244 | }); 245 | 246 | pickedImageResults.photos.forEach(photo => { 247 | originalImageFileUrls.push(photo.path!); 248 | }); 249 | await present({ 250 | message: 'Detecting barcodes...', 251 | spinner: 'circles' 252 | }); 253 | const response = await ScanbotSDKService.SDK.detectBarcodesOnImages({ imageFilesUris: originalImageFileUrls }); 254 | if (response.status === 'CANCELED') { 255 | await dismiss(); 256 | await presentAlert({ 257 | header: 'Information', 258 | message: 'Barcode detection process canceled.', 259 | buttons: ['OK'], 260 | }); 261 | return; 262 | } 263 | response.results!.forEach(element => { 264 | element.barcodeResults.forEach(barcode => { 265 | barcodes.push(barcode); 266 | }); 267 | }); 268 | if (barcodes?.length === 0) { 269 | await dismiss(); 270 | await presentAlert({ 271 | header: 'Information', 272 | message: 'No barcodes detected.', 273 | buttons: ['OK'], 274 | }); 275 | return; 276 | } 277 | await BarcodeRepository.addBarcodes(barcodes); 278 | await dismiss(); 279 | history.push("/barcoderesultview"); 280 | } 281 | catch (error) { 282 | console.error(error); 283 | } 284 | } 285 | 286 | // ------------- 287 | // MRZ scanner 288 | // ------------- 289 | const startMRZScanner = async () => { 290 | if (!(await ScanbotSDKService.checkLicense())) { return; } 291 | 292 | try { 293 | const configs: MrzScannerConfiguration = { 294 | // Customize colors, text resources, behavior, etc.. 295 | finderTextHint: 'Please hold your phone over the 2- or 3-line MRZ code at the front of your passport.', 296 | interfaceOrientation: 'PORTRAIT', 297 | // see further configs ... 298 | }; 299 | 300 | if (isPlatform('ios')) { 301 | const widthPx = window.screen.width; 302 | configs.finderWidth = widthPx * 0.9; 303 | configs.finderHeight = widthPx * 0.18; 304 | } 305 | const result = await ScanbotSDKService.SDK.UI.startMrzScanner({ uiConfigs: configs }); 306 | if (result.status === 'CANCELED') { 307 | await presentAlert({ 308 | header: 'Information', 309 | message: 'MRZ scanner canceled.', 310 | buttons: ['OK'], 311 | }); 312 | return; 313 | } 314 | let mrzResultString: string = ''; 315 | result.mrzResult?.fields.forEach(element => { 316 | mrzResultString += (element.name + " : " + element.value + "\r\n"); 317 | }); 318 | await presentAlert({ 319 | header: 'MRZ Results', 320 | message: mrzResultString, 321 | buttons: ['OK'], 322 | }); 323 | } 324 | catch (error) { 325 | console.error(error); 326 | } 327 | } 328 | 329 | // -------------- 330 | // Check Scanner 331 | // -------------- 332 | const startCheckScanner = async () => { 333 | if (!(await ScanbotSDKService.checkLicense())) { return; } 334 | 335 | try { 336 | const configs: CheckRecognizerConfiguration = { 337 | // Customize colors, text resources, behavior, etc.. 338 | enableCameraButtonTitle: 'Enable Camera', 339 | interfaceOrientation: 'PORTRAIT', 340 | finderLineColor: '#0000ff', 341 | // see further configs ... 342 | }; 343 | const checkResult = await ScanbotSDKService.SDK.UI.startCheckRecognizer({ uiConfigs: configs }); 344 | if (checkResult.status === 'CANCELED') { 345 | await presentAlert({ 346 | header: 'Information', 347 | message: 'Check scanner canceled.', 348 | buttons: ['OK'], 349 | }); 350 | return; 351 | } 352 | await presentAlert({ 353 | header: 'Check Result', 354 | message: JSON.stringify(checkResult), 355 | buttons: ['OK'], 356 | }); 357 | } 358 | catch (error) { 359 | console.error(error); 360 | } 361 | } 362 | 363 | // ------------------ 364 | // EHIC Card Scanner 365 | // ------------------ 366 | const startEHICCardScanner = async () => { 367 | if (!(await ScanbotSDKService.checkLicense())) { return; } 368 | 369 | try { 370 | const configs: HealthInsuranceCardScannerConfiguration = { 371 | // Customize colors, text resources, behavior, etc.. 372 | finderTextHint: 'Please hold your phone over the back of your Health Insurance Card.', 373 | interfaceOrientation: 'PORTRAIT', 374 | // see further configs ... 375 | }; 376 | const ehicResult = await ScanbotSDKService.SDK.UI.startEHICScanner({ uiConfigs: configs }); 377 | if (ehicResult.status === 'CANCELED') { 378 | await presentAlert({ 379 | header: 'Information', 380 | message: 'EHIC Scanner canceled.', 381 | buttons: ['OK'], 382 | }); 383 | return; 384 | } 385 | await presentAlert({ 386 | header: 'EHIC Results', 387 | message: JSON.stringify(ehicResult), 388 | buttons: ['OK'], 389 | }); 390 | } 391 | catch (error) { 392 | console.error(error); 393 | } 394 | } 395 | 396 | // ------------- 397 | // Data Scanner 398 | // ------------- 399 | const startDataScanner = async () => { 400 | if (!(await ScanbotSDKService.checkLicense())) { return; } 401 | 402 | try { 403 | const uiConfigs: DataScannerConfiguration = { 404 | // Customize colors, text resources, behavior, etc.. 405 | cancelButtonTitle: 'Cancel', 406 | topBarBackgroundColor: '#c8193c', 407 | topBarButtonsColor: '#ffffff', 408 | finderLineColor: '#c8193c', 409 | interfaceOrientation: 'PORTRAIT', 410 | // see further configs... 411 | }; 412 | const scannerStep: TextDataScannerStep = { 413 | textFilterStrategy: 'DOCUMENT', 414 | guidanceText: 'Place the text line in the frame to scan it', 415 | // an optional pattern can be used to validate scanned text and get better OCR results 416 | // '?' for any character, '#' for any digit, all other characters represent themselves. 417 | //pattern: '', 418 | }; 419 | const dataScannerResult = await ScanbotSDKService.SDK.UI.startDataScanner({ uiConfigs, scannerStep }); 420 | if (dataScannerResult.status === 'CANCELED') { 421 | await presentAlert({ 422 | header: 'Information', 423 | message: 'Data scanner canceled.', 424 | buttons: ['OK'], 425 | }); 426 | return; 427 | } 428 | await presentAlert({ 429 | header: 'Data Scanner Results', 430 | message: JSON.stringify(dataScannerResult), 431 | buttons: ['OK'], 432 | }); 433 | } 434 | catch (error) { 435 | console.error(error); 436 | } 437 | } 438 | 439 | // ---------------------- 440 | // License Plate Scanner 441 | // ---------------------- 442 | const startLicensePlateScanner = async () => { 443 | if (!(await ScanbotSDKService.checkLicense())) { return; } 444 | 445 | try { 446 | const config: LicensePlateScannerConfiguration = { 447 | // Customize colors, text resources, behavior, etc.. 448 | detectorMode: 'ML_BASED', 449 | topBarBackgroundColor: '#c8193c', 450 | topBarButtonsColor: '#ffffff', 451 | cancelButtonTitle: 'Cancel', 452 | finderLineColor: '#c8193c', 453 | finderLineWidth: 5, 454 | guidanceText: 'Place the whole license plate in the frame to scan it', 455 | interfaceOrientation: 'PORTRAIT', 456 | confirmationDialogConfirmButtonFilled: true, 457 | // see further configs... 458 | }; 459 | const licensePlateScannerResult = await ScanbotSDKService.SDK.UI.startLicensePlateScanner({ uiConfigs: config }); 460 | if (licensePlateScannerResult.status === 'CANCELED') { 461 | await presentAlert({ 462 | header: 'Information', 463 | message: 'License plate scanner canceled.', 464 | buttons: ['OK'], 465 | }); 466 | return; 467 | } 468 | await presentAlert({ 469 | header: 'License Plate Results', 470 | message: JSON.stringify(licensePlateScannerResult), 471 | buttons: ['OK'], 472 | }); 473 | } 474 | catch (error) { 475 | console.error(error); 476 | } 477 | } 478 | 479 | // ------------------------- 480 | // Generic Document Scanner 481 | // ------------------------- 482 | const startGenericDocumentScanner = async () => { 483 | if (!(await ScanbotSDKService.checkLicense())) { return; } 484 | 485 | try { 486 | const config: GenericDocumentRecognizerConfiguration = { 487 | // Customize colors, text resources, behavior, etc.. 488 | shouldSavePhotoImageInStorage: true, 489 | // see further configs... 490 | }; 491 | const genericDocumentRecognizerResult = await ScanbotSDKService.SDK.UI.startGenericDocumentRecognizer({ uiConfigs: config }); 492 | if (genericDocumentRecognizerResult.status === 'CANCELED') { 493 | await presentAlert({ 494 | header: 'Information', 495 | message: 'Generic document scanner canceled.', 496 | buttons: ['OK'], 497 | }); 498 | return; 499 | } 500 | await presentAlert({ 501 | header: 'Scanner Results', 502 | message: JSON.stringify(genericDocumentRecognizerResult), 503 | buttons: ['OK'], 504 | }); 505 | } 506 | catch (error) { 507 | console.error(error); 508 | } 509 | } 510 | 511 | // ------------------------- 512 | // SDK License Information 513 | // ------------------------- 514 | const viewLicenseInfo = async () => { 515 | const result = await ScanbotSDKService.SDK.getLicenseInfo(); 516 | await presentAlert({ 517 | header: 'License Info', 518 | message: JSON.stringify(result), 519 | buttons: ['OK'], 520 | }); 521 | } 522 | 523 | // ------------------------- 524 | // OCR Confoguaration 525 | // ------------------------- 526 | const viewOcrConfigs = async () => { 527 | const result = await ScanbotSDKService.SDK.getOcrConfigs(); 528 | await presentAlert({ 529 | header: 'OCR Configs', 530 | message: JSON.stringify(result), 531 | buttons: ['OK'], 532 | }); 533 | } 534 | 535 | return ( 536 | 537 | 538 | 539 | Scanbot SDK Example 540 | 541 | 542 | 543 | 544 | 545 | 546 | Document Scanner 547 | 548 | 549 | { await startDocumentScanner(); }}> 550 | Scan Document 551 | 552 | { await startFinderDocumentScanner(); }}> 553 | Finder Document Scanner 554 | 555 | { history.push("/imagepreview"); }}> 556 | View Image Results 557 | 558 | 559 | 560 | 561 | 562 | Barcode Scanner & Detector 563 | 564 | 565 | { await startBarcodeScanner() }}> 566 | Scan QR-/Barcode 567 | 568 | 569 | { await startBatchBarcodeScanner() }}> 570 | Scan Batch of Barcodes 571 | 572 | 573 | { await detectBarcodeFromImage() }}> 574 | Import Image & Detect Barcodes 575 | 576 | 577 | { await detectBarcodeFromImages() }}> 578 | Import Images & Detect Barcodes 579 | 580 | 581 | 582 | 583 | 584 | 585 | Data Detectors 586 | 587 | { await startMRZScanner() }}> 588 | Scan MRZ 589 | 590 | 591 | { await startEHICCardScanner() }}> 592 | Scan Health Insurance Card 593 | 594 | 595 | { await startCheckScanner() }}> 596 | Scan Checks 597 | 598 | 599 | { await startLicensePlateScanner() }}> 600 | Scan License Plate 601 | 602 | 603 | { await startDataScanner() }}> 604 | Scan Data 605 | 606 | 607 | { await startGenericDocumentScanner() }}> 608 | Scan Generic Documents 609 | 610 | 611 | 612 | 613 | 614 | Test Other SDK API Methods 615 | 616 | 617 | { await viewLicenseInfo(); }}> 618 | View License Info 619 | 620 | { await viewOcrConfigs(); }}> 621 | View OCR Configs 622 | 623 | 624 | 625 | Learn More About the Scanbot SDK 626 | 627 | 628 | 629 | 630 | 631 | 632 | ); 633 | }; 634 | 635 | export default Home; 636 | -------------------------------------------------------------------------------- /src/pages/ImageEditView.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | IonContent, 3 | IonHeader, 4 | IonFooter, 5 | IonPage, 6 | IonTitle, 7 | IonToolbar, 8 | IonButton, 9 | IonButtons, 10 | IonBackButton, 11 | IonImg, 12 | useIonAlert, 13 | IonModal, 14 | IonList, 15 | IonItem, 16 | IonLabel, 17 | useIonLoading, 18 | useIonViewWillEnter 19 | } from '@ionic/react'; 20 | 21 | import './styles/ImageEditView.css'; 22 | 23 | import React, { useState, useRef } from 'react'; 24 | import { RouteComponentProps } from 'react-router'; 25 | 26 | import { ImageResultsRepository } from '../utils/ImageRepository'; 27 | 28 | /* Scanbot SDK Service */ 29 | import { ScanbotSDKService } from '../services/ScanbotSDKService'; 30 | 31 | import { ImageFilter, Page } from 'cordova-plugin-scanbot-sdk'; 32 | 33 | interface ImageEditViewIdProps extends RouteComponentProps<{ pageId: string; }> { } 34 | 35 | const ImageEditView: React.FC = ({ match }) => { 36 | const imageFilterList: ImageFilter[] = [ 37 | 'NONE', 38 | 'COLOR_ENHANCED', 39 | 'GRAYSCALE', 40 | 'BINARIZED', 41 | 'COLOR_DOCUMENT', 42 | 'PURE_BINARIZED', 43 | 'BACKGROUND_CLEAN', 44 | 'BLACK_AND_WHITE', 45 | 'OTSU_BINARIZATION', 46 | 'DEEP_BINARIZATION', 47 | 'EDGE_HIGHLIGHT', 48 | 'LOW_LIGHT_BINARIZATION', 49 | 'LOW_LIGHT_BINARIZATION_2', 50 | 'SENSITIVE_BINARIZATION' 51 | ]; 52 | const filterModal = useRef(null); 53 | const [present, dismiss] = useIonLoading(); 54 | const [presentAlert] = useIonAlert(); 55 | const [imageData, setImageData] = useState(''); 56 | const [selectedPage, setSelectedPage] = useState( 57 | ImageResultsRepository.INSTANCE.getPageById(match.params.pageId)! 58 | ); 59 | 60 | useIonViewWillEnter(async () => { 61 | await loadImageData(); 62 | }); 63 | 64 | async function updatePage(page: Page) { 65 | setSelectedPage(page); 66 | await ImageResultsRepository.INSTANCE.updatePage(page); 67 | await loadImageData(); 68 | } 69 | 70 | /* Crop Image */ 71 | async function openCroppingUi() { 72 | if (!(await ScanbotSDKService.checkLicense())) { return; } 73 | 74 | try { 75 | const croppingResult = await ScanbotSDKService.SDK.UI.startCroppingScreen({ 76 | page: selectedPage, 77 | uiConfigs: { 78 | doneButtonTitle: 'Save', 79 | interfaceOrientation: 'PORTRAIT', 80 | topBarBackgroundColor: '#c8193c', 81 | bottomBarBackgroundColor: '#c8193c', 82 | hintTitle: 'Custom hint:\nDrag the dots to the document edges.', 83 | hintTitleColor: '#0000ff' 84 | } 85 | }); 86 | 87 | if (croppingResult.status === "CANCELED") { 88 | await presentAlert({ 89 | header: 'Information', 90 | message: 'Cropping screen cancelled.', 91 | buttons: ['OK'], 92 | }); 93 | return; 94 | } 95 | await updatePage(croppingResult.page!); 96 | } 97 | catch (error) { 98 | console.log(error); 99 | } 100 | } 101 | 102 | /* load image data */ 103 | async function loadImageData() { 104 | if (!(await ScanbotSDKService.checkLicense())) { return; } 105 | 106 | try { 107 | const imgData = await ScanbotSDKService.fetchDataFromUri( 108 | selectedPage.documentPreviewImageFileUri as string 109 | ); 110 | setImageData(imgData); 111 | } 112 | catch (error) { 113 | console.error(error); 114 | } 115 | } 116 | 117 | /* Filter Image */ 118 | async function applyFilter(selectedFilter: ImageFilter) { 119 | filterModal.current?.dismiss(); 120 | 121 | if (!(await ScanbotSDKService.checkLicense())) { return; } 122 | 123 | try { 124 | filterModal.current?.dismiss(); 125 | await present({ 126 | message: 'Loading...', 127 | spinner: 'circles' 128 | }); 129 | const filteredImageResult = await ScanbotSDKService.SDK.applyImageFilterOnPage({ 130 | page: selectedPage, 131 | imageFilter: selectedFilter 132 | }); 133 | await dismiss(); 134 | if (filteredImageResult.status === "CANCELED") { 135 | await presentAlert({ 136 | header: 'Information', 137 | message: 'Image filtering process cancelled.', 138 | buttons: ['OK'], 139 | }); 140 | return; 141 | } 142 | await updatePage(filteredImageResult.page); 143 | } 144 | catch (error) { 145 | await dismiss(); 146 | console.error(error); 147 | } 148 | } 149 | 150 | return ( 151 | 152 | 153 | 154 | 155 | 156 | 157 | Image Edit View 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | openCroppingUi()}>Crop 169 | 170 | 171 | 172 | Filter 173 | 174 | 175 |
176 |

Filter Formats

177 | 178 | {imageFilterList.map((item) => ( 179 | applyFilter(item)}> 180 | {item} 181 | 182 | ))} 183 | 184 |
185 |
186 |
187 |
188 |
189 |
190 | ); 191 | }; 192 | 193 | export default ImageEditView; -------------------------------------------------------------------------------- /src/pages/ImagePreview.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | IonContent, 3 | IonHeader, 4 | IonFooter, 5 | IonPage, 6 | IonTitle, 7 | IonToolbar, 8 | IonBackButton, 9 | IonButtons, 10 | IonButton, 11 | IonImg, 12 | useIonAlert, 13 | useIonViewWillEnter, 14 | IonGrid, 15 | IonRow, 16 | IonCol, 17 | IonModal, 18 | IonList, 19 | IonItem, 20 | IonLabel, 21 | useIonLoading, } from '@ionic/react'; 22 | 23 | import { useHistory } from 'react-router'; 24 | import React, {useState, useRef } from 'react'; 25 | 26 | import { Page, PDFPageSize } from 'cordova-plugin-scanbot-sdk'; 27 | import { ImageResultsRepository } from '../utils/ImageRepository'; 28 | 29 | /* Scanbot SDK Service */ 30 | import { ScanbotSDKService } from '../services/ScanbotSDKService'; 31 | 32 | const ImagePreview: React.FC = () => { 33 | const pdfPageSizeList: PDFPageSize[] = [ 34 | "FROM_IMAGE", 35 | "A4", 36 | "FIXED_A4", 37 | "US_LETTER", 38 | "FIXED_US_LETTER", 39 | "AUTO_LOCALE", 40 | "AUTO" 41 | ]; 42 | const tiffOptions = [ 43 | { 44 | label: "Binarized Images (1-bit)", 45 | binarized: true 46 | }, 47 | { 48 | label: "Color Images", 49 | binarized: false 50 | }, 51 | ]; 52 | 53 | const [presentAlert] = useIonAlert(); 54 | const pdfModal = useRef(null); 55 | const tiffModal = useRef(null); 56 | const [present, dismiss] = useIonLoading(); 57 | const history = useHistory(); 58 | const initialState = useState([]); 59 | const [imageData, setImageData] = initialState; 60 | 61 | const pages: Page[] = ImageResultsRepository.INSTANCE.getPages(); 62 | 63 | useIonViewWillEnter(async () => { 64 | await reloadPages(); 65 | }); 66 | 67 | function hasScannedPages(): boolean { 68 | if (!pages || pages.length === 0) { 69 | alert('No scanned images were found. Please scan at least one page.'); 70 | return false; 71 | } 72 | return true; 73 | } 74 | 75 | /* load scanned documents */ 76 | async function reloadPages() { 77 | if (!(await ScanbotSDKService.checkLicense())) { return; } 78 | if (!hasScannedPages()) { return; } 79 | 80 | try { 81 | for (const page of pages) { 82 | const url = page.documentPreviewImageFileUri as string; 83 | const imageURL = await ScanbotSDKService.fetchDataFromUri(url); 84 | if(imageURL === '' || imageURL === undefined) break; 85 | 86 | setImageData((imageData: any) => [...imageData, {id: page.pageId, url: imageURL}]); 87 | } 88 | } 89 | catch (error) { 90 | console.error(error); 91 | } 92 | } 93 | 94 | /* Navigate to cropping page */ 95 | function navigateToCroppingPage(pageId: string): void { 96 | history.push("/imageeditview/" + pageId); 97 | setImageData(() => initialState) 98 | } 99 | 100 | /* Create PDF */ 101 | async function createPDF(pageSize: PDFPageSize) { 102 | pdfModal.current?.dismiss(); 103 | 104 | if (!(await ScanbotSDKService.checkLicense())) { return; } 105 | if (!hasScannedPages()) { return; } 106 | 107 | try { 108 | await present({ 109 | message: 'Loading...', 110 | spinner: 'circles' 111 | }) 112 | const result = await ScanbotSDKService.SDK.createPdf({ 113 | images: pages.map(p => p.documentImageFileUri!), 114 | pageSize: pageSize 115 | }); 116 | await dismiss(); 117 | if (result.status === "CANCELED") { 118 | await presentAlert({ 119 | header: 'Information', 120 | message: result.message, 121 | buttons: ['OK'], 122 | }); 123 | return; 124 | } 125 | await presentAlert({ 126 | header: 'Success', 127 | message: result.pdfFileUri, 128 | buttons: ['OK'], 129 | }); 130 | } 131 | catch (error) { 132 | await dismiss(); 133 | console.error(error); 134 | } 135 | } 136 | 137 | /* Create TIFF */ 138 | async function createTIFF(binarized: boolean) { 139 | tiffModal.current?.dismiss(); 140 | 141 | if (!(await ScanbotSDKService.checkLicense())) { return; } 142 | if (!hasScannedPages()) { return; } 143 | 144 | try { 145 | await present({ 146 | message: 'Loading...', 147 | spinner: 'circles' 148 | }); 149 | const result = await ScanbotSDKService.SDK.writeTiff({ 150 | images: pages.map(p => p.documentImageFileUri!), 151 | oneBitEncoded: binarized, 152 | dpi: 300, 153 | compression: binarized ? 'CCITT_T6' : 'ADOBE_DEFLATE', 154 | }); 155 | await dismiss(); 156 | if (result.status !== "CANCELED") { 157 | await presentAlert({ 158 | header: 'Success', 159 | message: result.tiffFileUri, 160 | buttons: ['OK'], 161 | }); 162 | } 163 | else { 164 | await presentAlert({ 165 | header: 'Information', 166 | message: result.message, 167 | buttons: ['OK'], 168 | }); 169 | return; 170 | } 171 | } 172 | catch (error) { 173 | await dismiss(); 174 | console.error(error); 175 | } 176 | } 177 | 178 | /* Perform OCR, read text from images */ 179 | async function runOCR() { 180 | if (!(await ScanbotSDKService.checkLicense())) { return; } 181 | if (!hasScannedPages()) { return; } 182 | 183 | try { 184 | await present({ 185 | message: 'Processing...', 186 | spinner: 'circles' 187 | }); 188 | const ocrResult = await ScanbotSDKService.SDK.performOcr({ 189 | images: pages.map(p => p.documentImageFileUri!), 190 | languages: ['en', 'de'], 191 | outputFormat: 'FULL_OCR_RESULT', 192 | }); 193 | await dismiss(); 194 | if (ocrResult.status === 'CANCELED') { 195 | await presentAlert({ 196 | header: 'Information', 197 | message: 'OCR process canceled.', 198 | buttons: ['OK'], 199 | }); 200 | return; 201 | } 202 | await presentAlert({ 203 | header: 'OCR Results', 204 | message: JSON.stringify(ocrResult), 205 | buttons: ['OK'], 206 | }); 207 | } 208 | catch (error) { 209 | await dismiss(); 210 | console.error(error); 211 | } 212 | } 213 | 214 | return ( 215 | 216 | 217 | 218 | 219 | 220 | 221 | Display Images 222 | 223 | 224 | 225 | 226 | 227 | 228 | {imageData.map((page: any) => ( 229 | 230 | navigateToCroppingPage(page.id)} src={page.url} /> 231 | 232 | ))} 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | Create PDF 241 | 242 |
243 |

Page Size

244 | 245 | {pdfPageSizeList.map((item) => ( 246 | createPDF(item)}> 247 | {item} 248 | 249 | ))} 250 | 251 |
252 |
253 | runOCR()}>Run OCR 254 |
255 | 256 | 257 | Create TIFF 258 | 259 |
260 |

Image Type

261 | 262 | {tiffOptions.map((item) => ( 263 | createTIFF(item.binarized)}> 264 | {item.label} 265 | 266 | ))} 267 | 268 |
269 |
270 |
271 |
272 |
273 |
274 | ); 275 | }; 276 | 277 | export default ImagePreview; -------------------------------------------------------------------------------- /src/pages/styles/ImageEditView.css: -------------------------------------------------------------------------------- 1 | ion-modal#example-modal { 2 | --width: fit-content; 3 | --height: fit-content; 4 | --border-radius: 6px; 5 | --box-shadow: 0 28px 48px rgba(0, 0, 0, 0.4); 6 | } 7 | 8 | ion-modal#example-modal h1 { 9 | margin: 20px 20px 10px 20px; 10 | } 11 | 12 | ion-modal#example-modal ion-icon { 13 | margin-right: 6px; 14 | 15 | width: 48px; 16 | height: 48px; 17 | 18 | padding: 4px 0; 19 | 20 | color: #aaaaaa; 21 | } 22 | 23 | ion-modal#example-modal .wrapper { 24 | margin-bottom: 10px; 25 | } -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /src/service-worker.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /* eslint-disable no-restricted-globals */ 3 | 4 | // This service worker can be customized! 5 | // See https://developers.google.com/web/tools/workbox/modules 6 | // for the list of available Workbox modules, or add any other 7 | // code you'd like. 8 | // You can also remove this file if you'd prefer not to use a 9 | // service worker, and the Workbox build step will be skipped. 10 | 11 | import { clientsClaim } from 'workbox-core'; 12 | import { ExpirationPlugin } from 'workbox-expiration'; 13 | import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching'; 14 | import { registerRoute } from 'workbox-routing'; 15 | import { StaleWhileRevalidate } from 'workbox-strategies'; 16 | 17 | declare const self: ServiceWorkerGlobalScope; 18 | 19 | clientsClaim(); 20 | 21 | // Precache all of the assets generated by your build process. 22 | // Their URLs are injected into the manifest variable below. 23 | // This variable must be present somewhere in your service worker file, 24 | // even if you decide not to use precaching. See https://cra.link/PWA 25 | precacheAndRoute(self.__WB_MANIFEST); 26 | 27 | // Set up App Shell-style routing, so that all navigation requests 28 | // are fulfilled with your index.html shell. Learn more at 29 | // https://developers.google.com/web/fundamentals/architecture/app-shell 30 | const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$'); 31 | registerRoute( 32 | // Return false to exempt requests from being fulfilled by index.html. 33 | ({ request, url }: { request: Request; url: URL }) => { 34 | // If this isn't a navigation, skip. 35 | if (request.mode !== 'navigate') { 36 | return false; 37 | } 38 | 39 | // If this is a URL that starts with /_, skip. 40 | if (url.pathname.startsWith('/_')) { 41 | return false; 42 | } 43 | 44 | // If this looks like a URL for a resource, because it contains 45 | // a file extension, skip. 46 | if (url.pathname.match(fileExtensionRegexp)) { 47 | return false; 48 | } 49 | 50 | // Return true to signal that we want to use the handler. 51 | return true; 52 | }, 53 | createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html') 54 | ); 55 | 56 | // An example runtime caching route for requests that aren't handled by the 57 | // precache, in this case same-origin .png requests like those from in public/ 58 | registerRoute( 59 | // Add in any other file extensions or routing criteria as needed. 60 | ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), 61 | // Customize this strategy as needed, e.g., by changing to CacheFirst. 62 | new StaleWhileRevalidate({ 63 | cacheName: 'images', 64 | plugins: [ 65 | // Ensure that once this runtime cache reaches a maximum size the 66 | // least-recently used images are removed. 67 | new ExpirationPlugin({ maxEntries: 50 }), 68 | ], 69 | }) 70 | ); 71 | 72 | // This allows the web app to trigger skipWaiting via 73 | // registration.waiting.postMessage({type: 'SKIP_WAITING'}) 74 | self.addEventListener('message', (event) => { 75 | if (event.data && event.data.type === 'SKIP_WAITING') { 76 | self.skipWaiting(); 77 | } 78 | }); 79 | 80 | // Any other custom service worker logic can go here. 81 | -------------------------------------------------------------------------------- /src/serviceWorkerRegistration.ts: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://cra.link/PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.0/8 are considered localhost for IPv4. 18 | window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/) 19 | ); 20 | 21 | type Config = { 22 | onSuccess?: (registration: ServiceWorkerRegistration) => void; 23 | onUpdate?: (registration: ServiceWorkerRegistration) => void; 24 | }; 25 | 26 | export function register(config?: Config) { 27 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 28 | // The URL constructor is available in all browsers that support SW. 29 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 30 | if (publicUrl.origin !== window.location.origin) { 31 | // Our service worker won't work if PUBLIC_URL is on a different origin 32 | // from what our page is served on. This might happen if a CDN is used to 33 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 34 | return; 35 | } 36 | 37 | window.addEventListener('load', () => { 38 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 39 | 40 | if (isLocalhost) { 41 | // This is running on localhost. Let's check if a service worker still exists or not. 42 | checkValidServiceWorker(swUrl, config); 43 | 44 | // Add some additional logging to localhost, pointing developers to the 45 | // service worker/PWA documentation. 46 | navigator.serviceWorker.ready.then(() => { 47 | console.log( 48 | 'This web app is being served cache-first by a service ' + 49 | 'worker. To learn more, visit https://cra.link/PWA' 50 | ); 51 | }); 52 | } else { 53 | // Is not localhost. Just register service worker 54 | registerValidSW(swUrl, config); 55 | } 56 | }); 57 | } 58 | } 59 | 60 | function registerValidSW(swUrl: string, config?: Config) { 61 | navigator.serviceWorker 62 | .register(swUrl) 63 | .then((registration) => { 64 | registration.onupdatefound = () => { 65 | const installingWorker = registration.installing; 66 | if (installingWorker == null) { 67 | return; 68 | } 69 | installingWorker.onstatechange = () => { 70 | if (installingWorker.state === 'installed') { 71 | if (navigator.serviceWorker.controller) { 72 | // At this point, the updated precached content has been fetched, 73 | // but the previous service worker will still serve the older 74 | // content until all client tabs are closed. 75 | console.log( 76 | 'New content is available and will be used when all ' + 77 | 'tabs for this page are closed. See https://cra.link/PWA.' 78 | ); 79 | 80 | // Execute callback 81 | if (config && config.onUpdate) { 82 | config.onUpdate(registration); 83 | } 84 | } else { 85 | // At this point, everything has been precached. 86 | // It's the perfect time to display a 87 | // "Content is cached for offline use." message. 88 | console.log('Content is cached for offline use.'); 89 | 90 | // Execute callback 91 | if (config && config.onSuccess) { 92 | config.onSuccess(registration); 93 | } 94 | } 95 | } 96 | }; 97 | }; 98 | }) 99 | .catch((error) => { 100 | console.error('Error during service worker registration:', error); 101 | }); 102 | } 103 | 104 | function checkValidServiceWorker(swUrl: string, config?: Config) { 105 | // Check if the service worker can be found. If it can't reload the page. 106 | fetch(swUrl, { 107 | headers: { 'Service-Worker': 'script' }, 108 | }) 109 | .then((response) => { 110 | // Ensure service worker exists, and that we really are getting a JS file. 111 | const contentType = response.headers.get('content-type'); 112 | if ( 113 | response.status === 404 || 114 | (contentType != null && contentType.indexOf('javascript') === -1) 115 | ) { 116 | // No service worker found. Probably a different app. Reload the page. 117 | navigator.serviceWorker.ready.then((registration) => { 118 | registration.unregister().then(() => { 119 | window.location.reload(); 120 | }); 121 | }); 122 | } else { 123 | // Service worker found. Proceed as normal. 124 | registerValidSW(swUrl, config); 125 | } 126 | }) 127 | .catch(() => { 128 | console.log('No internet connection found. App is running in offline mode.'); 129 | }); 130 | } 131 | 132 | export function unregister() { 133 | if ('serviceWorker' in navigator) { 134 | navigator.serviceWorker.ready 135 | .then((registration) => { 136 | registration.unregister(); 137 | }) 138 | .catch((error) => { 139 | console.error(error.message); 140 | }); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/services/ScanbotSDKService.tsx: -------------------------------------------------------------------------------- 1 | /* Scanbot SDK */ 2 | import ScanbotSdk from 'cordova-plugin-scanbot-sdk'; 3 | 4 | export class ScanbotSDKService { 5 | public static SDK = ScanbotSdk.promisify!(); 6 | private static ImageExtension: String = 'JPG'; 7 | 8 | public static async checkLicense() { 9 | const result = await this.SDK.getLicenseInfo(); 10 | if (result.info.isLicenseValid) { 11 | // OK - we have a trial session, a valid trial license or valid production license. 12 | return true; 13 | } 14 | console.log(JSON.stringify(result)); 15 | alert('Scanbot SDK (trial) license has expired!'); 16 | return false; 17 | } 18 | 19 | public static async fetchDataFromUri(path: string): Promise { 20 | const result = await this.SDK.getImageData({ imageFileUri: path }); 21 | // ScanbotSDK return the raw base64 data. Add prefix to convert it to a dataUri 22 | return `data:image/${(ScanbotSDKService.ImageExtension)};base64,` + result.base64ImageData; 23 | } 24 | } -------------------------------------------------------------------------------- /src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | 7 | // Mock matchmedia 8 | window.matchMedia = window.matchMedia || function() { 9 | return { 10 | matches: false, 11 | addListener: function() {}, 12 | removeListener: function() {} 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /src/theme/variables.css: -------------------------------------------------------------------------------- 1 | /* Ionic Variables and Theming. For more info, please see: 2 | http://ionicframework.com/docs/theming/ */ 3 | 4 | /** Ionic CSS Variables **/ 5 | :root { 6 | /** primary **/ 7 | --ion-color-primary: #c8193c; 8 | --ion-color-primary-rgb: 56, 128, 255; 9 | --ion-color-primary-contrast: #ffffff; 10 | --ion-color-primary-contrast-rgb: 255, 255, 255; 11 | --ion-color-primary-shade: #3171e0; 12 | --ion-color-primary-tint: #4c8dff; 13 | 14 | /** secondary **/ 15 | --ion-color-secondary: #3dc2ff; 16 | --ion-color-secondary-rgb: 61, 194, 255; 17 | --ion-color-secondary-contrast: #ffffff; 18 | --ion-color-secondary-contrast-rgb: 255, 255, 255; 19 | --ion-color-secondary-shade: #36abe0; 20 | --ion-color-secondary-tint: #50c8ff; 21 | 22 | /** tertiary **/ 23 | --ion-color-tertiary: #5260ff; 24 | --ion-color-tertiary-rgb: 82, 96, 255; 25 | --ion-color-tertiary-contrast: #ffffff; 26 | --ion-color-tertiary-contrast-rgb: 255, 255, 255; 27 | --ion-color-tertiary-shade: #4854e0; 28 | --ion-color-tertiary-tint: #6370ff; 29 | 30 | /** success **/ 31 | --ion-color-success: #2dd36f; 32 | --ion-color-success-rgb: 45, 211, 111; 33 | --ion-color-success-contrast: #ffffff; 34 | --ion-color-success-contrast-rgb: 255, 255, 255; 35 | --ion-color-success-shade: #28ba62; 36 | --ion-color-success-tint: #42d77d; 37 | 38 | /** warning **/ 39 | --ion-color-warning: #ffc409; 40 | --ion-color-warning-rgb: 255, 196, 9; 41 | --ion-color-warning-contrast: #000000; 42 | --ion-color-warning-contrast-rgb: 0, 0, 0; 43 | --ion-color-warning-shade: #e0ac08; 44 | --ion-color-warning-tint: #ffca22; 45 | 46 | /** danger **/ 47 | --ion-color-danger: #eb445a; 48 | --ion-color-danger-rgb: 235, 68, 90; 49 | --ion-color-danger-contrast: #ffffff; 50 | --ion-color-danger-contrast-rgb: 255, 255, 255; 51 | --ion-color-danger-shade: #cf3c4f; 52 | --ion-color-danger-tint: #ed576b; 53 | 54 | /** dark **/ 55 | --ion-color-dark: #222428; 56 | --ion-color-dark-rgb: 34, 36, 40; 57 | --ion-color-dark-contrast: #ffffff; 58 | --ion-color-dark-contrast-rgb: 255, 255, 255; 59 | --ion-color-dark-shade: #1e2023; 60 | --ion-color-dark-tint: #383a3e; 61 | 62 | /** medium **/ 63 | --ion-color-medium: #92949c; 64 | --ion-color-medium-rgb: 146, 148, 156; 65 | --ion-color-medium-contrast: #ffffff; 66 | --ion-color-medium-contrast-rgb: 255, 255, 255; 67 | --ion-color-medium-shade: #808289; 68 | --ion-color-medium-tint: #9d9fa6; 69 | 70 | /** light **/ 71 | --ion-color-light: #f4f5f8; 72 | --ion-color-light-rgb: 244, 245, 248; 73 | --ion-color-light-contrast: #000000; 74 | --ion-color-light-contrast-rgb: 0, 0, 0; 75 | --ion-color-light-shade: #d7d8da; 76 | --ion-color-light-tint: #f5f6f9; 77 | } 78 | 79 | @media (prefers-color-scheme: dark) { 80 | /* 81 | * Dark Colors 82 | * ------------------------------------------- 83 | */ 84 | 85 | body { 86 | --ion-color-primary: #428cff; 87 | --ion-color-primary-rgb: 66,140,255; 88 | --ion-color-primary-contrast: #ffffff; 89 | --ion-color-primary-contrast-rgb: 255,255,255; 90 | --ion-color-primary-shade: #3a7be0; 91 | --ion-color-primary-tint: #5598ff; 92 | 93 | --ion-color-secondary: #50c8ff; 94 | --ion-color-secondary-rgb: 80,200,255; 95 | --ion-color-secondary-contrast: #ffffff; 96 | --ion-color-secondary-contrast-rgb: 255,255,255; 97 | --ion-color-secondary-shade: #46b0e0; 98 | --ion-color-secondary-tint: #62ceff; 99 | 100 | --ion-color-tertiary: #6a64ff; 101 | --ion-color-tertiary-rgb: 106,100,255; 102 | --ion-color-tertiary-contrast: #ffffff; 103 | --ion-color-tertiary-contrast-rgb: 255,255,255; 104 | --ion-color-tertiary-shade: #5d58e0; 105 | --ion-color-tertiary-tint: #7974ff; 106 | 107 | --ion-color-success: #2fdf75; 108 | --ion-color-success-rgb: 47,223,117; 109 | --ion-color-success-contrast: #000000; 110 | --ion-color-success-contrast-rgb: 0,0,0; 111 | --ion-color-success-shade: #29c467; 112 | --ion-color-success-tint: #44e283; 113 | 114 | --ion-color-warning: #ffd534; 115 | --ion-color-warning-rgb: 255,213,52; 116 | --ion-color-warning-contrast: #000000; 117 | --ion-color-warning-contrast-rgb: 0,0,0; 118 | --ion-color-warning-shade: #e0bb2e; 119 | --ion-color-warning-tint: #ffd948; 120 | 121 | --ion-color-danger: #ff4961; 122 | --ion-color-danger-rgb: 255,73,97; 123 | --ion-color-danger-contrast: #ffffff; 124 | --ion-color-danger-contrast-rgb: 255,255,255; 125 | --ion-color-danger-shade: #e04055; 126 | --ion-color-danger-tint: #ff5b71; 127 | 128 | --ion-color-dark: #f4f5f8; 129 | --ion-color-dark-rgb: 244,245,248; 130 | --ion-color-dark-contrast: #000000; 131 | --ion-color-dark-contrast-rgb: 0,0,0; 132 | --ion-color-dark-shade: #d7d8da; 133 | --ion-color-dark-tint: #f5f6f9; 134 | 135 | --ion-color-medium: #989aa2; 136 | --ion-color-medium-rgb: 152,154,162; 137 | --ion-color-medium-contrast: #000000; 138 | --ion-color-medium-contrast-rgb: 0,0,0; 139 | --ion-color-medium-shade: #86888f; 140 | --ion-color-medium-tint: #a2a4ab; 141 | 142 | --ion-color-light: #222428; 143 | --ion-color-light-rgb: 34,36,40; 144 | --ion-color-light-contrast: #ffffff; 145 | --ion-color-light-contrast-rgb: 255,255,255; 146 | --ion-color-light-shade: #1e2023; 147 | --ion-color-light-tint: #383a3e; 148 | } 149 | 150 | /* 151 | * iOS Dark Theme 152 | * ------------------------------------------- 153 | */ 154 | 155 | .ios body { 156 | --ion-background-color: #000000; 157 | --ion-background-color-rgb: 0,0,0; 158 | 159 | --ion-text-color: #ffffff; 160 | --ion-text-color-rgb: 255,255,255; 161 | 162 | --ion-color-step-50: #0d0d0d; 163 | --ion-color-step-100: #1a1a1a; 164 | --ion-color-step-150: #262626; 165 | --ion-color-step-200: #333333; 166 | --ion-color-step-250: #404040; 167 | --ion-color-step-300: #4d4d4d; 168 | --ion-color-step-350: #595959; 169 | --ion-color-step-400: #666666; 170 | --ion-color-step-450: #737373; 171 | --ion-color-step-500: #808080; 172 | --ion-color-step-550: #8c8c8c; 173 | --ion-color-step-600: #999999; 174 | --ion-color-step-650: #a6a6a6; 175 | --ion-color-step-700: #b3b3b3; 176 | --ion-color-step-750: #bfbfbf; 177 | --ion-color-step-800: #cccccc; 178 | --ion-color-step-850: #d9d9d9; 179 | --ion-color-step-900: #e6e6e6; 180 | --ion-color-step-950: #f2f2f2; 181 | 182 | --ion-item-background: #000000; 183 | 184 | --ion-card-background: #1c1c1d; 185 | } 186 | 187 | .ios ion-modal { 188 | --ion-background-color: var(--ion-color-step-100); 189 | --ion-toolbar-background: var(--ion-color-step-150); 190 | --ion-toolbar-border-color: var(--ion-color-step-250); 191 | } 192 | 193 | /* 194 | * Material Design Dark Theme 195 | * ------------------------------------------- 196 | */ 197 | 198 | .md body { 199 | --ion-background-color: #121212; 200 | --ion-background-color-rgb: 18,18,18; 201 | 202 | --ion-text-color: #ffffff; 203 | --ion-text-color-rgb: 255,255,255; 204 | 205 | --ion-border-color: #222222; 206 | 207 | --ion-color-step-50: #1e1e1e; 208 | --ion-color-step-100: #2a2a2a; 209 | --ion-color-step-150: #363636; 210 | --ion-color-step-200: #414141; 211 | --ion-color-step-250: #4d4d4d; 212 | --ion-color-step-300: #595959; 213 | --ion-color-step-350: #656565; 214 | --ion-color-step-400: #717171; 215 | --ion-color-step-450: #7d7d7d; 216 | --ion-color-step-500: #898989; 217 | --ion-color-step-550: #949494; 218 | --ion-color-step-600: #a0a0a0; 219 | --ion-color-step-650: #acacac; 220 | --ion-color-step-700: #b8b8b8; 221 | --ion-color-step-750: #c4c4c4; 222 | --ion-color-step-800: #d0d0d0; 223 | --ion-color-step-850: #dbdbdb; 224 | --ion-color-step-900: #e7e7e7; 225 | --ion-color-step-950: #f3f3f3; 226 | 227 | --ion-item-background: #1e1e1e; 228 | 229 | --ion-toolbar-background: #1f1f1f; 230 | 231 | --ion-tab-bar-background: #1f1f1f; 232 | 233 | --ion-card-background: #1e1e1e; 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /src/utils/BarcodeRepository.tsx: -------------------------------------------------------------------------------- 1 | import {BarcodeFormat, BarcodeResultField} from "cordova-plugin-scanbot-sdk"; 2 | 3 | export class BarcodeRepository{ 4 | private static barcodes: BarcodeResultField[] = []; 5 | 6 | public static barcodeFormatList = [ 7 | { key: 'AZTEC', value: true }, 8 | { key: 'CODABAR', value: true }, 9 | { key: 'CODE_39', value: true }, 10 | { key: 'CODE_93', value: true }, 11 | { key: 'CODE_128', value: true }, 12 | { key: 'DATA_MATRIX', value: true }, 13 | { key: 'EAN_8', value: true }, 14 | { key: 'EAN_13', value: true }, 15 | { key: 'ITF', value: true }, 16 | { key: 'PDF_417', value: true }, 17 | { key: 'QR_CODE', value: true }, 18 | { key: 'RSS_14', value: true }, 19 | { key: 'RSS_EXPANDED', value: true }, 20 | { key: 'UPC_A', value: true }, 21 | { key: 'UPC_E', value: true }, 22 | { key: 'MSI_PLESSEY', value: false } 23 | ]; 24 | 25 | public static getAcceptedTypes() { 26 | const result:BarcodeFormat[] = []; 27 | 28 | for (let i = 0; i < BarcodeRepository.barcodeFormatList.length; i++) { 29 | if (BarcodeRepository.barcodeFormatList[i].value) { 30 | result.push(BarcodeRepository.barcodeFormatList[i].key as BarcodeFormat); 31 | } 32 | } 33 | 34 | return result; 35 | } 36 | 37 | public static async addBarcodes(barcodes: BarcodeResultField[]) { 38 | if(this.barcodes.length > 0) this.barcodes = []; 39 | this.barcodes = this.barcodes.concat(barcodes); 40 | } 41 | 42 | public static getBarcodes(): BarcodeResultField[] { 43 | return this.barcodes; 44 | } 45 | } -------------------------------------------------------------------------------- /src/utils/ImageRepository.tsx: -------------------------------------------------------------------------------- 1 | import { Page } from 'cordova-plugin-scanbot-sdk'; 2 | 3 | export class ImageResultsRepository { 4 | 5 | public static INSTANCE = new ImageResultsRepository(); 6 | 7 | private pages: Page[] = []; 8 | 9 | public getPages(): Page[] { 10 | return this.pages; 11 | } 12 | 13 | public getPageById(id: string) { 14 | return this.pages.find(p => p.pageId === id); 15 | } 16 | 17 | public async addPages(pages: Page[]) { 18 | this.pages = this.pages.concat(pages); 19 | } 20 | 21 | public async updatePage(page: Page) { 22 | let replaced = false; 23 | for (let i = 0; i < this.pages.length; ++i) { 24 | if (this.pages[i].pageId === page.pageId) { 25 | this.pages[i] = page; 26 | replaced = true; 27 | break; 28 | } 29 | } 30 | if (!replaced) { 31 | this.pages.push(page); 32 | } 33 | } 34 | 35 | public async removePage(page: Page) { 36 | const index = this.pages.findIndex(p => p.pageId === page.pageId); 37 | if (index > -1) { 38 | this.pages.splice(index, 1); 39 | } 40 | } 41 | 42 | public async removeAllPages() { 43 | this.pages = []; 44 | } 45 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | --------------------------------------------------------------------------------