diff --git a/.github/workflows/capture-sdk.check.yml b/.github/workflows/capture-sdk.check.yml index 060a26990a..cb9f8092ef 100644 --- a/.github/workflows/capture-sdk.check.yml +++ b/.github/workflows/capture-sdk.check.yml @@ -62,6 +62,65 @@ jobs: # name: capture-sdk-unit-test-coverage # path: capture-sdk/sdk/build/jacoco/jacocoHtml + instrumented-test: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: setup java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + cache: 'gradle' + + - name: enable KVM group perms for emulator + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: avd cache + uses: actions/cache@v4 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-x86_64-33-${{ github.ref_name }} + + - name: create avd and generate snapshot for caching + if: steps.avd-cache.outputs.cache-hit != 'true' + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 33 + arch: x86_64 + force-avd-creation: false + emulator-options: -no-window -gpu swiftshader_indirect -no-audio -no-boot-anim -camera-back none + disable-animations: true + script: echo "Generated AVD snapshot for caching." + + - name: run instrumented tests + timeout-minutes: 20 + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 33 + arch: x86_64 + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + script: > + adb uninstall net.gini.android.capture.test ; + ./gradlew capture-sdk:sdk:connectedCheck + + - name: archive instrumented test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: capture-sdk-instrumented-test-results + path: capture-sdk/sdk/build/outputs/androidTest-results/connected + default-network-test: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/merchant-sdk.check.yml b/.github/workflows/merchant-sdk.check.yml new file mode 100644 index 0000000000..1569337013 --- /dev/null +++ b/.github/workflows/merchant-sdk.check.yml @@ -0,0 +1,157 @@ +name: Check Merchant SDK + +on: + push: + paths: + - 'merchant-sdk/**' + - 'health-api-library/**' + - 'core-api-library/**' + - 'gradle/**' + branches: + - '**' + tags-ignore: + - '**' + pull_request: + types: [opened, edited, reopened] + paths: + - 'merchant-sdk/**' + - 'health-api-library/**' + - 'core-api-library/**' + - 'gradle/**' + workflow_call: + secrets: + GINI_MOBILE_TEST_CLIENT_SECRET: + required: true + MERCHANT_SDK_EXAMPLE_APP_KEYSTORE_PASSWORD: + required: true + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: setup java + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' + cache: 'gradle' + + - name: run unit tests + run: ./gradlew merchant-sdk:sdk:testDebugUnitTest + + - name: archive unit test results + if: always() + uses: actions/upload-artifact@v3 + with: + name: merchant-sdk-unit-test-results + path: merchant-sdk/sdk/build/reports/tests + + build-example-app: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + + - uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' + cache: 'gradle' + + - name: build release example app for QA + run: > + ./gradlew merchant-sdk:example-app:assembleQaRelease + -PclientId="gini-mobile-test" + -PclientSecret="${{ secrets.GINI_MOBILE_TEST_CLIENT_SECRET }}" + -PreleaseKeystoreFile="merchant_sdk_example.jks" + -PreleaseKeystorePassword='${{ secrets.MERCHANT_SDK_EXAMPLE_APP_KEYSTORE_PASSWORD }}' + -PreleaseKeyAlias="merchant_sdk_example" + -PreleaseKeyPassword='${{ secrets.MERCHANT_SDK_EXAMPLE_APP_KEYSTORE_PASSWORD }}' + + - name: archive release example app for QA + uses: actions/upload-artifact@v3 + with: + name: merchant-sdk-example-app-qa-release + path: merchant-sdk/example-app/build/outputs/apk/qa/release + + - name: build release example app for production + run: > + ./gradlew merchant-sdk:example-app:assembleProdRelease + -PclientId="gini-mobile-test" + -PclientSecret="${{ secrets.GINI_MOBILE_TEST_CLIENT_SECRET }}" + -PreleaseKeystoreFile="merchant_sdk_example.jks" + -PreleaseKeystorePassword='${{ secrets.MERCHANT_SDK_EXAMPLE_APP_KEYSTORE_PASSWORD }}' + -PreleaseKeyAlias="merchant_sdk_example" + -PreleaseKeyPassword='${{ secrets.MERCHANT_SDK_EXAMPLE_APP_KEYSTORE_PASSWORD }}' + + - name: archive release example app for production + uses: actions/upload-artifact@v3 + with: + name: merchant-sdk-example-app-prod-release + path: merchant-sdk/example-app/build/outputs/apk/prod/release + + android-lint: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + + - uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' + cache: 'gradle' + + - name: run android lint + run: ./gradlew merchant-sdk:sdk:lint + + - name: archive android lint report + uses: actions/upload-artifact@v3 + with: + name: merchant-sdk-android-lint-report + path: merchant-sdk/sdk/build/reports/lint-results*.html + + detekt: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + + - uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' + cache: 'gradle' + + - name: run detekt + run: ./gradlew merchant-sdk:sdk:detekt + + - name: archive detekt report + uses: actions/upload-artifact@v3 + with: + name: merchant-sdk-detekt-report + path: merchant-sdk/sdk/build/reports/detekt/*.html + + ktlint: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + + - uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' + cache: 'gradle' + + - name: run ktlint + run: ./gradlew merchant-sdk:sdk:ktlintCheck + + - name: archive ktlint report + uses: actions/upload-artifact@v3 + with: + name: merchant-sdk-ktlint-report + path: merchant-sdk/sdk/build/reports/ktlint/**/*.html diff --git a/.github/workflows/merchant-sdk.docs.build.yml b/.github/workflows/merchant-sdk.docs.build.yml new file mode 100644 index 0000000000..40fe3e989c --- /dev/null +++ b/.github/workflows/merchant-sdk.docs.build.yml @@ -0,0 +1,55 @@ +name: Build docs for Merchant SDK + +on: + push: + paths: + - 'merchant-sdk/**' + branches: + - '**' + tags-ignore: + - '**' + pull_request: + types: [opened, edited, reopened] + paths: + - 'merchant-sdk/**' + +jobs: + build-docs: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: setup java + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' + cache: 'gradle' + + - name: setup python + uses: actions/setup-python@v4 + with: + python-version: 'pypy2.7' + + - name: setup ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.2.0' + bundler-cache: true + + - name: build documentation + uses: maierj/fastlane-action@v3.0.0 + with: + lane: 'build_documentation' + options: > + { + "project_id": "merchant-sdk", + "module_id": "sdk" + } + + - name: archive documentation + uses: actions/upload-artifact@v3 + with: + name: merchant-sdk-documentation + path: merchant-sdk/sdk/build/docs \ No newline at end of file diff --git a/.github/workflows/merchant-sdk.docs.release.yml b/.github/workflows/merchant-sdk.docs.release.yml new file mode 100644 index 0000000000..1b46426435 --- /dev/null +++ b/.github/workflows/merchant-sdk.docs.release.yml @@ -0,0 +1,75 @@ +name: Release docs for Merchant SDK + +on: + push: + tags: + - 'merchant-sdk;[0-9]+.[0-9]+.[0-9]+;doc**' + - 'merchant-sdk;[0-9]+.[0-9]+.[0-9]+-beta[0-9][0-9];doc**' + workflow_call: + secrets: + RELEASE_GITHUB_USER: + required: true + RELEASE_GITHUB_PASSWORD: + required: true + +jobs: + release-docs: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: get branch name + id: branch + shell: bash + run: | + # Get the branch ref that contains the tag in github.ref + # (github.ref contains the tag because this workflow is triggered by tags: + # https://docs.github.com/en/actions/learn-github-actions/contexts#github-context) + branch_ref=$(git branch -r --contains "${{ github.ref }}") + # Remove "origin/" prefix from branch_ref and trim whitespace + branch_name=$(echo ${branch_ref/origin\/} | tr -d '[:space:]') + echo "::set-output name=branch_name::$branch_name" + echo "branch_name: $branch_name" + + - name: setup java + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' + cache: 'gradle' + + - name: setup python + uses: actions/setup-python@v4 + with: + python-version: 'pypy2.7' + + - name: setup ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.2.0' + bundler-cache: true + + - name: release documentation + uses: maierj/fastlane-action@v3.0.0 + with: + lane: 'release_documentation' + options: > + { + "project_id": "merchant-sdk", + "module_id": "sdk", + "documentation_title": "Gini Merchant SDK for Android", + "is_stable_release": "${{ steps.branch.outputs.branch_name == 'main' }}", + "git_tag": "${{ github.ref }}", + "ci": "true", + "git_user": "${{ secrets.RELEASE_GITHUB_USER }}", + "git_password": "${{ secrets.RELEASE_GITHUB_PASSWORD }}" + } + + - name: archive documentation + uses: actions/upload-artifact@v3 + with: + name: merchant-sdk-documentation + path: merchant-sdk/sdk/build/docs diff --git a/.github/workflows/merchant-sdk.release.snapshots.yml b/.github/workflows/merchant-sdk.release.snapshots.yml new file mode 100644 index 0000000000..91dd655165 --- /dev/null +++ b/.github/workflows/merchant-sdk.release.snapshots.yml @@ -0,0 +1,57 @@ +# Disabled until we find a way to avoid manually appending "-SNAPSHOT" to versions after every release. +# Or we find a way to inject the version as a gradle property ONLY for the module we are releasing. + +# name: Release snapshot of Merchant SDK + +# on: +# pull_request: + +# jobs: +# release-snapshot: +# runs-on: ubuntu-latest +# steps: +# - name: checkout +# uses: actions/checkout@v3 + +# - name: setup java +# uses: actions/setup-java@v3 +# with: +# distribution: 'temurin' +# java-version: '17' +# cache: 'gradle' + +# - name: setup ruby +# uses: ruby/setup-ruby@v1 +# with: +# ruby-version: '3.2.0' +# bundler-cache: true + +# - name: "publish to gini's maven snapshots repo at https://repo.gini.net/nexus/content/repositories/snapshots" +# uses: maierj/fastlane-action@v3.0.0 +# with: +# lane: 'publish_to_maven_snapshots_repo' +# options: > +# { +# "repo_url": "https://repo.gini.net/nexus/content/repositories/snapshots", +# "repo_user": "jenkins", +# "repo_password": "${{ secrets.GINI_EXTERNAL_NEXUS_PASSWORD }}", +# "project_id": "merchant-sdk", +# "module_id": "sdk", +# "signing_key_base64": "${{ secrets.MAVEN_CENTRAL_SIGNING_KEY_BASE64 }}", +# "signing_password": "${{ secrets.MAVEN_CENTRAL_SIGNING_PASSWORD }}" +# } + +# - name: "publish to Maven Central snapshots repo at https://oss.sonatype.org/content/repositories/snapshots/" +# uses: maierj/fastlane-action@v3.0.0 +# with: +# lane: 'publish_to_maven_snapshots_repo' +# options: > +# { +# "repo_url": "https://oss.sonatype.org/content/repositories/snapshots/", +# "repo_user": "alpar.gini", +# "repo_password": "${{ secrets.MAVEN_CENTRAL_PASSWORD }}", +# "project_id": "merchant-sdk", +# "module_id": "sdk", +# "signing_key_base64": "${{ secrets.MAVEN_CENTRAL_SIGNING_KEY_BASE64 }}", +# "signing_password": "${{ secrets.MAVEN_CENTRAL_SIGNING_PASSWORD }}" +# } diff --git a/.github/workflows/merchant-sdk.release.yml b/.github/workflows/merchant-sdk.release.yml new file mode 100644 index 0000000000..53ab8f9968 --- /dev/null +++ b/.github/workflows/merchant-sdk.release.yml @@ -0,0 +1,58 @@ +name: Release Merchant SDK + +on: + push: + tags: + - 'merchant-sdk;[0-9]+.[0-9]+.[0-9]+' + - 'merchant-sdk;[0-9]+.[0-9]+.[0-9]+-beta[0-9][0-9]' + +jobs: + check: + uses: ./.github/workflows/merchant-sdk.check.yml + secrets: + GINI_MOBILE_TEST_CLIENT_SECRET: ${{ secrets.GINI_MOBILE_TEST_CLIENT_SECRET }} + MERCHANT_SDK_EXAMPLE_APP_KEYSTORE_PASSWORD: ${{ secrets.MERCHANT_SDK_EXAMPLE_APP_KEYSTORE_PASSWORD }} + + release: + needs: check + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: setup java + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' + cache: 'gradle' + + - name: setup ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.2.0' + bundler-cache: true + + - name: "publish to Maven Central staging repo at https://oss.sonatype.org/service/local/staging/deploy/maven2/" + uses: maierj/fastlane-action@v3.0.0 + with: + lane: 'publish_to_maven_repo' + options: > + { + "repo_url": "https://oss.sonatype.org/service/local/staging/deploy/maven2/", + "repo_user": "${{ secrets.MAVEN_CENTRAL_USER_TOKEN_USERNAME }}", + "repo_password": "${{ secrets.MAVEN_CENTRAL_USER_TOKEN_PASSWORD }}", + "project_id": "merchant-sdk", + "module_id": "sdk", + "build_number": "${{ github.run_number }}", + "git_tag": "${{ github.ref }}", + "signing_key_base64": "${{ secrets.MAVEN_CENTRAL_SIGNING_KEY_BASE64 }}", + "signing_password": "${{ secrets.MAVEN_CENTRAL_SIGNING_PASSWORD }}" + } + + release-documentation: + needs: release + uses: ./.github/workflows/merchant-sdk.docs.release.yml + secrets: + RELEASE_GITHUB_USER: ${{ secrets.RELEASE_GITHUB_USER }} + RELEASE_GITHUB_PASSWORD: ${{ secrets.RELEASE_GITHUB_PASSWORD }} diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index e6d2cb3dba..0000000000 --- a/Gemfile.lock +++ /dev/null @@ -1,221 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - CFPropertyList (3.0.7) - base64 - nkf - rexml - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) - artifactory (3.0.17) - atomos (0.1.3) - aws-eventstream (1.3.0) - aws-partitions (1.940.0) - aws-sdk-core (3.197.0) - aws-eventstream (~> 1, >= 1.3.0) - aws-partitions (~> 1, >= 1.651.0) - aws-sigv4 (~> 1.8) - jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.83.0) - aws-sdk-core (~> 3, >= 3.197.0) - aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.152.0) - aws-sdk-core (~> 3, >= 3.197.0) - aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.8) - aws-sigv4 (1.8.0) - aws-eventstream (~> 1, >= 1.0.2) - babosa (1.0.4) - base64 (0.2.0) - claide (1.1.0) - colored (1.2) - colored2 (3.1.2) - commander (4.6.0) - highline (~> 2.0.0) - declarative (0.0.20) - digest-crc (0.6.5) - rake (>= 12.0.0, < 14.0.0) - domain_name (0.6.20240107) - dotenv (2.8.1) - emoji_regex (3.2.3) - excon (0.110.0) - faraday (1.10.3) - faraday-em_http (~> 1.0) - faraday-em_synchrony (~> 1.0) - faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0) - faraday-multipart (~> 1.0) - faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.0) - faraday-patron (~> 1.0) - faraday-rack (~> 1.0) - faraday-retry (~> 1.0) - ruby2_keywords (>= 0.0.4) - faraday-cookie_jar (0.0.7) - faraday (>= 0.8.0) - http-cookie (~> 1.0.0) - faraday-em_http (1.0.0) - faraday-em_synchrony (1.0.0) - faraday-excon (1.1.0) - faraday-httpclient (1.0.1) - faraday-multipart (1.0.4) - multipart-post (~> 2) - faraday-net_http (1.0.1) - faraday-net_http_persistent (1.2.0) - faraday-patron (1.0.0) - faraday-rack (1.0.0) - faraday-retry (1.0.3) - faraday_middleware (1.2.0) - faraday (~> 1.0) - fastimage (2.3.1) - fastlane (2.220.0) - CFPropertyList (>= 2.3, < 4.0.0) - addressable (>= 2.8, < 3.0.0) - artifactory (~> 3.0) - aws-sdk-s3 (~> 1.0) - babosa (>= 1.0.3, < 2.0.0) - bundler (>= 1.12.0, < 3.0.0) - colored (~> 1.2) - commander (~> 4.6) - dotenv (>= 2.1.1, < 3.0.0) - emoji_regex (>= 0.1, < 4.0) - excon (>= 0.71.0, < 1.0.0) - faraday (~> 1.0) - faraday-cookie_jar (~> 0.0.6) - faraday_middleware (~> 1.0) - fastimage (>= 2.1.0, < 3.0.0) - gh_inspector (>= 1.1.2, < 2.0.0) - google-apis-androidpublisher_v3 (~> 0.3) - google-apis-playcustomapp_v1 (~> 0.1) - google-cloud-env (>= 1.6.0, < 2.0.0) - google-cloud-storage (~> 1.31) - highline (~> 2.0) - http-cookie (~> 1.0.5) - json (< 3.0.0) - jwt (>= 2.1.0, < 3) - mini_magick (>= 4.9.4, < 5.0.0) - multipart-post (>= 2.0.0, < 3.0.0) - naturally (~> 2.2) - optparse (>= 0.1.1, < 1.0.0) - plist (>= 3.1.0, < 4.0.0) - rubyzip (>= 2.0.0, < 3.0.0) - security (= 0.1.5) - simctl (~> 1.6.3) - terminal-notifier (>= 2.0.0, < 3.0.0) - terminal-table (~> 3) - tty-screen (>= 0.6.3, < 1.0.0) - tty-spinner (>= 0.8.0, < 1.0.0) - word_wrap (~> 1.0.0) - xcodeproj (>= 1.13.0, < 2.0.0) - xcpretty (~> 0.3.0) - xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) - gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.54.0) - google-apis-core (>= 0.11.0, < 2.a) - google-apis-core (0.11.3) - addressable (~> 2.5, >= 2.5.1) - googleauth (>= 0.16.2, < 2.a) - httpclient (>= 2.8.1, < 3.a) - mini_mime (~> 1.0) - representable (~> 3.0) - retriable (>= 2.0, < 4.a) - rexml - google-apis-iamcredentials_v1 (0.17.0) - google-apis-core (>= 0.11.0, < 2.a) - google-apis-playcustomapp_v1 (0.13.0) - google-apis-core (>= 0.11.0, < 2.a) - google-apis-storage_v1 (0.31.0) - google-apis-core (>= 0.11.0, < 2.a) - google-cloud-core (1.7.0) - google-cloud-env (>= 1.0, < 3.a) - google-cloud-errors (~> 1.0) - google-cloud-env (1.6.0) - faraday (>= 0.17.3, < 3.0) - google-cloud-errors (1.4.0) - google-cloud-storage (1.47.0) - addressable (~> 2.8) - digest-crc (~> 0.4) - google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.31.0) - google-cloud-core (~> 1.6) - googleauth (>= 0.16.2, < 2.a) - mini_mime (~> 1.0) - googleauth (1.8.1) - faraday (>= 0.17.3, < 3.a) - jwt (>= 1.4, < 3.0) - multi_json (~> 1.11) - os (>= 0.9, < 2.0) - signet (>= 0.16, < 2.a) - highline (2.0.3) - http-cookie (1.0.6) - domain_name (~> 0.5) - httpclient (2.8.3) - jmespath (1.6.2) - json (2.7.2) - jwt (2.8.1) - base64 - mini_magick (4.12.0) - mini_mime (1.1.5) - multi_json (1.15.0) - multipart-post (2.4.1) - nanaimo (0.3.0) - naturally (2.2.1) - nkf (0.2.0) - optparse (0.5.0) - os (1.1.4) - plist (3.7.1) - public_suffix (5.0.5) - rake (13.2.1) - representable (3.2.0) - declarative (< 0.1.0) - trailblazer-option (>= 0.1.1, < 0.2.0) - uber (< 0.2.0) - retriable (3.1.2) - rexml (3.2.8) - strscan (>= 3.0.9) - rouge (2.0.7) - ruby2_keywords (0.0.5) - rubyzip (2.3.2) - security (0.1.5) - signet (0.19.0) - addressable (~> 2.8) - faraday (>= 0.17.5, < 3.a) - jwt (>= 1.5, < 3.0) - multi_json (~> 1.10) - simctl (1.6.10) - CFPropertyList - naturally - strscan (3.1.0) - terminal-notifier (2.0.0) - terminal-table (3.0.2) - unicode-display_width (>= 1.1.1, < 3) - trailblazer-option (0.1.2) - tty-cursor (0.7.1) - tty-screen (0.8.2) - tty-spinner (0.9.3) - tty-cursor (~> 0.7) - uber (0.1.0) - unicode-display_width (2.5.0) - word_wrap (1.0.0) - xcodeproj (1.24.0) - CFPropertyList (>= 2.3.3, < 4.0) - atomos (~> 0.1.3) - claide (>= 1.0.2, < 2.0) - colored2 (~> 3.1) - nanaimo (~> 0.3.0) - rexml (~> 3.2.4) - xcpretty (0.3.0) - rouge (~> 2.0.7) - xcpretty-travis-formatter (1.0.1) - xcpretty (~> 0.2, >= 0.0.7) - -PLATFORMS - arm64-darwin-21 - x86_64-darwin-20 - x86_64-linux - -DEPENDENCIES - fastlane - -BUNDLED WITH - 2.2.29 diff --git a/RELEASE-ORDER.md b/RELEASE-ORDER.md index a976b7779d..74a7660857 100644 --- a/RELEASE-ORDER.md +++ b/RELEASE-ORDER.md @@ -1,35 +1,40 @@ DO NOT EDIT MANUALLY! Automatically created by the updateReleaseOrderFile task. -Release order for :capture-sdk:sdk 3.10.3: - 1. :capture-sdk:sdk 3.10.3 - -Release order for :core-api-library:library 2.1.4: - 1. :core-api-library:library 2.1.4 - -Release order for :bank-api-library:library 3.1.3: - 1. :core-api-library:library 2.1.4 - 2. :bank-api-library:library 3.1.3 - -Release order for :health-api-library:library 4.1.0: - 1. :core-api-library:library 2.1.4 - 2. :health-api-library:library 4.1.0 - -Release order for :health-sdk:sdk 4.1.0: - 1. :core-api-library:library 2.1.4 - 2. :health-api-library:library 4.1.0 - 3. :health-sdk:sdk 4.1.0 - -Release order for :capture-sdk:default-network 3.10.3: - 1. :core-api-library:library 2.1.4 - 2. :bank-api-library:library 3.1.3 - 3. :capture-sdk:sdk 3.10.3 - 4. :capture-sdk:default-network 3.10.3 - -Release order for :bank-sdk:sdk 3.11.2: - 1. :core-api-library:library 2.1.4 - 2. :bank-api-library:library 3.1.3 - 3. :capture-sdk:sdk 3.10.3 - 4. :capture-sdk:default-network 3.10.3 - 5. :bank-sdk:sdk 3.11.2 +Release order for :capture-sdk:sdk 3.11.0: + 1. :capture-sdk:sdk 3.11.0 + +Release order for :core-api-library:library 2.2.0: + 1. :core-api-library:library 2.2.0 + +Release order for :bank-api-library:library 3.2.0: + 1. :core-api-library:library 2.2.0 + 2. :bank-api-library:library 3.2.0 + +Release order for :health-api-library:library 4.2.0: + 1. :core-api-library:library 2.2.0 + 2. :health-api-library:library 4.2.0 + +Release order for :health-sdk:sdk 4.2.0: + 1. :core-api-library:library 2.2.0 + 2. :health-api-library:library 4.2.0 + 3. :health-sdk:sdk 4.2.0 + +Release order for :merchant-sdk:sdk 1.0.0: + 1. :core-api-library:library 2.2.0 + 2. :health-api-library:library 4.2.0 + 3. :merchant-sdk:sdk 1.0.0 + +Release order for :capture-sdk:default-network 3.11.0: + 1. :core-api-library:library 2.2.0 + 2. :bank-api-library:library 3.2.0 + 3. :capture-sdk:sdk 3.11.0 + 4. :capture-sdk:default-network 3.11.0 + +Release order for :bank-sdk:sdk 3.12.0: + 1. :core-api-library:library 2.2.0 + 2. :bank-api-library:library 3.2.0 + 3. :capture-sdk:sdk 3.11.0 + 4. :capture-sdk:default-network 3.11.0 + 5. :bank-sdk:sdk 3.12.0 diff --git a/bank-api-library/library/build.gradle.kts b/bank-api-library/library/build.gradle.kts index f98be00893..2a820657cf 100644 --- a/bank-api-library/library/build.gradle.kts +++ b/bank-api-library/library/build.gradle.kts @@ -19,7 +19,8 @@ android { } defaultConfig { minSdk = libs.versions.android.minSdk.get().toInt() - targetSdk = libs.versions.android.targetSdk.get().toInt() + testOptions.targetSdk = libs.versions.android.targetSdk.get().toInt() + lint.targetSdk = libs.versions.android.targetSdk.get().toInt() // Use the test runner with JUnit4 support testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" @@ -113,7 +114,7 @@ tasks.register("injectTestProperties") { doFirst { propertiesMap.clear() - propertiesMap.putAll(readLocalPropertiesToMap(project, + propertiesMap.putAll(readLocalPropertiesToMapSilent(project, listOf("testClientId", "testClientSecret", "testApiUri", "testUserCenterUri", "testHealthApiUri"))) } diff --git a/bank-api-library/library/gradle.properties b/bank-api-library/library/gradle.properties index a5fa91765e..bd9803510d 100644 --- a/bank-api-library/library/gradle.properties +++ b/bank-api-library/library/gradle.properties @@ -1,7 +1,7 @@ # Maven coordinates # groupId is in the root gradle.properties artifactId=gini-bank-api-lib -version=3.1.3 +version=3.2.0 # Version code is visible only in the generated BuildConfig file versionCode=0 diff --git a/bank-api-library/library/src/doc/source/guides/getting-started.rst b/bank-api-library/library/src/doc/source/guides/getting-started.rst index 81c9b41c38..8f5f62fc40 100644 --- a/bank-api-library/library/src/doc/source/guides/getting-started.rst +++ b/bank-api-library/library/src/doc/source/guides/getting-started.rst @@ -13,7 +13,7 @@ build.gradle: .. code-block:: groovy dependencies { - implementation 'net.gini.android:gini-bank-api-lib:3.1.2' + implementation 'net.gini.android:gini-bank-api-lib:3.2.0' } Integrating the Gini Bank API Library diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentManager.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentManager.kt index 251cc4cc90..edf1714b71 100644 --- a/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentManager.kt +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentManager.kt @@ -1,5 +1,7 @@ package net.gini.android.bank.api; +import net.gini.android.bank.api.models.AmplitudeRoot +import net.gini.android.bank.api.models.Configuration import net.gini.android.bank.api.models.ExtractionsContainer import net.gini.android.bank.api.models.ResolvePaymentInput import net.gini.android.bank.api.models.ResolvedPayment @@ -45,4 +47,11 @@ class BankApiDocumentManager internal constructor(private val documentRepository errorEvent: ErrorEvent ): Resource = documentRepository.logErrorEvent(errorEvent) + + + suspend fun getConfigurations(): Resource = + documentRepository.getConfigurations() + + suspend fun sendEvents(amplitudeRoot: AmplitudeRoot): Resource = + documentRepository.sendEvents(amplitudeRoot) } diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentRemoteSource.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentRemoteSource.kt index 86c40bdfb1..8511971ddd 100644 --- a/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentRemoteSource.kt +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentRemoteSource.kt @@ -1,11 +1,14 @@ package net.gini.android.bank.api import kotlinx.coroutines.withContext +import net.gini.android.bank.api.models.Configuration import net.gini.android.bank.api.models.ResolvePaymentInput import net.gini.android.bank.api.models.ResolvedPayment import net.gini.android.bank.api.models.toResolvedPayment import net.gini.android.bank.api.requests.ErrorEvent +import net.gini.android.bank.api.requests.toAmplitudeRequestBody import net.gini.android.bank.api.requests.toResolvePaymentBody +import net.gini.android.bank.api.response.toConfiguration import net.gini.android.core.api.DocumentRemoteSource import net.gini.android.core.api.requests.ApiException import net.gini.android.core.api.requests.SafeApiRequest @@ -34,4 +37,11 @@ class BankApiDocumentRemoteSource internal constructor( documentService.logErrorEvent(bearerHeaderMap(accessToken, contentType = giniApiType.giniJsonMediaType), errorEvent) } } + + suspend fun getConfigurations(accessToken: String): Configuration = withContext(coroutineContext) { + val response = SafeApiRequest.apiRequest { + documentService.getConfigurations(bearerHeaderMap(accessToken, giniApiType.giniJsonMediaType)) + } + response.body()?.toConfiguration() ?: throw ApiException.forResponse("Empty response body", response) + } } diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentRepository.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentRepository.kt index 00d18dd376..c1372df64a 100644 --- a/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentRepository.kt +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentRepository.kt @@ -18,7 +18,8 @@ import org.json.JSONObject class BankApiDocumentRepository( private val documentRemoteSource: BankApiDocumentRemoteSource, sessionManager: SessionManager, - giniApiType: GiniBankApiType + giniApiType: GiniBankApiType, + private val trackingAnalysisRemoteSource: TrackingAnalysisRemoteSource ) : DocumentRepository(documentRemoteSource, sessionManager, giniApiType) { override fun createExtractionsContainer( @@ -26,15 +27,23 @@ class BankApiDocumentRepository( compoundExtractions: Map, responseJSON: JSONObject ): ExtractionsContainer { - val returnReasons: List = parseReturnReason(responseJSON.optJSONArray("returnReasons")) + val returnReasons: List = + parseReturnReason(responseJSON.optJSONArray("returnReasons")) return ExtractionsContainer(specificExtractions, compoundExtractions, returnReasons) } - suspend fun resolvePaymentRequest(requestId: String, resolvePaymentInput: ResolvePaymentInput): Resource = + suspend fun resolvePaymentRequest( + requestId: String, + resolvePaymentInput: ResolvePaymentInput + ): Resource = withAccessToken { accessToken -> wrapInResource { - documentRemoteSource.resolvePaymentRequests(accessToken, requestId, resolvePaymentInput) + documentRemoteSource.resolvePaymentRequests( + accessToken, + requestId, + resolvePaymentInput + ) } } @@ -45,6 +54,19 @@ class BankApiDocumentRepository( } } + suspend fun getConfigurations(): Resource = + withAccessToken { accessToken -> + wrapInResource { + documentRemoteSource.getConfigurations(accessToken) + } + } + + suspend fun sendEvents(amplitudeRoot: AmplitudeRoot): Resource = + wrapInResource { + trackingAnalysisRemoteSource.sendEvents(amplitudeRoot) + } + + @Throws(JSONException::class) private fun parseReturnReason(returnReasonsJson: JSONArray?): List { if (returnReasonsJson == null) { diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentService.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentService.kt index 3fa1130b47..9a84e98527 100644 --- a/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentService.kt +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/BankApiDocumentService.kt @@ -2,6 +2,7 @@ package net.gini.android.bank.api import net.gini.android.bank.api.requests.ErrorEvent import net.gini.android.bank.api.requests.ResolvePaymentBody +import net.gini.android.bank.api.response.ConfigurationResponse import net.gini.android.bank.api.response.ResolvePaymentResponse import net.gini.android.core.api.DocumentService import okhttp3.RequestBody @@ -19,4 +20,7 @@ internal interface BankApiDocumentService: DocumentService { @POST("events/error") suspend fun logErrorEvent(@HeaderMap bearer: Map, @Body errorEvent: ErrorEvent): Response + + @GET("configurations") + suspend fun getConfigurations(@HeaderMap bearer: Map): Response } diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/GiniBankAPIBuilder.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/GiniBankAPIBuilder.kt index 2c66c476d5..cdf03301fa 100644 --- a/bank-api-library/library/src/main/java/net/gini/android/bank/api/GiniBankAPIBuilder.kt +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/GiniBankAPIBuilder.kt @@ -48,7 +48,11 @@ class GiniBankAPIBuilder @JvmOverloads constructor( return BankApiDocumentRemoteSource(Dispatchers.IO, getApiRetrofit().create(BankApiDocumentService::class.java), bankApiType, getApiBaseUrl() ?: "") } + private fun createTrackingAnalysisRemoteSource(): TrackingAnalysisRemoteSource { + return TrackingAnalysisRemoteSource(Dispatchers.IO,getTrackingAnalyticsApiRetrofit().create(TrackingAnalysisService::class.java)) + } + override fun createDocumentRepository(): BankApiDocumentRepository { - return BankApiDocumentRepository(createDocumentRemoteSource(), getSessionManager(), bankApiType) + return BankApiDocumentRepository(createDocumentRemoteSource(), getSessionManager(), bankApiType, createTrackingAnalysisRemoteSource()) } } diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/TrackingAnalysisRemoteSource.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/TrackingAnalysisRemoteSource.kt new file mode 100644 index 0000000000..0a84df8720 --- /dev/null +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/TrackingAnalysisRemoteSource.kt @@ -0,0 +1,24 @@ +package net.gini.android.bank.api + +import kotlinx.coroutines.withContext +import net.gini.android.bank.api.models.AmplitudeRoot +import net.gini.android.bank.api.requests.toAmplitudeRequestBody +import net.gini.android.core.api.requests.SafeApiRequest +import kotlin.coroutines.CoroutineContext + +/** + * Internal use only. + */ +class TrackingAnalysisRemoteSource internal constructor( + private val coroutineContext: CoroutineContext, + private val trackingAnalysisService: TrackingAnalysisService +) { + + suspend fun sendEvents(amplitudeRoot: AmplitudeRoot): Unit = + withContext(coroutineContext) { + SafeApiRequest.apiRequest { + trackingAnalysisService.sendEvents(amplitudeRoot.toAmplitudeRequestBody()) + } + } + +} diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/TrackingAnalysisService.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/TrackingAnalysisService.kt new file mode 100644 index 0000000000..1be0fcc415 --- /dev/null +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/TrackingAnalysisService.kt @@ -0,0 +1,14 @@ +package net.gini.android.bank.api + +import net.gini.android.bank.api.requests.AmplitudeRequestBody +import net.gini.android.core.api.DocumentService +import okhttp3.ResponseBody +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.POST + +internal interface TrackingAnalysisService: DocumentService { + + @POST("/batch") + suspend fun sendEvents(@Body amplitudeBody: AmplitudeRequestBody): Response +} diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/models/AmplitudeEvent.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/models/AmplitudeEvent.kt new file mode 100644 index 0000000000..2ed9c71831 --- /dev/null +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/models/AmplitudeEvent.kt @@ -0,0 +1,28 @@ +package net.gini.android.bank.api.models + +data class AmplitudeRoot( + val apiKey: String, + val events: List, +) + +data class AmplitudeEvent( + val userId: String, + val deviceId: String, + val eventType: String, + val sessionId: String, + val eventId: String, + val time: Long, + val platform: String, + val osVersion: String, + val deviceManufacturer: String, + val deviceBrand: String, + val deviceModel: String, + val versionName: String, + val osName: String, + val carrier: String, + val language: String, + val eventProperties: Map? = null, + val userProperties: Map? = null, +) + + diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/models/Configuration.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/models/Configuration.kt new file mode 100644 index 0000000000..45331cccb6 --- /dev/null +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/models/Configuration.kt @@ -0,0 +1,11 @@ +package net.gini.android.bank.api.models + +data class Configuration( + val clientID: String, + val isUserJourneyAnalyticsEnabled: Boolean, + val isSkontoEnabled: Boolean, + val isReturnAssistantEnabled: Boolean, + val mixpanelToken: String?, + val amplitudeApiKey: String?, + + ) \ No newline at end of file diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/requests/AmplitudeBody.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/requests/AmplitudeBody.kt new file mode 100644 index 0000000000..87b696fcfc --- /dev/null +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/requests/AmplitudeBody.kt @@ -0,0 +1,60 @@ +package net.gini.android.bank.api.requests + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import net.gini.android.bank.api.models.AmplitudeEvent +import net.gini.android.bank.api.models.AmplitudeRoot + +@JsonClass(generateAdapter = true) +data class AmplitudeRequestBody( + @Json(name = "api_key") val apiKey: String, + @Json(name = "events") val events: List, +) + +@JsonClass(generateAdapter = true) +data class AmplitudeEventBody( + @Json(name = "user_id") val userId: String, + @Json(name = "device_id") val deviceId: String, + @Json(name = "event_type") val eventType: String, + @Json(name = "session_id") val sessionId: String, + @Json(name = "event_id") val eventId: String, + @Json(name = "time") val time: Long = 0, + @Json(name = "platform") val platform: String, + @Json(name = "os_version") val osVersion: String, + @Json(name = "device_manufacturer") val deviceManufacturer: String, + @Json(name = "device_brand") val deviceBrand: String, + @Json(name = "device_model") val deviceModel: String, + @Json(name = "version_name") val versionName: String, + @Json(name = "os_name") val osName: String, + @Json(name = "carrier") val carrier: String, + @Json(name = "language") val language: String, + @Json(name = "ip") val ip: String = "\$remote", + @Json(name = "event_properties") val eventProperties: Map? = null, + @Json(name = "user_properties") val userProperties: Map? = null, +) + + +internal fun AmplitudeRoot.toAmplitudeRequestBody() = AmplitudeRequestBody( + apiKey = apiKey, + events = events.map { it.toAmplitudeEventBody() } +) + +internal fun AmplitudeEvent.toAmplitudeEventBody() = AmplitudeEventBody( + userId = userId, + deviceId = deviceId, + eventType = eventType, + sessionId = sessionId, + eventId = eventId, + time = time, + platform = platform, + osVersion = osVersion, + deviceManufacturer = deviceManufacturer, + deviceBrand = deviceBrand, + deviceModel = deviceModel, + versionName = versionName, + osName = osName, + carrier = carrier, + language = language, + eventProperties = eventProperties, + userProperties = userProperties, +) diff --git a/bank-api-library/library/src/main/java/net/gini/android/bank/api/response/ConfigurationResponse.kt b/bank-api-library/library/src/main/java/net/gini/android/bank/api/response/ConfigurationResponse.kt new file mode 100644 index 0000000000..a359832881 --- /dev/null +++ b/bank-api-library/library/src/main/java/net/gini/android/bank/api/response/ConfigurationResponse.kt @@ -0,0 +1,25 @@ +package net.gini.android.bank.api.response + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import net.gini.android.bank.api.models.Configuration + +@JsonClass(generateAdapter = true) +data class ConfigurationResponse( + @Json(name = "clientID") val clientID: String?, + @Json(name = "userJourneyAnalyticsEnabled") val userJourneyAnalyticsEnabled: Boolean?, + @Json(name = "skontoEnabled") val skontoEnabled: Boolean?, + @Json(name = "returnAssistantEnabled") val returnAssistantEnabled: Boolean?, + @Json(name = "mixpanelToken") val mixpanelToken: String?, + @Json(name = "amplitudeApiKey") val amplitudeApiKey: String?, +) + +internal fun ConfigurationResponse.toConfiguration() = Configuration( + clientID = clientID ?: "", + isUserJourneyAnalyticsEnabled = userJourneyAnalyticsEnabled ?: false, + isSkontoEnabled = skontoEnabled ?: false, + isReturnAssistantEnabled = returnAssistantEnabled ?: false, + mixpanelToken = mixpanelToken, + amplitudeApiKey = amplitudeApiKey +) + diff --git a/bank-api-library/library/src/test/java/net/gini/android/bank/api/BankApiDocumentRemoteSourceTest.kt b/bank-api-library/library/src/test/java/net/gini/android/bank/api/BankApiDocumentRemoteSourceTest.kt index f8606e91fa..72cea28a49 100644 --- a/bank-api-library/library/src/test/java/net/gini/android/bank/api/BankApiDocumentRemoteSourceTest.kt +++ b/bank-api-library/library/src/test/java/net/gini/android/bank/api/BankApiDocumentRemoteSourceTest.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.test.runTest import net.gini.android.bank.api.models.ResolvePaymentInput import net.gini.android.bank.api.requests.ErrorEvent import net.gini.android.bank.api.requests.ResolvePaymentBody +import net.gini.android.bank.api.response.ConfigurationResponse import net.gini.android.bank.api.response.ResolvePaymentResponse import net.gini.android.core.api.response.PaymentRequestResponse import net.gini.android.core.api.response.PaymentResponse @@ -110,6 +111,10 @@ class BankApiDocumentRemoteSourceTest { return Response.success(null) } + override suspend fun getConfigurations(bearer: Map): Response { + return Response.success(ConfigurationResponse(null, null, null, null, null, null)) + } + override suspend fun uploadDocument( bearer: Map, bytes: RequestBody, diff --git a/bank-sdk/example-app/README.md b/bank-sdk/example-app/README.md index c5040d2357..cb5563f9ca 100644 --- a/bank-sdk/example-app/README.md +++ b/bank-sdk/example-app/README.md @@ -34,8 +34,8 @@ is used for creating release builds which can be shared with clients while the ` for QA purposes. The difference between `prod` and `qa` is that `qa` allows using custom SSL root certificates for SSL proxies (e.g. Charles Proxy). -Payment Providers for testing Gini Pay Connect and the Health SDK -============================================================== +Payment Providers for testing Gini Pay Connect with the Health SDK or Merchant SDK +================================================================================== Run `bundle exec fastlane install_test_payment_provider_apps` in the repository root to install test payment provider apps on all running emulators and connected devices. You can run `bundle exec fastlane uninstall_test_payment_provider_apps` diff --git a/bank-sdk/example-app/build.gradle.kts b/bank-sdk/example-app/build.gradle.kts index 74dc4eb026..fa6f914f77 100644 --- a/bank-sdk/example-app/build.gradle.kts +++ b/bank-sdk/example-app/build.gradle.kts @@ -98,7 +98,7 @@ android { resValue("string", "gini_api_client_secret", credentials["clientSecret"] ?: "") } release { - isMinifyEnabled = true + isMinifyEnabled = false proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") signingConfig = signingConfigs.getByName("release") diff --git a/bank-sdk/example-app/detekt-baseline.xml b/bank-sdk/example-app/detekt-baseline.xml new file mode 100644 index 0000000000..1fcd660502 --- /dev/null +++ b/bank-sdk/example-app/detekt-baseline.xml @@ -0,0 +1,96 @@ + + + + + CyclomaticComplexMethod:ConfigurationViewModel.kt$ConfigurationViewModel$fun configureGiniBank(context: Context) + EmptyFunctionBlock:CustomOnButtonLoadingIndicatorAdapter.kt$CustomOnButtonLoadingIndicatorAdapter${} + LongMethod:ConfigurationActivity.kt$ConfigurationActivity$private fun setConfigurationFeatures() + LongMethod:ConfigurationActivity.kt$ConfigurationActivity$private fun updateUIWithConfigurationObject(configuration: Configuration) + LongMethod:ConfigurationViewModel.kt$ConfigurationViewModel$fun configureGiniBank(context: Context) + LongParameterList:ClientCaptureSDKFragment.kt$ClientCaptureSDKFragment$(paymentRecipient: String, paymentReference: String, paymentPurpose: String, iban: String, bic: String, amount: Amount ) + MagicNumber:ExtractionsActivity.kt$ExtractionsActivity$0.5f + MagicNumber:MainActivity.kt$MainActivity$600 + MaxLineLength:ClientBankSDKFragment.kt$ClientBankSDKFragment$"Error: ${(result.value as ResultError.Capture).giniCaptureError.errorCode} ${(result.value as ResultError.Capture).giniCaptureError.message}" + MaxLineLength:ClientBankSDKFragment.kt$ClientBankSDKFragment$"Error: ${(result.value as ResultError.FileImport).code} ${(result.value as ResultError.FileImport).message}" + MaxLineLength:ClientCaptureSDKFragment.kt$ClientCaptureSDKFragment$"Error: ${(result.value as ResultError.FileImport).code} ${(result.value as ResultError.FileImport).message}" + MaxLineLength:Configuration.kt$Configuration$// net.gini.android.capture.GiniCapture.Builder#setCameraNavigationBarBottomAdapter → on/off switch to show a custom adapter implementation + MaxLineLength:Configuration.kt$Configuration$// net.gini.android.capture.GiniCapture.Builder#setCustomOnboardingPages → on/off switch to show custom onboarding pages + MaxLineLength:Configuration.kt$Configuration$// net.gini.android.capture.GiniCapture.Builder#setDocumentImportEnabledFileTypes → radio buttons to select an available enum value + MaxLineLength:Configuration.kt$Configuration$// net.gini.android.capture.GiniCapture.Builder#setHelpNavigationBarBottomAdapter → on/off switch to show a custom adapter implementation + MaxLineLength:Configuration.kt$Configuration$// net.gini.android.capture.GiniCapture.Builder#setLoadingIndicatorAdapter → on/off switch to show a custom adapter implementation + MaxLineLength:Configuration.kt$Configuration$// net.gini.android.capture.GiniCapture.Builder#setNavigationBarTopAdapter → on/off switch to show a custom adapter implementation + MaxLineLength:Configuration.kt$Configuration$// net.gini.android.capture.GiniCapture.Builder#setOnButtonLoadingIndicatorAdapter → on/off switch to show a custom adapter implementation + MaxLineLength:Configuration.kt$Configuration$// net.gini.android.capture.GiniCapture.Builder#setOnboardingQRCodeIllustrationAdapter-> on/off switch to show custom adapter with animated illustrations + MaxLineLength:Configuration.kt$Configuration$// net.gini.android.capture.GiniCapture.Builder#setReviewBottomBarNavigationAdapter → on/off switch to show a custom adapter implementation + MaxLineLength:Configuration.kt$Configuration.Companion$fun + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutBottomNavigationToggles.switchCameraScreenCustomBottomNavbar + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutBottomNavigationToggles.switchDigitalInvoiceBottomNavigationBar + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutBottomNavigationToggles.switchDigitalInvoiceHelpBottomNavigationBar + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutBottomNavigationToggles.switchDigitalInvoiceOnboardingBottomNavigationBar + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutBottomNavigationToggles.switchReviewScreenCustomBottomNavbar + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutBottomNavigationToggles.switchShowBottomNavbar.isChecked = configuration.isBottomNavigationBarEnabled + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutBottomNavigationToggles.switchShowHelpScreenCustomBottomNavbar + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutBottomNavigationToggles.switchSkontoCustomBottomNavbar + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutDebugDevelopmentOptionsToggles.switchCustomErrorLogger + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutDebugDevelopmentOptionsToggles.switchCustomErrorLogger.isChecked = configuration.isCustomErrorLoggerEnabled + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutDebugDevelopmentOptionsToggles.switchDisableCameraPermission + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutDebugDevelopmentOptionsToggles.switchGiniErrorLogger.isChecked = configuration.isGiniErrorLoggerEnabled + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutFeatureToggle.toggleBtnFileImportSetup + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutGeneralUiCustomizationToggles.switchButtonsCustomLoadingIndicator + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutGeneralUiCustomizationToggles.switchCustomNavigationController + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutGeneralUiCustomizationToggles.switchCustomNavigationController.isChecked = configuration.isCustomNavBarEnabled + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutOnboardingToggles.switchCustomOnboardingAlignCornersPage + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutOnboardingToggles.switchCustomOnboardingPages.isChecked = configuration.isCustomOnboardingPagesEnabled + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutOnboardingToggles.switchOnboardingScreensAtEveryLaunch + MaxLineLength:ConfigurationActivity.kt$ConfigurationActivity$binding.layoutReturnAssistantToggles.switchDigitalInvoiceOnboardingCustomIllustration + MaxLineLength:ConfigurationViewModel.kt$ConfigurationViewModel$@GiniCaptureNetworkServiceDebugDisabled private val giniCaptureDefaultNetworkServiceDebugDisabled: GiniCaptureDefaultNetworkService + MaxLineLength:ConfigurationViewModel.kt$ConfigurationViewModel$@GiniCaptureNetworkServiceDebugEnabled private val giniCaptureDefaultNetworkServiceDebugEnabled: GiniCaptureDefaultNetworkService + MaxLineLength:ConfigurationViewModel.kt$ConfigurationViewModel$if + MaxLineLength:ConfigurationViewModel.kt$ConfigurationViewModel$networkService = if (configuration.isDebugModeEnabled) giniCaptureDefaultNetworkServiceDebugEnabled else giniCaptureDefaultNetworkServiceDebugDisabled + MaxLineLength:CustomCameraNavigationBarBottomAdapter.kt$CustomCameraNavigationBarBottomAdapter$val binding = CustomCameraNavigationBarBottomBinding.inflate(LayoutInflater.from(container.context), container, false) + MaxLineLength:CustomDigitalInvoiceHelpNavigationBarBottomAdapter.kt$CustomDigitalInvoiceHelpNavigationBarBottomAdapter$val binding = CustomDigitalInvoiceHelpNavigationBarBottomBinding.inflate(LayoutInflater.from(container.context), container, false) + MaxLineLength:CustomDigitalInvoiceNavigationBarBottomAdapter.kt$CustomDigitalInvoiceNavigationBarBottomAdapter$binding = CustomDigitalInvoiceNavigationBarBinding.inflate(LayoutInflater.from(container.context), container, false) + MaxLineLength:CustomDigitalInvoiceOnboardingNavigationBarBottomAdapter.kt$CustomDigitalInvoiceOnboardingNavigationBarBottomAdapter$val binding = CustomDigitalInvoiceOnboardingBottomNavigationBarBinding.inflate(LayoutInflater.from(container.context), container, false) + MaxLineLength:CustomOnboardingNavigationBarBottomAdapter.kt$CustomOnboardingNavigationBarBottomAdapter$OnboardingNavigationBarBottomButton.GET_STARTED -> viewBinding?.buttonGetStarted?.visibility = View.VISIBLE + MaxLineLength:CustomReviewNavigationBarBottomAdapter.kt$CustomReviewNavigationBarBottomAdapter$viewBinding.injectedViewContainerInjectedLoadingIndicatorContainer.injectedViewAdapterHolder + MaxLineLength:DocumentAnalyzer.kt$DocumentAnalyzer$Log.d("gini-api", "Analysis failed for document ${giniApiDocument?.id}: ${extractionsResource!!.message}") + MaxLineLength:ExampleUtil.kt$ExampleUtil$return extractionName == "amountToPay" || extractionName == "bic" || extractionName == "iban" || extractionName == "paymentReference" || extractionName == "paymentRecipient" + MaxLineLength:GiniExampleModule.kt$GiniExampleModule$"Missing Gini API client credentials. Either create a local.properties file " + "with clientId and clientSecret properties or pass them in as gradle " + "parameters with -PclientId and -PclientSecret." + MaxLineLength:MainActivity.kt$MainActivity$"Error: ${(result.value as ResultError.Capture).giniCaptureError.errorCode} ${(result.value as ResultError.Capture).giniCaptureError.message}" + MaxLineLength:MainActivity.kt$MainActivity$"Error: ${(result.value as ResultError.FileImport).code} ${(result.value as ResultError.FileImport).message}" + MaxLineLength:PermissionHandler.kt$PermissionHandler$private + MaxLineLength:SplashActivity.kt$SplashActivity$is GiniBank.CreateDocumentFromImportedFileResult.Error -> showErrorToast("Open with failed with error ${documentCreationResult.error}") + NewLineAtEndOfFile:CaptureFlowHostActivity.kt$net.gini.android.bank.sdk.exampleapp.ui.CaptureFlowHostActivity.kt + NewLineAtEndOfFile:ConfigurationActivity.kt$net.gini.android.bank.sdk.exampleapp.ui.ConfigurationActivity.kt + NewLineAtEndOfFile:ConfigurationViewModel.kt$net.gini.android.bank.sdk.exampleapp.ui.ConfigurationViewModel.kt + NewLineAtEndOfFile:CustomCameraNavigationBarBottomAdapter.kt$net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomCameraNavigationBarBottomAdapter.kt + NewLineAtEndOfFile:CustomDigitalInvoiceNavigationBarBottomAdapter.kt$net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomDigitalInvoiceNavigationBarBottomAdapter.kt + NewLineAtEndOfFile:CustomDigitalInvoiceOnboardingNavigationBarBottomAdapter.kt$net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomDigitalInvoiceOnboardingNavigationBarBottomAdapter.kt + NewLineAtEndOfFile:CustomHelpActivity.kt$net.gini.android.bank.sdk.exampleapp.ui.CustomHelpActivity.kt + NewLineAtEndOfFile:CustomNavigationBarTopAdapter.kt$net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomNavigationBarTopAdapter.kt + NewLineAtEndOfFile:CustomOnButtonLoadingIndicatorAdapter.kt$net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomOnButtonLoadingIndicatorAdapter.kt + NewLineAtEndOfFile:CustomOnboardingIllustrationAdapter.kt$net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomOnboardingIllustrationAdapter.kt + NewLineAtEndOfFile:CustomOnboardingNavigationBarBottomAdapter.kt$net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomOnboardingNavigationBarBottomAdapter.kt + NewLineAtEndOfFile:CustomReviewNavigationBarBottomAdapter.kt$net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomReviewNavigationBarBottomAdapter.kt + NewLineAtEndOfFile:CustomSkontoNavigationBarBottomAdapter.kt$net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomSkontoNavigationBarBottomAdapter.kt + NewLineAtEndOfFile:DocumentAnalyzer.kt$net.gini.android.bank.sdk.exampleapp.core.DocumentAnalyzer.kt + NewLineAtEndOfFile:ExampleApp.kt$net.gini.android.bank.sdk.exampleapp.ExampleApp.kt + NewLineAtEndOfFile:ExampleUtil.kt$net.gini.android.bank.sdk.exampleapp.core.ExampleUtil.kt + NewLineAtEndOfFile:MainActivity.kt$net.gini.android.bank.sdk.exampleapp.ui.MainActivity.kt + NewLineAtEndOfFile:PayViewModel.kt$net.gini.android.bank.sdk.exampleapp.ui.pay.PayViewModel.kt + NewLineAtEndOfFile:PermissionHandler.kt$net.gini.android.bank.sdk.exampleapp.core.PermissionHandler.kt + NewLineAtEndOfFile:ResultWrapper.kt$net.gini.android.bank.sdk.exampleapp.core.ResultWrapper.kt + NewLineAtEndOfFile:SplashActivity.kt$net.gini.android.bank.sdk.exampleapp.ui.SplashActivity.kt + SwallowedException:ExampleApp.kt$ExampleApp$e: IllegalStateException + TooGenericExceptionCaught:PayActivity.kt$PayActivity$t: Throwable + TooGenericExceptionCaught:ResultWrapper.kt$throwable: Throwable + TooManyFunctions:ExtractionsActivity.kt$ExtractionsActivity : AppCompatActivityExtractionsAdapterInterface + TooManyFunctions:MainActivity.kt$MainActivity : AppCompatActivity + UnusedParameter:ExtractionsActivity.kt$ExtractionsActivity$binding: ActivityExtractionsBinding + UnusedPrivateMember:ClientBankSDKFragment.kt$ClientBankSDKFragment$private fun overrideBankSDKConfiguration() + UnusedPrivateMember:ExtractionsActivity.kt$ExtractionsActivity$private fun hideProgressIndicator(binding: ActivityExtractionsBinding) + UnusedPrivateMember:ExtractionsActivity.kt$ExtractionsActivity$private fun showProgressIndicator(binding: ActivityExtractionsBinding) + UnusedPrivateProperty:ClientCaptureSDKFragment.kt$ClientCaptureSDKFragment$val capture = GiniCapture.Builder() .setGiniCaptureNetworkService(networkService) .setFileImportEnabled(true) .setDocumentImportEnabledFileTypes(DocumentImportEnabledFileTypes.PDF_AND_IMAGES) .setQRCodeScanningEnabled(true) .setFlashButtonEnabled(true) .setMultiPageEnabled(true) .build() + UnusedPrivateProperty:MainActivity.kt$MainActivity.Companion$private const val REQUEST_CONFIGURATION = 3 + + diff --git a/bank-sdk/example-app/src/main/AndroidManifest.xml b/bank-sdk/example-app/src/main/AndroidManifest.xml index 806bed0e97..0761fff595 100644 --- a/bank-sdk/example-app/src/main/AndroidManifest.xml +++ b/bank-sdk/example-app/src/main/AndroidManifest.xml @@ -4,7 +4,7 @@ + binding.layoutDebugDevelopmentOptionsToggles.switchDisableCameraPermission.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.disableCameraPermission(isChecked) } @@ -104,21 +104,21 @@ class ConfigurationActivity : AppCompatActivity() { private fun updateUIWithConfigurationObject(configuration: Configuration) { // 0 setup sdk with default configuration - binding.switchSetupSdkWithDefaultConfiguration.isChecked = + binding.layoutFeatureToggle.switchSetupSdkWithDefaultConfiguration.isChecked = configuration.isDefaultSDKConfigurationsEnabled // 1 file import - binding.switchOpenWith.isChecked = configuration.isFileImportEnabled + binding.layoutFeatureToggle.switchOpenWith.isChecked = configuration.isFileImportEnabled // 2 QR code scanning - binding.switchQrCodeScanning.isChecked = configuration.isQrCodeEnabled + binding.layoutFeatureToggle.switchQrCodeScanning.isChecked = configuration.isQrCodeEnabled // 3 only QR code scanning - binding.switchOnlyQRCodeScanning.isChecked = configuration.isOnlyQrCodeEnabled + binding.layoutFeatureToggle.switchOnlyQRCodeScanning.isChecked = configuration.isOnlyQrCodeEnabled // 4 enable multi page - binding.switchMultiPage.isChecked = configuration.isMultiPageEnabled + binding.layoutFeatureToggle.switchMultiPage.isChecked = configuration.isMultiPageEnabled // 5 enable flash toggle - binding.switchDisplayFlashButton.isChecked = configuration.isFlashButtonDisplayed + binding.layoutCameraToggles.switchDisplayFlashButton.isChecked = configuration.isFlashButtonDisplayed // 6 enable flash on by default - binding.switchFlashOnByDefault.isChecked = configuration.isFlashDefaultStateEnabled + binding.layoutCameraToggles.switchFlashOnByDefault.isChecked = configuration.isFlashDefaultStateEnabled // 7 set import document type support val checkButtonId = when (configuration.documentImportEnabledFileTypes) { DocumentImportEnabledFileTypes.NONE -> R.id.btn_fileImportDisabled @@ -126,101 +126,107 @@ class ConfigurationActivity : AppCompatActivity() { DocumentImportEnabledFileTypes.PDF_AND_IMAGES -> R.id.btn_fileImportPdfAndImage else -> R.id.btn_fileImportOnlyPdf } - binding.toggleBtnFileImportSetup.check(checkButtonId) + binding.layoutFeatureToggle.toggleBtnFileImportSetup.check(checkButtonId) // 8 enable bottom navigation bar - binding.switchShowBottomNavbar.isChecked = configuration.isBottomNavigationBarEnabled + binding.layoutBottomNavigationToggles.switchShowBottomNavbar.isChecked = configuration.isBottomNavigationBarEnabled // 9 enable Help screens custom bottom navigation bar - binding.switchShowHelpScreenCustomBottomNavbar.isChecked = + binding.layoutBottomNavigationToggles.switchShowHelpScreenCustomBottomNavbar.isChecked = configuration.isHelpScreensCustomBottomNavBarEnabled // 10 enable camera screens custom bottom navigation bar - binding.switchCameraScreenCustomBottomNavbar.isChecked = + binding.layoutBottomNavigationToggles.switchCameraScreenCustomBottomNavbar.isChecked = configuration.isCameraBottomNavBarEnabled // 11 enable review screens custom bottom navigation bar - binding.switchReviewScreenCustomBottomNavbar.isChecked = + binding.layoutBottomNavigationToggles.switchReviewScreenCustomBottomNavbar.isChecked = configuration.isReviewScreenCustomBottomNavBarEnabled + binding.layoutBottomNavigationToggles.switchSkontoCustomBottomNavbar.isChecked = + configuration.isSkontoCustomNavBarEnabled + // 12 enable image picker screens custom bottom navigation bar -> was implemented on iOS, not needed for Android // 13 enable onboarding screens at first launch - binding.switchOnboardingScreensAtFirstRun.isChecked = + binding.layoutOnboardingToggles.switchOnboardingScreensAtFirstRun.isChecked = configuration.isOnboardingAtFirstRunEnabled // 14 enable onboarding at every launch - binding.switchOnboardingScreensAtEveryLaunch.isChecked = + binding.layoutOnboardingToggles.switchOnboardingScreensAtEveryLaunch.isChecked = configuration.isOnboardingAtEveryLaunchEnabled // 15 enable custom onboarding pages - binding.switchCustomOnboardingPages.isChecked = configuration.isCustomOnboardingPagesEnabled + binding.layoutOnboardingToggles.switchCustomOnboardingPages.isChecked = configuration.isCustomOnboardingPagesEnabled // 16 enable align corners onboarding pages - binding.switchCustomOnboardingAlignCornersPage.isChecked = + binding.layoutOnboardingToggles.switchCustomOnboardingAlignCornersPage.isChecked = configuration.isAlignCornersInCustomOnboardingEnabled // 17 enable lighting in custom onboarding pages - binding.switchCustomOnboardingLightingPage.isChecked = + binding.layoutOnboardingToggles.switchCustomOnboardingLightingPage.isChecked = configuration.isLightingInCustomOnboardingEnabled // 18 enable QR code in custom onboarding pages - binding.switchCustomOnboardingQRCodePage.isChecked = + binding.layoutOnboardingToggles.switchCustomOnboardingQRCodePage.isChecked = configuration.isQRCodeInCustomOnboardingEnabled // 19 enable multi page in custom onboarding pages - binding.switchCustomOnboardingMultiPage.isChecked = + binding.layoutOnboardingToggles.switchCustomOnboardingMultiPage.isChecked = configuration.isMultiPageInCustomOnboardingEnabled // 20 enable custom navigation bar in custom onboarding pages - binding.switchOnboardingCustomNavBar.isChecked = + binding.layoutBottomNavigationToggles.switchOnboardingCustomNavBar.isChecked = configuration.isCustomNavigationBarInCustomOnboardingEnabled // 21 enable button's custom loading indicator - binding.switchButtonsCustomLoadingIndicator.isChecked = + binding.layoutGeneralUiCustomizationToggles.switchButtonsCustomLoadingIndicator.isChecked = configuration.isButtonsCustomLoadingIndicatorEnabled // 22 enable screen's custom loading indicator - binding.switchScreenCustomLoadingIndicator.isChecked = + binding.layoutAnalysisToggles.switchScreenCustomLoadingIndicator.isChecked = configuration.isScreenCustomLoadingIndicatorEnabled // 23 enable supported format help screen - binding.switchSupportedFormatsScreen.isChecked = + binding.layoutHelpToggles.switchSupportedFormatsScreen.isChecked = configuration.isSupportedFormatsHelpScreenEnabled // 24 enable custom help items - binding.switchCustomHelpMenuItems.isChecked = configuration.isCustomHelpItemsEnabled + binding.layoutHelpToggles.switchCustomHelpMenuItems.isChecked = configuration.isCustomHelpItemsEnabled // 25 enable custom navigation bar - binding.switchCustomNavigationController.isChecked = configuration.isCustomNavBarEnabled + binding.layoutGeneralUiCustomizationToggles.switchCustomNavigationController.isChecked = configuration.isCustomNavBarEnabled // 26 enable event tracker - binding.switchEventTracker.isChecked = configuration.isEventTrackerEnabled + binding.layoutFeatureToggle.switchEventTracker.isChecked = configuration.isEventTrackerEnabled // 27 enable Gini error logger - binding.switchGiniErrorLogger.isChecked = configuration.isGiniErrorLoggerEnabled + binding.layoutDebugDevelopmentOptionsToggles.switchGiniErrorLogger.isChecked = configuration.isGiniErrorLoggerEnabled // 28 enable custom error logger - binding.switchCustomErrorLogger.isChecked = configuration.isCustomErrorLoggerEnabled + binding.layoutDebugDevelopmentOptionsToggles.switchCustomErrorLogger.isChecked = configuration.isCustomErrorLoggerEnabled // 29 set imported file size bytes limit - binding.editTextImportedFileSizeBytesLimit.hint = + binding.layoutDebugDevelopmentOptionsToggles.editTextImportedFileSizeBytesLimit.hint = configuration.importedFileSizeBytesLimit.toString() // 31 enable return assistant - binding.switchReturnAssistantFeature.isChecked = configuration.isReturnAssistantEnabled + binding.layoutFeatureToggle.switchReturnAssistantFeature.isChecked = configuration.isReturnAssistantEnabled // 32 enable return reasons dialog - binding.switchReturnReasonsDialog.isChecked = configuration.isReturnReasonsEnabled + binding.layoutReturnAssistantToggles.switchReturnReasonsDialog.isChecked = configuration.isReturnReasonsEnabled // 33 Digital invoice onboarding custom illustration - binding.switchDigitalInvoiceOnboardingCustomIllustration.isChecked = + binding.layoutReturnAssistantToggles.switchDigitalInvoiceOnboardingCustomIllustration.isChecked = configuration.isDigitalInvoiceOnboardingCustomIllustrationEnabled // 34 Digital invoice help bottom navigation bar - binding.switchDigitalInvoiceHelpBottomNavigationBar.isChecked = + binding.layoutBottomNavigationToggles.switchDigitalInvoiceHelpBottomNavigationBar.isChecked = configuration.isDigitalInvoiceHelpBottomNavigationBarEnabled // 35 Digital invoice onboarding bottom navigation bar - binding.switchDigitalInvoiceOnboardingBottomNavigationBar.isChecked = + binding.layoutBottomNavigationToggles.switchDigitalInvoiceOnboardingBottomNavigationBar.isChecked = configuration.isDigitalInvoiceOnboardingBottomNavigationBarEnabled // 36 Digital invoice bottom navigation bar - binding.switchDigitalInvoiceBottomNavigationBar.isChecked = + binding.layoutBottomNavigationToggles.switchDigitalInvoiceBottomNavigationBar.isChecked = configuration.isDigitalInvoiceBottomNavigationBarEnabled // Allow screenshots - binding.switchAllowScreenshots.isChecked = + binding.layoutDebugDevelopmentOptionsToggles.switchAllowScreenshots.isChecked = configuration.isAllowScreenshotsEnabled // 37 Debug mode - binding.switchDebugMode.isChecked = + binding.layoutDebugDevelopmentOptionsToggles.switchDebugMode.isChecked = configuration.isDebugModeEnabled + + // 40 enable skonto + binding.layoutFeatureToggle.switchSkontoFeature.isChecked = configuration.isSkontoEnabled } private fun setConfigurationFeatures() { // 0 setup sdk with default configuration - binding.switchSetupSdkWithDefaultConfiguration.setOnCheckedChangeListener { _, isChecked -> + binding.layoutFeatureToggle.switchSetupSdkWithDefaultConfiguration.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isDefaultSDKConfigurationsEnabled = isChecked @@ -232,7 +238,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 1 file import - binding.switchOpenWith.setOnCheckedChangeListener { _, isChecked -> + binding.layoutFeatureToggle.switchOpenWith.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isFileImportEnabled = isChecked @@ -241,7 +247,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 2 QR code scanning - binding.switchQrCodeScanning.setOnCheckedChangeListener { _, isChecked -> + binding.layoutFeatureToggle.switchQrCodeScanning.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isQrCodeEnabled = isChecked @@ -257,7 +263,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 3 only QR code scanning - binding.switchOnlyQRCodeScanning.setOnCheckedChangeListener { _, isChecked -> + binding.layoutFeatureToggle.switchOnlyQRCodeScanning.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isOnlyQrCodeEnabled = isChecked @@ -272,7 +278,7 @@ class ConfigurationActivity : AppCompatActivity() { } } // 4 enable multi page - binding.switchMultiPage.setOnCheckedChangeListener { _, isChecked -> + binding.layoutFeatureToggle.switchMultiPage.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isMultiPageEnabled = isChecked @@ -280,7 +286,7 @@ class ConfigurationActivity : AppCompatActivity() { ) } // 5 enable flash toggle - binding.switchDisplayFlashButton.setOnCheckedChangeListener { _, isChecked -> + binding.layoutCameraToggles.switchDisplayFlashButton.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isFlashButtonDisplayed = isChecked @@ -295,7 +301,7 @@ class ConfigurationActivity : AppCompatActivity() { } } // 6 enable flash on by default - binding.switchFlashOnByDefault.setOnCheckedChangeListener { _, isChecked -> + binding.layoutCameraToggles.switchFlashOnByDefault.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isFlashDefaultStateEnabled = isChecked @@ -310,7 +316,7 @@ class ConfigurationActivity : AppCompatActivity() { } } // 7 set import document type support - binding.toggleBtnFileImportSetup.addOnButtonCheckedListener { toggleButton, checkedId, isChecked -> + binding.layoutFeatureToggle.toggleBtnFileImportSetup.addOnButtonCheckedListener { toggleButton, checkedId, isChecked -> val checked = toggleButton.checkedButtonId configurationViewModel.setConfiguration( when (checked) { @@ -334,7 +340,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 8 enable bottom navigation bar - binding.switchShowBottomNavbar.setOnCheckedChangeListener { _, isChecked -> + binding.layoutBottomNavigationToggles.switchShowBottomNavbar.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isBottomNavigationBarEnabled = isChecked @@ -343,7 +349,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 9 enable Help screens custom bottom navigation bar - binding.switchShowHelpScreenCustomBottomNavbar.setOnCheckedChangeListener { _, isChecked -> + binding.layoutBottomNavigationToggles.switchShowHelpScreenCustomBottomNavbar.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isHelpScreensCustomBottomNavBarEnabled = isChecked @@ -352,7 +358,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 10 enable camera screens custom bottom navigation bar - binding.switchCameraScreenCustomBottomNavbar.setOnCheckedChangeListener { _, isChecked -> + binding.layoutBottomNavigationToggles.switchCameraScreenCustomBottomNavbar.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isCameraBottomNavBarEnabled = isChecked @@ -361,7 +367,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 11 enable review screens custom bottom navigation bar - binding.switchReviewScreenCustomBottomNavbar.setOnCheckedChangeListener { _, isChecked -> + binding.layoutBottomNavigationToggles.switchReviewScreenCustomBottomNavbar.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isReviewScreenCustomBottomNavBarEnabled = isChecked @@ -369,10 +375,18 @@ class ConfigurationActivity : AppCompatActivity() { ) } + binding.layoutBottomNavigationToggles.switchSkontoCustomBottomNavbar.setOnCheckedChangeListener { _, isChecked -> + configurationViewModel.setConfiguration( + configurationViewModel.configurationFlow.value.copy( + isSkontoCustomNavBarEnabled = isChecked + ) + ) + } + // 12 enable image picker screens custom bottom navigation bar -> was implemented on iOS, not needed for Android // 13 enable onboarding screens at first launch - binding.switchOnboardingScreensAtFirstRun.setOnCheckedChangeListener { _, isChecked -> + binding.layoutOnboardingToggles.switchOnboardingScreensAtFirstRun.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isOnboardingAtFirstRunEnabled = isChecked @@ -381,7 +395,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 14 enable onboarding at every launch - binding.switchOnboardingScreensAtEveryLaunch.setOnCheckedChangeListener { _, isChecked -> + binding.layoutOnboardingToggles.switchOnboardingScreensAtEveryLaunch.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isOnboardingAtEveryLaunchEnabled = isChecked @@ -390,7 +404,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 15 enable custom onboarding pages - binding.switchCustomOnboardingPages.setOnCheckedChangeListener { _, isChecked -> + binding.layoutOnboardingToggles.switchCustomOnboardingPages.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isCustomOnboardingPagesEnabled = isChecked @@ -398,7 +412,7 @@ class ConfigurationActivity : AppCompatActivity() { ) } // 16 enable align corners onboarding pages - binding.switchCustomOnboardingAlignCornersPage.setOnCheckedChangeListener { _, isChecked -> + binding.layoutOnboardingToggles.switchCustomOnboardingAlignCornersPage.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isAlignCornersInCustomOnboardingEnabled = isChecked @@ -406,7 +420,7 @@ class ConfigurationActivity : AppCompatActivity() { ) } // 17 enable lighting in custom onboarding pages - binding.switchCustomOnboardingLightingPage.setOnCheckedChangeListener { _, isChecked -> + binding.layoutOnboardingToggles.switchCustomOnboardingLightingPage.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isLightingInCustomOnboardingEnabled = isChecked @@ -414,15 +428,16 @@ class ConfigurationActivity : AppCompatActivity() { ) } // 18 enable QR code in custom onboarding pages - binding.switchCustomOnboardingQRCodePage.setOnCheckedChangeListener { _, isChecked -> + binding.layoutOnboardingToggles.switchCustomOnboardingQRCodePage.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isQRCodeInCustomOnboardingEnabled = isChecked ) ) } + // 19 enable multi page in custom onboarding pages - binding.switchCustomOnboardingMultiPage.setOnCheckedChangeListener { _, isChecked -> + binding.layoutOnboardingToggles.switchCustomOnboardingMultiPage.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isMultiPageInCustomOnboardingEnabled = isChecked @@ -430,7 +445,7 @@ class ConfigurationActivity : AppCompatActivity() { ) } // 20 enable custom navigation bar in custom onboarding pages - binding.switchOnboardingCustomNavBar.setOnCheckedChangeListener { _, isChecked -> + binding.layoutBottomNavigationToggles.switchOnboardingCustomNavBar.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isCustomNavigationBarInCustomOnboardingEnabled = isChecked @@ -438,7 +453,7 @@ class ConfigurationActivity : AppCompatActivity() { ) } // 21 enable button's custom loading indicator - binding.switchButtonsCustomLoadingIndicator.setOnCheckedChangeListener { _, isChecked -> + binding.layoutGeneralUiCustomizationToggles.switchButtonsCustomLoadingIndicator.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isButtonsCustomLoadingIndicatorEnabled = isChecked @@ -447,7 +462,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 22 enable screen's custom loading indicator - binding.switchScreenCustomLoadingIndicator.setOnCheckedChangeListener { _, isChecked -> + binding.layoutAnalysisToggles.switchScreenCustomLoadingIndicator.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isScreenCustomLoadingIndicatorEnabled = isChecked @@ -456,7 +471,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 23 enable supported format help screen - binding.switchSupportedFormatsScreen.setOnCheckedChangeListener { _, isChecked -> + binding.layoutHelpToggles.switchSupportedFormatsScreen.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isSupportedFormatsHelpScreenEnabled = isChecked @@ -465,7 +480,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 24 enable custom help items - binding.switchCustomHelpMenuItems.setOnCheckedChangeListener { _, isChecked -> + binding.layoutHelpToggles.switchCustomHelpMenuItems.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isCustomHelpItemsEnabled = isChecked @@ -474,7 +489,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 25 enable custom navigation bar - binding.switchCustomNavigationController.setOnCheckedChangeListener { _, isChecked -> + binding.layoutGeneralUiCustomizationToggles.switchCustomNavigationController.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isCustomNavBarEnabled = isChecked @@ -483,7 +498,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 26 enable event tracker - binding.switchEventTracker.setOnCheckedChangeListener { _, isChecked -> + binding.layoutFeatureToggle.switchEventTracker.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isEventTrackerEnabled = isChecked @@ -492,7 +507,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 27 enable Gini error logger - binding.switchGiniErrorLogger.setOnCheckedChangeListener { _, isChecked -> + binding.layoutDebugDevelopmentOptionsToggles.switchGiniErrorLogger.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isGiniErrorLoggerEnabled = isChecked @@ -501,7 +516,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 28 enable custom error logger - binding.switchCustomErrorLogger.setOnCheckedChangeListener { _, isChecked -> + binding.layoutDebugDevelopmentOptionsToggles.switchCustomErrorLogger.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isCustomErrorLoggerEnabled = isChecked @@ -510,7 +525,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 29 set imported file size bytes limit - binding.editTextImportedFileSizeBytesLimit.doAfterTextChanged { + binding.layoutDebugDevelopmentOptionsToggles.editTextImportedFileSizeBytesLimit.doAfterTextChanged { if (it.toString().isNotEmpty()) { configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( @@ -521,7 +536,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 31 enable return assistant - binding.switchReturnAssistantFeature.setOnCheckedChangeListener { _, isChecked -> + binding.layoutFeatureToggle.switchReturnAssistantFeature.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isReturnAssistantEnabled = isChecked @@ -530,7 +545,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 32 enable return reasons dialog - binding.switchReturnReasonsDialog.setOnCheckedChangeListener { _, isChecked -> + binding.layoutReturnAssistantToggles.switchReturnReasonsDialog.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isReturnReasonsEnabled = isChecked @@ -539,7 +554,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 33 Digital invoice onboarding custom illustration - binding.switchDigitalInvoiceOnboardingCustomIllustration.setOnCheckedChangeListener { _, isChecked -> + binding.layoutReturnAssistantToggles.switchDigitalInvoiceOnboardingCustomIllustration.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isDigitalInvoiceOnboardingCustomIllustrationEnabled = isChecked @@ -548,7 +563,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 34 Digital invoice help bottom navigation bar - binding.switchDigitalInvoiceHelpBottomNavigationBar.setOnCheckedChangeListener { _, isChecked -> + binding.layoutBottomNavigationToggles.switchDigitalInvoiceHelpBottomNavigationBar.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isDigitalInvoiceHelpBottomNavigationBarEnabled = isChecked @@ -557,7 +572,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 35 Digital invoice onboarding bottom navigation bar - binding.switchDigitalInvoiceOnboardingBottomNavigationBar.setOnCheckedChangeListener { _, isChecked -> + binding.layoutBottomNavigationToggles.switchDigitalInvoiceOnboardingBottomNavigationBar.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isDigitalInvoiceOnboardingBottomNavigationBarEnabled = isChecked @@ -566,7 +581,7 @@ class ConfigurationActivity : AppCompatActivity() { } // 36 Digital invoice bottom navigation bar - binding.switchDigitalInvoiceBottomNavigationBar.setOnCheckedChangeListener { _, isChecked -> + binding.layoutBottomNavigationToggles.switchDigitalInvoiceBottomNavigationBar.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isDigitalInvoiceBottomNavigationBarEnabled = isChecked @@ -575,7 +590,7 @@ class ConfigurationActivity : AppCompatActivity() { } // Allow screenshots - binding.switchAllowScreenshots.setOnCheckedChangeListener { _, isChecked -> + binding.layoutDebugDevelopmentOptionsToggles.switchAllowScreenshots.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isAllowScreenshotsEnabled = isChecked @@ -584,13 +599,21 @@ class ConfigurationActivity : AppCompatActivity() { } // 37 Debug mode - binding.switchDebugMode.setOnCheckedChangeListener { _, isChecked -> + binding.layoutDebugDevelopmentOptionsToggles.switchDebugMode.setOnCheckedChangeListener { _, isChecked -> configurationViewModel.setConfiguration( configurationViewModel.configurationFlow.value.copy( isDebugModeEnabled = isChecked ) ) } + + binding.layoutFeatureToggle.switchSkontoFeature.setOnCheckedChangeListener { _, isChecked -> + configurationViewModel.setConfiguration( + configurationViewModel.configurationFlow.value.copy( + isSkontoEnabled = isChecked + ) + ) + } } } \ No newline at end of file diff --git a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationViewModel.kt b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationViewModel.kt index e2abeb843b..94475f05c3 100644 --- a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationViewModel.kt +++ b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/ConfigurationViewModel.kt @@ -26,6 +26,7 @@ import net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomOnButtonLoadingInd import net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomOnboardingIllustrationAdapter import net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomOnboardingNavigationBarBottomAdapter import net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomReviewNavigationBarBottomAdapter +import net.gini.android.bank.sdk.exampleapp.ui.adapters.CustomSkontoNavigationBarBottomAdapter import net.gini.android.bank.sdk.exampleapp.ui.data.Configuration import net.gini.android.capture.GiniCaptureDebug import net.gini.android.capture.help.HelpItem @@ -122,7 +123,10 @@ class ConfigurationViewModel @Inject constructor( returnAssistantEnabled = configuration.isReturnAssistantEnabled, // allow screenshots - allowScreenshots = configuration.isAllowScreenshotsEnabled + allowScreenshots = configuration.isAllowScreenshotsEnabled, + + // 40 enable skonto + skontoEnabled = configuration.isSkontoEnabled, ) // 9 enable Help screens custom bottom navigation bar @@ -275,6 +279,12 @@ class ConfigurationViewModel @Inject constructor( CustomDigitalInvoiceHelpNavigationBarBottomAdapter() } + if (configuration.isSkontoCustomNavBarEnabled) { + GiniBank.skontoNavigationBarBottomAdapter = CustomSkontoNavigationBarBottomAdapter() + } else { + GiniBank.skontoNavigationBarBottomAdapter = null + } + // 35 Digital invoice onboarding bottom navigation bar if (configuration.isDigitalInvoiceOnboardingBottomNavigationBarEnabled) { GiniBank.digitalInvoiceOnboardingNavigationBarBottomAdapter = diff --git a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/MainActivity.kt b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/MainActivity.kt index 967e2f8d6a..3b3858c233 100644 --- a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/MainActivity.kt +++ b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/MainActivity.kt @@ -77,7 +77,7 @@ class MainActivity : AppCompatActivity() { cancellationToken?.cancel() } - override fun onNewIntent(intent: Intent?) { + override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) if (intent != null && isIntentActionViewOrSend(intent)) { startGiniBankSdkForOpenWith(intent) diff --git a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/adapters/CustomSkontoNavigationBarBottomAdapter.kt b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/adapters/CustomSkontoNavigationBarBottomAdapter.kt new file mode 100644 index 0000000000..21bea13e37 --- /dev/null +++ b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/adapters/CustomSkontoNavigationBarBottomAdapter.kt @@ -0,0 +1,59 @@ +package net.gini.android.bank.sdk.exampleapp.ui.adapters + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.view.isVisible +import net.gini.android.bank.sdk.capture.skonto.SkontoNavigationBarBottomAdapter +import net.gini.android.bank.sdk.exampleapp.databinding.CustomSkontoNavigationBarBinding + +class CustomSkontoNavigationBarBottomAdapter : SkontoNavigationBarBottomAdapter { + + private var binding: CustomSkontoNavigationBarBinding? = null + + override fun setOnBackClickListener(onClick: () -> Unit) { + binding?.gbsBackBtn?.setOnClickListener { onClick() } + } + + override fun setOnProceedClickListener(onClick: () -> Unit) { + binding?.gbsPay?.setOnClickListener { onClick() } + } + + + override fun onTotalAmountUpdated(amount: String) { + binding?.priceTotal?.text = amount + } + + override fun setOnHelpClickListener(onClick: () -> Unit) { + // Unused now + } + + override fun onSkontoPercentageBadgeUpdated(text: String) { + binding?.discountInfo?.text = text + } + + override fun onSkontoPercentageBadgeVisibilityUpdate(isVisible: Boolean) { + binding?.discountInfo?.isVisible = isVisible + } + + override fun onSkontoSavingsAmountUpdated(text: String) { + binding?.skontoSavingsAmount?.text = text + } + + override fun onSkontoSavingsAmountVisibilityUpdated(isVisible: Boolean) { + binding?.skontoSavingsAmount?.isVisible = isVisible + } + + override fun onCreateView(container: ViewGroup): View { + binding = CustomSkontoNavigationBarBinding.inflate( + LayoutInflater.from(container.context), + container, + false + ) + return binding!!.root + } + + override fun onDestroy() { + binding = null + } +} \ No newline at end of file diff --git a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/data/Configuration.kt b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/data/Configuration.kt index cc40c366fa..4af4125c3e 100644 --- a/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/data/Configuration.kt +++ b/bank-sdk/example-app/src/main/java/net/gini/android/bank/sdk/exampleapp/ui/data/Configuration.kt @@ -154,8 +154,15 @@ data class Configuration( // 37 Debug mode val isDebugModeEnabled: Boolean = true, + // 38 Is Allow Screenshots val isAllowScreenshotsEnabled: Boolean = true, + // 39 Skonto Custom bottom navigation + val isSkontoCustomNavBarEnabled: Boolean = false, + + // 40 enable Skonto + val isSkontoEnabled: Boolean = true, + ) : Parcelable { companion object { @@ -174,7 +181,8 @@ data class Configuration( isSupportedFormatsHelpScreenEnabled = defaultCaptureConfiguration.supportedFormatsHelpScreenEnabled, isGiniErrorLoggerEnabled = defaultCaptureConfiguration.giniErrorLoggerIsOn, isReturnAssistantEnabled = defaultCaptureConfiguration.returnAssistantEnabled, - isAllowScreenshotsEnabled = defaultCaptureConfiguration.allowScreenshots + isAllowScreenshotsEnabled = defaultCaptureConfiguration.allowScreenshots, + isSkontoEnabled = defaultCaptureConfiguration.skontoEnabled ) diff --git a/bank-sdk/example-app/src/main/res/drawable/bg_round_corners.xml b/bank-sdk/example-app/src/main/res/drawable/bg_round_corners.xml new file mode 100644 index 0000000000..bee373f09d --- /dev/null +++ b/bank-sdk/example-app/src/main/res/drawable/bg_round_corners.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/bank-sdk/example-app/src/main/res/layout/activity_configuration.xml b/bank-sdk/example-app/src/main/res/layout/activity_configuration.xml index 845396ef52..3bedeb0241 100644 --- a/bank-sdk/example-app/src/main/res/layout/activity_configuration.xml +++ b/bank-sdk/example-app/src/main/res/layout/activity_configuration.xml @@ -1,557 +1,116 @@ - + - + android:padding="8dp"> + android:text="@string/relaunch_to_use_default_configuration" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -