Compare commits

...

74 Commits

Author SHA1 Message Date
Honza Rychnovský 00db536674
[#1417] Add in-app authentication
* [#1417] Add authentication

- Closes #1417
- Closes #326
- Partially addresses [Electric-Coin-Company/zashi#7] too
- Creates reusable AuthenticationVM component with all necessary logic that reports authentication status to its callers
- Addresses authentication requirements for the Send funds, Delete wallet, Export private data, and Recovery phrase. The App access authentication use case is prepared and can be turned on anytime.
- The new logic also counts with possible future user customization via the app UI of the default on/off states for all implemented authentication use cases
- Send.Confirmation logic simplification
- This also adds the welcome screen (splash) animation to all the app entry points (the app recreation caused by system included)

* Allow unauthenticated access

- In case no authentication method is available on the device

* Build supported authenticators for the device

- Based on the device Android SDK version

* Disable broken screenshot testing

- This is a temporary change until #1448 is addressed

* Changelog update

* Add temporary placeholder screenshot test

To suppress no test error
2024-05-22 15:59:38 +02:00
dependabot[bot] 02e67ae778
Bump actions/checkout from 4.1.5 to 4.1.6 (#1446)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.5 to 4.1.6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](44c2b7a8a4...a5ac7e51b4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-20 17:45:21 +02:00
dependabot[bot] 9fdfcf39dd
Bump google-github-actions/auth from 2.1.2 to 2.1.3 (#1445)
Bumps [google-github-actions/auth](https://github.com/google-github-actions/auth) from 2.1.2 to 2.1.3.
- [Release notes](https://github.com/google-github-actions/auth/releases)
- [Changelog](https://github.com/google-github-actions/auth/blob/main/CHANGELOG.md)
- [Commits](55bd3a7c6e...71fee32a0b)

---
updated-dependencies:
- dependency-name: google-github-actions/auth
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-16 06:44:23 +02:00
Honza Rychnovský 6ee0deeb5c
[#1442] Release Zashi Android version 1.0 (650)
* [#1442] Release Zashi Android version 1.0 (650)

- Closes #1442
- Changelog
2024-05-07 17:02:17 +02:00
Honza Rychnovský a97b71d922
[#1338] Redesign Update-Available screen
- Closes  #1338
- Changelog update
2024-05-07 16:57:45 +02:00
dependabot[bot] b235e0cc82
Bump actions/checkout from 4.1.4 to 4.1.5 (#1439)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.4 to 4.1.5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](0ad4b8fada...44c2b7a8a4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-07 07:00:09 +02:00
Honza Rychnovský 6c3307748a
Improve delete wallet app state reset (#1438) 2024-05-06 19:29:50 +02:00
Honza Rychnovský c3cf711ee6
[#1382] Improve Onboarding screen dynamic height calculation
- Closes #1382
- Changelog update
2024-05-06 18:54:52 +02:00
Honza Rychnovský 5c21a776d5
[#1434] Improve Shielding UX
* [#1434] Improve Shielding UX

- Closes #1434
- Changelog update

* Trigger balances refresh after sending too
2024-05-06 16:33:31 +02:00
Honza Rychnovský 6160554d64
[#1431] Minor UI improvements
* [#1431] Minor UI improvements

- Account - syncing bar vertical paddings too big

* Add missing bottom padding on About

* Changelog update

* Improve OS info in the support email template

* [#1348] Update restore wallet text field copy

Closes #1348
2024-05-03 13:53:10 +02:00
Honza Rychnovský 2828c25c21
[#1350] No message included in transaction
- Closes #1350
2024-05-03 10:15:59 +02:00
Honza Rychnovský e2ddebe47c
[#1429] Deduplicate messages on transaction
- Closes #1429
- Changelog update
2024-05-02 12:53:21 +02:00
Honza Rychnovský 448177c2d1
[#1427] Do not concatenate memos
- Closes #1427
- Changelog update
2024-05-02 12:37:50 +02:00
Honza Rychnovský 09febc6ff1
[#1425] Improve Balances widget loader logic
- Closes #1425
- Changelog update
2024-05-02 12:04:49 +02:00
Honza Rychnovský a1cf59f9b2
[#1407] Add Delete wallet feature
- Closes #1407
- Changelog update
- Link a new snapshot version of the Zcash SDK
2024-05-02 10:07:28 +02:00
Honza Rychnovský eae133f650
[#1405] Release version 1.0 (638)
* Fix server selection in Restore wallet flow

* [#1405] Release version 1.0 (638)

- Closes #1405
- Changleog update
2024-04-26 16:43:27 +02:00
Honza Rychnovský b0ccdef6e3
Fix server selection in Restore wallet flow (#1404) 2024-04-26 16:42:54 +02:00
Honza Rychnovský a95172ad76
[#1402] Release version 1.0 (636) 2024-04-26 13:11:44 +02:00
Honza Rychnovský 9b2bad6f10
Add zec.rocks lightwalletd server options (#1401)
- Default wallet option changed to zec.rocks:443
- Changleog update
2024-04-26 13:02:07 +02:00
dependabot[bot] 9ca5548ca3
Bump gradle/gradle-build-action from 3.3.1 to 3.3.2 (#1400)
Bumps [gradle/gradle-build-action](https://github.com/gradle/gradle-build-action) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/gradle/gradle-build-action/releases)
- [Commits](e2097ccd7e...4c39dd82cd)

---
updated-dependencies:
- dependency-name: gradle/gradle-build-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-26 12:45:38 +02:00
dependabot[bot] 841e0e76d1
Bump gradle/wrapper-validation-action from 3.3.1 to 3.3.2 (#1399)
Bumps [gradle/wrapper-validation-action](https://github.com/gradle/wrapper-validation-action) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/gradle/wrapper-validation-action/releases)
- [Commits](5188e9b552...216d1ad2b3)

---
updated-dependencies:
- dependency-name: gradle/wrapper-validation-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-26 12:45:15 +02:00
dependabot[bot] e1a805fc0a
Bump actions/checkout from 4.1.3 to 4.1.4 (#1398)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.3 to 4.1.4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](1d96c772d1...0ad4b8fada)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-26 12:44:47 +02:00
dependabot[bot] 9ae38c92bc
Bump actions/download-artifact from 4.1.6 to 4.1.7 (#1397)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.1.6 to 4.1.7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](9c19ed7fe5...65a9edc588)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-26 12:44:17 +02:00
Honza Rychnovský b9249d6ebf
[#1395] Release Zashi Android version 1.0 (630)
Closes #1395
2024-04-24 19:05:28 +02:00
Honza Rychnovský 2ac9f5ebd4
Add more servers to the list (#1394)
- 8 more servers added to the list
- Order of servers changed to show default as 1st, custom as 2nd
2024-04-24 18:47:23 +02:00
Honza Rychnovský e0439f0ca9
[#1150] Release Zashi Android v1.0 (628)
- Closes #1150
- Changelog updated
2024-04-23 21:14:19 +02:00
Honza Rychnovský abafc0387f
[#1391] Adopt SDK production v2.1.1
Closes #1391
2024-04-23 20:22:40 +02:00
Honza Rychnovský d9565e68e0
Remove unused resources (#1390) 2024-04-23 18:08:58 +02:00
Honza Rychnovský 45ca274f98
Display only 3 decimals within fee amount (#1387)
- The proper solution will be added with #1047
2024-04-23 13:30:11 +02:00
Honza Rychnovský 66ba050719
Scroll to Send button (#1386) 2024-04-23 13:29:12 +02:00
Honza Rychnovský 1ffbaf986f
[#1284] Rework Scan screen
- Closes #1284
- Closes #423
- Closes #437
- Changelog update
2024-04-23 10:05:15 +02:00
dependabot[bot] 992c1dd197
Bump actions/download-artifact from 4.1.5 to 4.1.6 (#1383)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.1.5 to 4.1.6.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](8caf195ad4...9c19ed7fe5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-23 08:56:57 +02:00
dependabot[bot] 32e68c3d91
Bump actions/upload-artifact from 4.3.2 to 4.3.3 (#1384)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.2 to 4.3.3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](1746f4ab65...65462800fd)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-23 08:46:09 +02:00
Honza Rychnovský dd371348eb
[#372] Improve scrolling on Onboarding
* [#372] Improve scrolling on Onboarding

- Closes #372
- All screens were checked
- The Onboarding screen behavior on very small screens improved
- Tested with Split screen OS feature to emulate a very small screen

* Fixed status and navigation bars height
2024-04-23 08:45:27 +02:00
dependabot[bot] 6ef9d9f02e
Bump actions/checkout from 4.1.2 to 4.1.3 (#1379)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.2 to 4.1.3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](9bb56186c3...1d96c772d1)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-23 08:44:23 +02:00
Honza Rychnovský 551055e65c
[#1291] Balances hint box copy update
Closes #1291
2024-04-23 08:43:48 +02:00
Honza Rychnovský ff2ce3a379
[#1372] Throw if parsing configuration failed
- Closes #1372
- Follow up #1373
2024-04-23 08:43:14 +02:00
Honza Rychnovský 786c8c2cab
[#1371] Improve Balances widget loader logic
- Closes #1371
- This also covers the security audit recommendation: 4.2.14 (App) This comment in WalletSnapshot.kt should be ticketed
2024-04-23 08:42:34 +02:00
Honza Rychnovský fb5d446bab
[#1367] Send 0 funds only within shielded transaction
- Closes #1367
- Plus slightly refactored SendForm composable to two functions
- Changelog update
2024-04-23 08:39:40 +02:00
Honza Rychnovský b00c807df1
[#1190] Add native debug symbols to builds
- Although this build flag is not transitive, and thus it does not cover SDK, it’s still a good approach to have it turned on
- Using the middle path with symbol_table value - this could be changed once needed
2024-04-23 08:38:36 +02:00
dependabot[bot] 533f335038
Bump actions/upload-artifact from 4.3.1 to 4.3.2 (#1366)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.1 to 4.3.2.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](5d5d22a312...1746f4ab65)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-19 09:01:24 +02:00
dependabot[bot] e3fb6083c9
Bump actions/download-artifact from 4.1.4 to 4.1.5 (#1365)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.1.4 to 4.1.5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](c850b930e6...8caf195ad4)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-19 09:00:56 +02:00
dependabot[bot] 681fb6ae85
Bump gradle/wrapper-validation-action from 3.3.0 to 3.3.1 (#1364)
Bumps [gradle/wrapper-validation-action](https://github.com/gradle/wrapper-validation-action) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/gradle/wrapper-validation-action/releases)
- [Commits](460a3ca55f...5188e9b552)

---
updated-dependencies:
- dependency-name: gradle/wrapper-validation-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-19 09:00:17 +02:00
dependabot[bot] 7cc067af49
Bump gradle/gradle-build-action from 3.3.0 to 3.3.1 (#1363)
Bumps [gradle/gradle-build-action](https://github.com/gradle/gradle-build-action) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/gradle/gradle-build-action/releases)
- [Commits](8baac4c8ef...e2097ccd7e)

---
updated-dependencies:
- dependency-name: gradle/gradle-build-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-19 08:59:51 +02:00
Honza Rychnovský 9c9388a695
[#1361] Release 0.2.0 (609) 2024-04-18 14:23:30 +02:00
Honza Rychnovský e92c0b613c
[#1359] Remove fixed US locale
* [#1359]: Use default Locale in PercentDecimal

* Intended use of Local.US

* Use default Locale in Transaction history dates

* Use default Locale in Balance widget

* Use default Locale in Send tests

* Use default Locale in WalletDisplayValues.kt
2024-04-18 13:05:32 +02:00
dependabot[bot] cada044991
Bump clamav/clamav from 1.3.0 to 1.3.1 in /.github/actions/antivirus (#1358)
Bumps clamav/clamav from 1.3.0 to 1.3.1.

---
updated-dependencies:
- dependency-name: clamav/clamav
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-18 08:11:13 +02:00
Honza Rychnovský 895d692588
[#1356] Do not report caught exceptions
- Although GlobalCrashReporter is built primarily as an interface for the locale exceptions reporting using LocalCrashReporter, the FirebaseCrashReporter inherits its reportCaughtException API and provides the ability to report a caught exception to remote crashyltics service. This commit disables this API for FirebaseCrashReporter.
- Closes #1356
2024-04-18 08:10:46 +02:00
Honza Rychnovský 81508f6466
[#1354] Repository restriction regex
- Closes #1354
- The repository regex changed to align with audit findings and still be able to cover both
com.android:signflinger:[version] and com.android.tools:common:[version]
2024-04-18 08:10:28 +02:00
Honza Rychnovský afd47e513e
[#1352] Remove test fixture values ZIP321
- Addresses issue J from the security audit: Payment URI parser uses a test fixture address
- This also removes unused Request screen with its logic and tests
- Closes #1352
2024-04-18 08:10:08 +02:00
Honza Rychnovský 0e6b8f83a0
[#1347] Adopt Zcash SDK 2.1.1-SNAPSHOT
* [#1347] Adopt Zcash SDK 2.1.1-SNAPSHOT

- Closes #1347

* Add missing Progurad rules
2024-04-17 18:30:33 +02:00
dependabot[bot] fc1ce4087d
Bump gradle/gradle-build-action from 3.2.1 to 3.3.0 (#1345)
Bumps [gradle/gradle-build-action](https://github.com/gradle/gradle-build-action) from 3.2.1 to 3.3.0.
- [Release notes](https://github.com/gradle/gradle-build-action/releases)
- [Commits](bdf99f9dad...8baac4c8ef)

---
updated-dependencies:
- dependency-name: gradle/gradle-build-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-15 18:00:05 +02:00
dependabot[bot] 316bc8702a
Bump gradle/wrapper-validation-action from 2.1.3 to 3.3.0 (#1344)
Bumps [gradle/wrapper-validation-action](https://github.com/gradle/wrapper-validation-action) from 2.1.3 to 3.3.0.
- [Release notes](https://github.com/gradle/wrapper-validation-action/releases)
- [Commits](b5418f5a58...460a3ca55f)

---
updated-dependencies:
- dependency-name: gradle/wrapper-validation-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-15 17:59:34 +02:00
Honza Rychnovský dc955d6ee3
[#1342] Dependency update
* [#1342] Bip-39 1.0.8-SNAPSHOT

* Gradle versions 0.51.0

* Ktlint 1.2.1

* Kotlin 1.9.23 + Compose Compiler 1.5.11

* Gradle 8.7

* compose Activity 1.8.2

* AndroidX Annotation 1.7.1

* Test Macrobenchmark 1.2.3

* Compose 1.6.5

* AndroidX Core 1.12.0

* AndroidX Lifecycle 2.7.0

* Uiautomator 2.3.0

* Accompanist Permission 0.34.0

* Firebase Bom 32.8.1

* Google Play Service Plugin 4.4.1 + Firebase CL Tools 4.4.1

* UiAutomater version fix

* Zxing 3.5.3

* Detekt 1.23.6 + Detekt Compose 0.3.15

* Kotlin Immutable Collections 0.3.7

* Emulator Wtf Gradle Plugin 0.16.2

* Changelog update

[skip ci]

* Bip-39 1.0.8

* AGP 8.3.0

* Jacoco 0.8.12
2024-04-15 17:46:49 +02:00
Honza Rychnovský bd8cbcab10
Document encoding of the upload key for Github secrets in deploy action (#1339)
Co-authored-by: Kris Nuttycombe <kris@nutty.land>
2024-04-14 14:27:29 +02:00
Honza Rychnovský 47937ffabc
Show initial restoring dialog (#1335) 2024-04-12 15:02:44 +02:00
Honza Rychnovský cad8e48bf8
[#1319] Restoring state UI in Account and Balances (#1334)
* [#1319] Restoring state UI in Account and Balances

- Closes #1319

* [#1319] Restoring state widget in Account

- Closes #1319

* Add syncing widget to Account while restoring

* Update changelog

Plus reset the previously unreleased app record
2024-04-12 11:55:44 +02:00
Honza Rychnovský bcdf328cb4
Fix shielding state interpretation (#1333) 2024-04-10 14:41:41 +02:00
dependabot[bot] ed34fb1b3a
Bump gradle/wrapper-validation-action from 2.1.2 to 2.1.3 (#1332)
Bumps [gradle/wrapper-validation-action](https://github.com/gradle/wrapper-validation-action) from 2.1.2 to 2.1.3.
- [Release notes](https://github.com/gradle/wrapper-validation-action/releases)
- [Commits](b231772637...b5418f5a58)

---
updated-dependencies:
- dependency-name: gradle/wrapper-validation-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-10 14:38:01 +02:00
Honza Rychnovský c9308546ab
Release 0.2.0 (594) (#1330) 2024-04-09 16:20:17 +02:00
Honza Rychnovský c6aac62070
[#1328] Release 0.2.0 (593)
- Closes #1328
2024-04-09 15:44:15 +02:00
Honza Rychnovský 0d3d0c4d19
[#1263] Statuses of the sync process
- Closes #1263
- Changelog update
2024-04-09 12:19:13 +02:00
dependabot[bot] af92f1b52f
Bump gradle/gradle-build-action from 3.2.0 to 3.2.1 (#1325)
Bumps [gradle/gradle-build-action](https://github.com/gradle/gradle-build-action) from 3.2.0 to 3.2.1.
- [Release notes](https://github.com/gradle/gradle-build-action/releases)
- [Commits](fe59895742...bdf99f9dad)

---
updated-dependencies:
- dependency-name: gradle/gradle-build-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-09 11:42:51 +02:00
Honza Rychnovský bca1c32b8c
[#1264] Handle unavailable AccountBalance
- Closes #1264
- Changelog update
2024-04-08 12:59:03 +02:00
Honza Rychnovský b34d086cc0
Extend shielding state (#1322)
- This adds `ShieldState.Shielded` that helps us keep the correct UI state of the Transparent funds widget after the user starts shielding action
- This also brings little UI improvement in PrimaryButton sizing
2024-04-08 07:49:53 +02:00
Honza Rychnovský 8c027003cc
[#1164] Restoring UI state in TopAppBar
- Closes #1164
- This incorporates the new wallet restoring label into the custom TopAppBar UI component, so it’s accessible from all screens
- This also fixes the adjust brightness feature that previously stayed turned on when the user left to a surrounding tab screen (Send or Balances)
- Changelog update

Move DisableScreenTimeout into the parent HomeView

Persist restoring state

Fix infinite loading trx history UI state

Add New wallet syncing state

This also adds the wallet restoring state into the transaction history state calculation
2024-04-05 13:09:08 +02:00
dependabot[bot] 84c7618037
Bump gradle/gradle-build-action from 3.1.0 to 3.2.0 (#1320)
Bumps [gradle/gradle-build-action](https://github.com/gradle/gradle-build-action) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/gradle/gradle-build-action/releases)
- [Commits](29c0906b64...fe59895742)

---
updated-dependencies:
- dependency-name: gradle/gradle-build-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-05 08:41:15 +02:00
Honza Rychnovský e398af5690
[#1317] Improve balances logic calculation
- Closes #1317
2024-04-03 14:16:51 +02:00
Honza Rychnovský 2c45ab642b
[#1162] Finish expandable trx item UI state
- Closes #1162
- Closes #1237
- Closes #1078
- This removes unused DangerousButton component and its related resources
- It fixes the Collapse button vector icon
- It brings send_failed and receive_failed states into the trx item UI
- It adds the fee part of the expandable item
- Its follow-up is #1047
- Changelog updated
2024-04-03 09:18:46 +02:00
Honza Rychnovský c8a14f0375
[#1312] Display SDK error cause in dialog
* [#1312] Display SDK error cause in dialog

- Closes #1312
- Changelog reverter as the previous release hasn’t been deployed yet due to a new bug

* Too long dialog text scrollable
2024-04-02 08:29:08 +02:00
Honza Rychnovský a8ad649ef8
[#1310] Release 0.2.0 (583)
* [#1310] Release 0.2.0 (583)

Closes #1310

* Fix valid message check
2024-03-29 21:23:39 +01:00
Honza Rychnovský 4ae3fde690
[#1162] Expandable transaction history item
Although this brings many changes to the transaction history item UI, it only partly solves Expandable transaction history item #1162
Follow-up PR will close it
2024-03-29 20:27:30 +01:00
Honza Rychnovský c99c2907b1
[#1307] Keep transaction history UI state
- Closes #1307
- Changelog update
- #1162 is the direct follow-up of this PR
2024-03-28 12:57:04 +01:00
Honza Rychnovský 809820c1f2
[#1305] Connect shielding Multi-Trx-Submit-Error
- Closes #1305
2024-03-28 10:54:51 +01:00
197 changed files with 7097 additions and 3090 deletions

View File

@ -1,3 +1,3 @@
FROM clamav/clamav:1.3.0
FROM clamav/clamav:1.3.1
RUN freshclam
ENTRYPOINT ["clamscan", "--recursive"]

View File

@ -38,12 +38,12 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
# Gradle Wrapper validation can be flaky
# https://github.com/gradle/wrapper-validation-action/issues/40
- name: Gradle Wrapper Validation
timeout-minutes: 1
uses: gradle/wrapper-validation-action@b231772637bb498f11fdbc86052b6e8a8dc9fc92
uses: gradle/wrapper-validation-action@216d1ad2b3710bf005dc39237337b9673fd8fcd5
check_secrets:
environment: deployment
@ -80,7 +80,7 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
with:
ref: main
fetch-depth: 0 # To fetch all commits
@ -91,7 +91,7 @@ jobs:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e
uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff
timeout-minutes: 10
with:
gradle-home-cache-cleanup: true
@ -112,7 +112,7 @@ jobs:
# Note that this step is not currently used due to #1033
if: false
id: auth_google_play
uses: google-github-actions/auth@55bd3a7c6e2ae7cf1877fd1ccb9d54c0503c457c
uses: google-github-actions/auth@71fee32a0bb7e97b4d33d548e7d957010649d8fa
with:
create_credentials_file: true
project_id: ${{ secrets.GOOGLE_PLAY_CLOUD_PROJECT }}
@ -125,6 +125,13 @@ jobs:
echo "home=${HOME}" >> "$GITHUB_ENV"
- name: Export Signing Key
env:
# The upload key must be exported using `base64 -w 0 <filename.jks>` for use
# as a Github Secrets value; if the key is exported with standard wrapping,
# it will fail to import correctly.
# NOTE: This is the upload signing key, which may be replaced at will, not
# the application signing key which is escrowed by Google and may only be
# replaced once a year (and has a bunch of additional hassles associated with
# replacing it.)
SIGNING_KEYSTORE_BASE_64: ${{ secrets.UPLOAD_KEYSTORE_BASE_64 }}
SIGNING_KEY_PATH: ${{ format('{0}/release.jks', env.home) }}
shell: bash
@ -160,7 +167,7 @@ jobs:
zip -r ${BINARIES_ZIP_PATH} . -i app/build/outputs/apk/\*/\*.apk app/build/outputs/apk_from_bundle/\*/\*.apk app/build/outputs/bundle/\*/\*.aab
zip -r ${MAPPINGS_ZIP_PATH} . -i app/build/outputs/mapping/\*/mapping.txt
- name: Upload Artifacts
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
timeout-minutes: 5
with:
name: Binaries
@ -177,9 +184,9 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Download release artifact
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
with:
name: Binaries
- name: Unzip artifacts

View File

@ -32,12 +32,12 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
# Gradle Wrapper validation can be flaky
# https://github.com/gradle/wrapper-validation-action/issues/40
- name: Gradle Wrapper Validation
timeout-minutes: 1
uses: gradle/wrapper-validation-action@b231772637bb498f11fdbc86052b6e8a8dc9fc92
uses: gradle/wrapper-validation-action@216d1ad2b3710bf005dc39237337b9673fd8fcd5
check_firebase_secrets:
runs-on: ubuntu-latest
@ -71,7 +71,7 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Set up Java
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
timeout-minutes: 1
@ -79,7 +79,7 @@ jobs:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e
uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff
timeout-minutes: 5
- name: Check properties
timeout-minutes: 4
@ -94,7 +94,7 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Set up Java
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
timeout-minutes: 1
@ -102,7 +102,7 @@ jobs:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e
uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff
timeout-minutes: 5
- name: Detekt
timeout-minutes: 10
@ -120,7 +120,7 @@ jobs:
zip -r ${REPORTS_ZIP_PATH} . -i build/reports/detekt/*
- name: Upload Artifacts
if: ${{ always() }}
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
timeout-minutes: 1
with:
name: Detekt static analysis results
@ -134,7 +134,7 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Set up Java
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
timeout-minutes: 1
@ -142,7 +142,7 @@ jobs:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e
uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff
timeout-minutes: 5
- name: Ktlint
timeout-minutes: 4
@ -160,7 +160,7 @@ jobs:
zip -r ${REPORTS_ZIP_PATH} . -i build/reports/ktlint/\*
- name: Upload Artifacts
if: ${{ always() }}
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
timeout-minutes: 1
with:
name: Ktlint static analysis results
@ -174,7 +174,7 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Set up Java
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
timeout-minutes: 1
@ -182,7 +182,7 @@ jobs:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e
uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff
timeout-minutes: 5
- name: Android Lint
timeout-minutes: 15
@ -203,7 +203,7 @@ jobs:
zip -r ${LINT_ZIP_PATH} . -i \*build/reports/\*
- name: Upload Artifacts
if: ${{ always() }}
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
timeout-minutes: 1
with:
name: Android Lint static analysis results
@ -217,7 +217,7 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Set up Java
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
timeout-minutes: 1
@ -225,7 +225,7 @@ jobs:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e
uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff
timeout-minutes: 5
- name: Test
timeout-minutes: 10
@ -244,7 +244,7 @@ jobs:
zip -r ${RESULTS_ZIP_PATH} . -i \*build/reports/\* \*/build/kover/html/\* \*/build/kover/xml/report.xml
- name: Upload Artifacts
if: ${{ always() }}
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
timeout-minutes: 1
with:
name: Test Kotlin modules results
@ -261,7 +261,7 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Set up Java
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
timeout-minutes: 1
@ -269,7 +269,7 @@ jobs:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e
uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff
timeout-minutes: 5
- name: Build
timeout-minutes: 20
@ -277,7 +277,7 @@ jobs:
./gradlew assembleDebug assembleAndroidTest assembleZcashmainnetDebug assembleZcashtestnetDebug
- name: Authenticate to Google Cloud for Firebase Test Lab
id: auth_test_lab
uses: google-github-actions/auth@55bd3a7c6e2ae7cf1877fd1ccb9d54c0503c457c
uses: google-github-actions/auth@71fee32a0bb7e97b4d33d548e7d957010649d8fa
with:
create_credentials_file: true
project_id: ${{ vars.FIREBASE_TEST_LAB_PROJECT }}
@ -309,7 +309,7 @@ jobs:
zip -r ${TEST_RESULTS_ZIP_PATH} . -i build/fladle/\* \*/build/outputs/androidTest-results/\*
- name: Upload Artifacts
if: ${{ always() }}
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
timeout-minutes: 1
with:
name: Test Android modules with FTL results
@ -324,7 +324,7 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Set up Java
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
timeout-minutes: 1
@ -332,7 +332,7 @@ jobs:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e
uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff
timeout-minutes: 5
- name: Build and test
timeout-minutes: 30
@ -356,7 +356,7 @@ jobs:
zip -r ${TEST_RESULTS_ZIP_PATH} . -i \*/build/test-results/\*
- name: Upload Artifacts
if: ${{ always() }}
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
timeout-minutes: 1
with:
name: Test Android libs with WTF results
@ -371,7 +371,7 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Set up Java
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
timeout-minutes: 1
@ -379,7 +379,7 @@ jobs:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e
uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff
timeout-minutes: 5
- name: Build and test
timeout-minutes: 30
@ -403,7 +403,7 @@ jobs:
zip -r ${TEST_RESULTS_ZIP_PATH} . -i \*/build/test-results/\*
- name: Upload Artifacts
if: ${{ always() }}
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
timeout-minutes: 1
with:
name: Test Android app with WTF results
@ -421,7 +421,7 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Set up Java
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
timeout-minutes: 1
@ -429,7 +429,7 @@ jobs:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e
uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff
timeout-minutes: 5
- name: Export Google Services JSON
env:
@ -451,7 +451,7 @@ jobs:
./gradlew :app:assembleDebug
- name: Authenticate to Google Cloud for Firebase Test Lab
id: auth_test_lab
uses: google-github-actions/auth@55bd3a7c6e2ae7cf1877fd1ccb9d54c0503c457c
uses: google-github-actions/auth@71fee32a0bb7e97b4d33d548e7d957010649d8fa
with:
create_credentials_file: true
project_id: ${{ vars.FIREBASE_TEST_LAB_PROJECT }}
@ -475,7 +475,7 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Set up Java
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
timeout-minutes: 1
@ -483,7 +483,7 @@ jobs:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e
uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff
timeout-minutes: 5
- name: Export Google Services JSON
env:
@ -530,7 +530,7 @@ jobs:
zip -r ${MAPPINGS_ZIP_PATH} . -i *app/build/outputs/mapping/*/mapping.txt
zip -r ${COMPOSE_METRICS_ZIP_PATH} . -i \*/build/compose-metrics/\* \*/build/compose-reports/\*
- name: Upload Artifacts
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
timeout-minutes: 2
with:
name: Binaries
@ -548,7 +548,7 @@ jobs:
steps:
- name: Checkout
timeout-minutes: 1
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- name: Set up Java
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
timeout-minutes: 1
@ -556,11 +556,11 @@ jobs:
distribution: 'temurin'
java-version: 17
- name: Set up Gradle
uses: gradle/gradle-build-action@29c0906b64b8fc82467890bfb7a0a7ef34bda89e
uses: gradle/gradle-build-action@4c39dd82cd5e1ec7c6fa0173bb41b4b6bb3b86ff
timeout-minutes: 5
- name: Authenticate to Google Cloud for Firebase Test Lab
id: auth_test_lab
uses: google-github-actions/auth@55bd3a7c6e2ae7cf1877fd1ccb9d54c0503c457c
uses: google-github-actions/auth@71fee32a0bb7e97b4d33d548e7d957010649d8fa
with:
create_credentials_file: true
project_id: ${{ vars.FIREBASE_TEST_LAB_PROJECT }}
@ -568,7 +568,7 @@ jobs:
workload_identity_provider: ${{ secrets.FIREBASE_TEST_LAB_WORKLOAD_IDENTITY_PROVIDER }}
access_token_lifetime: '900s'
- name: Download a single artifact
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
with:
name: Binaries
- name: Robo test

3
.gitignore vendored
View File

@ -9,6 +9,9 @@ syntax: glob
.idea/modules.xml
.idea/tasks.xml
.idea/workspace.xml
.idea/deploymentTargetSelector.xml
.idea/migrations.xml
.idea/studiobot.xml
.settings
*.iml
bin/

View File

@ -9,6 +9,62 @@ directly impact users rather than highlighting other key architectural updates.*
## [Unreleased]
### Added
- Zashi now provides system biometric or device credential (pattern, pin, or password) authentication for these use
cases: Send funds, Recovery Phrase, Export Private Data, and Delete Wallet.
- The app entry animation has been reworked to apply on every app access point, i.e. it will be displayed when
users return to an already set up app as well.
## [1.0 (650)] - 2024-05-07
### Added
- Delete Zashi feature has been added. It's accessible from the Advanced settings screen. It removes the wallet
secrets from Zashi and resets its state.
- Transaction messages are now checked and removed in case of duplicity
### Changed
- We've improved the visibility logic of the little loader that is part of the Balances widget
- The App-Update screen UI has been reworked to align with the latest design guidelines
### Removed
- Concatenation of the messages on a multi-messages transaction has been removed and will be addressed using a new
design
### Fixed
- Transparent funds shielding action has been improved to address the latest user feedback
- Onboarding screen dynamic height calculation has been improved
- A few more minor UI improvements
## [1.0 (638)] - 2024-04-26
### Fixed
- Default server selection option
## [1.0 (636)] - 2024-04-26
### Changed
- We have added one more group of server options (zec.rocks) for increased coverage and reliability
- zec.rocks:443 is now default wallet option
## [1.0 (630)] - 2024-04-24
### Changed
- We have added more server options for increased coverage and reliability
- If you experience issues with the Zcash Lightwalletd Mainnet server selected by default, please switch to one of
the Ywallet servers: https://status.zcash-infra.com/
## [1.0 (628)] - 2024-04-23
### Changed
- The Scan QR code screen has been reworked to align with the rest of the screens
- The Send Form screen scrolls to the Send button on very small devices after the memo is typed
### Fixed
- Sending zero funds is allowed only for shielded recipient address type
- The Balances widget loader has been improved to better handle cases, like a wallet with only transparent funds
## [0.2.0 (609)] - 2024-04-18
### Added
- Advanced Settings screen that provides more technical options like Export private data, Recovery phrase, or
Choose server has been added
@ -19,12 +75,20 @@ directly impact users rather than highlighting other key architectural updates.*
- Transitions between screens are now animated with a simple slide animation
- Proposal API from the Zcash SDK has been integrated together with handling error states for multi-transaction
submission
- New Restoring Your Wallet label and Synchronization widget have been added to all post-onboarding screens to notify
users about the current state of the wallet-restoring process
### Changed
- The Transaction History UI has been incorporated into the Account screen
- The Transaction History UI has been incorporated into the Account screen and completely reworked according to the
design guidelines
- Reworked Send screens flow and their look (e.g., Send Failure screen is now a modal dialog instead of a separate
screen)
- The sending and shielding funds logic has been connected to the new Proposal API from the Zcash SDK
- The error dialog contains an error description now. It's useful for tracking down the failure cause.
- A small circular progress indicator is displayed when the app runs block synchronization, and the available balance
is zero instead of reflecting a result value.
- Block synchronization statuses have been simplified to Syncing, Synced, and Error states only
- All internal dependencies have been updated
### Fixed
- Button sizing has been updated to align with the design guidelines and preserve stretching if necessary

View File

@ -93,7 +93,7 @@ android {
releaseKeystorePassword,
releaseKeyAlias,
releaseKeyAliasPassword
).all { !it.isNullOrBlank() }
).all { it.isNotBlank() }
signingConfigs {
if (isReleaseSigningConfigured) {
@ -120,6 +120,8 @@ android {
getByName("release").apply {
isMinifyEnabled = project.property("IS_MINIFY_ENABLED").toString().toBoolean()
isShrinkResources = project.property("IS_MINIFY_ENABLED").toString().toBoolean()
ndk.debugSymbolLevel = project.property("NDK_DEBUG_SYMBOL_LEVEL").toString()
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-project.txt"
@ -251,6 +253,7 @@ androidComponents {
".readme",
))
// The fixed Locale.US is intended
if (variant.name.lowercase(Locale.US).contains("release")) {
variant.packaging.resources.excludes.addAll(listOf(
"**/*.kotlin_metadata",

View File

@ -9,6 +9,9 @@
# Generate the combined proguard configuration for debugging.
-printconfiguration build/outputs/proguard-config.txt
# This is generated automatically by the Android Gradle plugin.
-dontwarn com.google.j2objc.annotations.ReflectionSupport
-dontwarn com.google.j2objc.annotations.RetainedWith
-dontwarn androidx.compose.ui.util.MathHelpersKt
-dontwarn com.google.common.util.concurrent.ListenableFuture
-dontwarn com.google.errorprone.annotations.InlineMe

View File

@ -1,35 +1,35 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:4.2.1=classpath
org.gradle.kotlin:gradle-kotlin-dsl-plugins:4.2.1=classpath
org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:4.3.0=classpath
org.gradle.kotlin:gradle-kotlin-dsl-plugins:4.3.0=classpath
org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
org.jetbrains.kotlin:kotlin-android-extensions:1.9.20=classpath
org.jetbrains.kotlin:kotlin-assignment:1.9.20=classpath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.20=classpath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.20=classpath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.20=classpath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.20=classpath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.20=classpath
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.20=classpath
org.jetbrains.kotlin:kotlin-native-utils:1.9.20=classpath
org.jetbrains.kotlin:kotlin-project-model:1.9.20=classpath
org.jetbrains.kotlin:kotlin-sam-with-receiver:1.9.20=classpath
org.jetbrains.kotlin:kotlin-scripting-common:1.9.20=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.20=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.20=classpath
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.20=classpath
org.jetbrains.kotlin:kotlin-stdlib:1.9.20=classpath
org.jetbrains.kotlin:kotlin-tooling-core:1.9.20=classpath
org.jetbrains.kotlin:kotlin-util-io:1.9.20=classpath
org.jetbrains.kotlin:kotlin-util-klib:1.9.20=classpath
org.jetbrains.kotlin:kotlin-android-extensions:1.9.22=classpath
org.jetbrains.kotlin:kotlin-assignment:1.9.22=classpath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.22=classpath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.22=classpath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.22=classpath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.22=classpath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.22=classpath
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.22=classpath
org.jetbrains.kotlin:kotlin-native-utils:1.9.22=classpath
org.jetbrains.kotlin:kotlin-project-model:1.9.22=classpath
org.jetbrains.kotlin:kotlin-sam-with-receiver:1.9.22=classpath
org.jetbrains.kotlin:kotlin-scripting-common:1.9.22=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.22=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.22=classpath
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.22=classpath
org.jetbrains.kotlin:kotlin-stdlib:1.9.22=classpath
org.jetbrains.kotlin:kotlin-tooling-core:1.9.22=classpath
org.jetbrains.kotlin:kotlin-util-io:1.9.22=classpath
org.jetbrains.kotlin:kotlin-util-klib:1.9.22=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
org.jetbrains:annotations:13.0=classpath
empty=

View File

@ -1,74 +1,78 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
androidx.databinding:databinding-common:8.1.1=runtimeClasspath
androidx.databinding:databinding-compiler-common:8.1.1=runtimeClasspath
com.android.databinding:baseLibrary:8.1.1=runtimeClasspath
com.android.tools.analytics-library:crash:31.1.1=runtimeClasspath
com.android.tools.analytics-library:protos:31.1.1=runtimeClasspath
com.android.tools.analytics-library:shared:31.1.1=runtimeClasspath
com.android.tools.analytics-library:tracker:31.1.1=runtimeClasspath
androidx.databinding:databinding-common:8.3.0=runtimeClasspath
androidx.databinding:databinding-compiler-common:8.3.0=runtimeClasspath
com.android.databinding:baseLibrary:8.3.0=runtimeClasspath
com.android.tools.analytics-library:crash:31.3.0=runtimeClasspath
com.android.tools.analytics-library:protos:31.3.0=runtimeClasspath
com.android.tools.analytics-library:shared:31.3.0=runtimeClasspath
com.android.tools.analytics-library:tracker:31.3.0=runtimeClasspath
com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=runtimeClasspath
com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=runtimeClasspath
com.android.tools.build:aapt2-proto:8.1.1-10154469=runtimeClasspath
com.android.tools.build:aaptcompiler:8.1.1=runtimeClasspath
com.android.tools.build:apksig:8.1.1=compileClasspath,runtimeClasspath
com.android.tools.build:apkzlib:8.1.1=compileClasspath,runtimeClasspath
com.android.tools.build:builder-model:8.1.1=compileClasspath,runtimeClasspath
com.android.tools.build:builder-test-api:8.1.1=runtimeClasspath
com.android.tools.build:builder:8.1.1=compileClasspath,runtimeClasspath
com.android.tools.build:bundletool:1.14.0=runtimeClasspath
com.android.tools.build:gradle-api:8.1.1=compileClasspath,runtimeClasspath
com.android.tools.build:gradle-settings-api:8.1.1=runtimeClasspath
com.android.tools.build:gradle:8.1.1=compileClasspath,runtimeClasspath
com.android.tools.build:manifest-merger:31.1.1=compileClasspath,runtimeClasspath
com.android.tools.build:aapt2-proto:8.3.0-10880808=runtimeClasspath
com.android.tools.build:aaptcompiler:8.3.0=runtimeClasspath
com.android.tools.build:apksig:8.3.0=compileClasspath,runtimeClasspath
com.android.tools.build:apkzlib:8.3.0=compileClasspath,runtimeClasspath
com.android.tools.build:builder-model:8.3.0=compileClasspath,runtimeClasspath
com.android.tools.build:builder-test-api:8.3.0=runtimeClasspath
com.android.tools.build:builder:8.3.0=compileClasspath,runtimeClasspath
com.android.tools.build:bundletool:1.15.6=runtimeClasspath
com.android.tools.build:gradle-api:8.3.0=compileClasspath,runtimeClasspath
com.android.tools.build:gradle-settings-api:8.3.0=runtimeClasspath
com.android.tools.build:gradle:8.3.0=compileClasspath,runtimeClasspath
com.android.tools.build:manifest-merger:31.3.0=compileClasspath,runtimeClasspath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=runtimeClasspath
com.android.tools.ddms:ddmlib:31.1.1=runtimeClasspath
com.android.tools.layoutlib:layoutlib-api:31.1.1=runtimeClasspath
com.android.tools.lint:lint-model:31.1.1=runtimeClasspath
com.android.tools.lint:lint-typedef-remover:31.1.1=runtimeClasspath
com.android.tools.utp:android-device-provider-ddmlib-proto:31.1.1=runtimeClasspath
com.android.tools.utp:android-device-provider-gradle-proto:31.1.1=runtimeClasspath
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.1.1=runtimeClasspath
com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.1.1=runtimeClasspath
com.android.tools.utp:android-test-plugin-host-coverage-proto:31.1.1=runtimeClasspath
com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.1.1=runtimeClasspath
com.android.tools.utp:android-test-plugin-host-logcat-proto:31.1.1=runtimeClasspath
com.android.tools.utp:android-test-plugin-host-retention-proto:31.1.1=runtimeClasspath
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.1.1=runtimeClasspath
com.android.tools:annotations:31.1.1=runtimeClasspath
com.android.tools:common:31.1.1=runtimeClasspath
com.android.tools:dvlib:31.1.1=runtimeClasspath
com.android.tools:repository:31.1.1=runtimeClasspath
com.android.tools:sdk-common:31.1.1=runtimeClasspath
com.android.tools:sdklib:31.1.1=runtimeClasspath
com.android:signflinger:8.1.1=runtimeClasspath
com.android:zipflinger:8.1.1=compileClasspath,runtimeClasspath
com.android.tools.ddms:ddmlib:31.3.0=runtimeClasspath
com.android.tools.layoutlib:layoutlib-api:31.3.0=runtimeClasspath
com.android.tools.lint:lint-model:31.3.0=runtimeClasspath
com.android.tools.lint:lint-typedef-remover:31.3.0=runtimeClasspath
com.android.tools.utp:android-device-provider-ddmlib-proto:31.3.0=runtimeClasspath
com.android.tools.utp:android-device-provider-gradle-proto:31.3.0=runtimeClasspath
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.3.0=runtimeClasspath
com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.3.0=runtimeClasspath
com.android.tools.utp:android-test-plugin-host-coverage-proto:31.3.0=runtimeClasspath
com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.3.0=runtimeClasspath
com.android.tools.utp:android-test-plugin-host-logcat-proto:31.3.0=runtimeClasspath
com.android.tools.utp:android-test-plugin-host-retention-proto:31.3.0=runtimeClasspath
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.3.0=runtimeClasspath
com.android.tools:annotations:31.3.0=runtimeClasspath
com.android.tools:common:31.3.0=runtimeClasspath
com.android.tools:dvlib:31.3.0=runtimeClasspath
com.android.tools:repository:31.3.0=runtimeClasspath
com.android.tools:sdk-common:31.3.0=runtimeClasspath
com.android.tools:sdklib:31.3.0=runtimeClasspath
com.android:signflinger:8.3.0=runtimeClasspath
com.android:zipflinger:8.3.0=compileClasspath,runtimeClasspath
com.google.android:annotations:4.1.1.4=runtimeClasspath
com.google.api-client:google-api-client:2.2.0=compileClasspath,runtimeClasspath
com.google.api.grpc:proto-google-common-protos:2.0.1=runtimeClasspath
com.google.api.grpc:proto-google-common-protos:2.17.0=runtimeClasspath
com.google.apis:google-api-services-androidpublisher:v3-rev20231030-2.0.0=compileClasspath,runtimeClasspath
com.google.auth:google-auth-library-credentials:1.18.0=compileClasspath,runtimeClasspath
com.google.auth:google-auth-library-oauth2-http:1.18.0=compileClasspath,runtimeClasspath
com.google.auto.value:auto-value-annotations:1.10.1=compileClasspath,runtimeClasspath
com.google.code.findbugs:jsr305:3.0.2=compileClasspath,runtimeClasspath
com.google.code.gson:gson:2.10=compileClasspath,runtimeClasspath
com.google.code.gson:gson:2.10=compileClasspath
com.google.code.gson:gson:2.10.1=runtimeClasspath
com.google.crypto.tink:tink:1.7.0=runtimeClasspath
com.google.dagger:dagger:2.28.3=runtimeClasspath
com.google.errorprone:error_prone_annotations:2.16=compileClasspath,runtimeClasspath
com.google.errorprone:error_prone_annotations:2.16=compileClasspath
com.google.errorprone:error_prone_annotations:2.18.0=runtimeClasspath
com.google.flatbuffers:flatbuffers-java:1.12.0=runtimeClasspath
com.google.guava:failureaccess:1.0.1=compileClasspath,runtimeClasspath
com.google.guava:guava:31.1-jre=compileClasspath,runtimeClasspath
com.google.guava:guava:31.1-jre=compileClasspath
com.google.guava:guava:32.0.1-jre=runtimeClasspath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=compileClasspath,runtimeClasspath
com.google.http-client:google-http-client-apache-v2:1.42.3=compileClasspath,runtimeClasspath
com.google.http-client:google-http-client-gson:1.42.3=compileClasspath,runtimeClasspath
com.google.http-client:google-http-client:1.42.3=compileClasspath,runtimeClasspath
com.google.j2objc:j2objc-annotations:1.3=compileClasspath,runtimeClasspath
com.google.j2objc:j2objc-annotations:1.3=compileClasspath
com.google.j2objc:j2objc-annotations:2.8=runtimeClasspath
com.google.jimfs:jimfs:1.1=runtimeClasspath
com.google.oauth-client:google-oauth-client:1.34.1=compileClasspath,runtimeClasspath
com.google.protobuf:protobuf-java-util:3.19.3=runtimeClasspath
com.google.protobuf:protobuf-java:3.19.3=runtimeClasspath
com.google.testing.platform:core-proto:0.0.8-alpha08=runtimeClasspath
com.google.protobuf:protobuf-java-util:3.22.3=runtimeClasspath
com.google.protobuf:protobuf-java:3.22.3=runtimeClasspath
com.google.testing.platform:core-proto:0.0.9-alpha02=runtimeClasspath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=runtimeClasspath
com.squareup:javapoet:1.10.0=runtimeClasspath
com.squareup:javawriter:2.5.0=compileClasspath,runtimeClasspath
@ -77,31 +81,31 @@ com.sun.istack:istack-commons-runtime:3.0.8=runtimeClasspath
com.sun.xml.fastinfoset:FastInfoset:1.2.16=runtimeClasspath
com.vdurmont:semver4j:3.1.0=runtimeClasspath
commons-codec:commons-codec:1.15=compileClasspath,runtimeClasspath
commons-io:commons-io:2.12.0=runtimeClasspath
commons-io:commons-io:2.15.1=runtimeClasspath
commons-logging:commons-logging:1.2=compileClasspath,runtimeClasspath
io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.0=compileClasspath,runtimeClasspath
io.grpc:grpc-api:1.45.1=runtimeClasspath
io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.6=compileClasspath,runtimeClasspath
io.grpc:grpc-api:1.57.0=runtimeClasspath
io.grpc:grpc-context:1.27.2=compileClasspath
io.grpc:grpc-context:1.45.1=runtimeClasspath
io.grpc:grpc-core:1.45.1=runtimeClasspath
io.grpc:grpc-netty:1.45.1=runtimeClasspath
io.grpc:grpc-protobuf-lite:1.45.1=runtimeClasspath
io.grpc:grpc-protobuf:1.45.1=runtimeClasspath
io.grpc:grpc-stub:1.45.1=runtimeClasspath
io.netty:netty-buffer:4.1.72.Final=runtimeClasspath
io.netty:netty-codec-http2:4.1.72.Final=runtimeClasspath
io.netty:netty-codec-http:4.1.72.Final=runtimeClasspath
io.netty:netty-codec-socks:4.1.72.Final=runtimeClasspath
io.netty:netty-codec:4.1.72.Final=runtimeClasspath
io.netty:netty-common:4.1.72.Final=runtimeClasspath
io.netty:netty-handler-proxy:4.1.72.Final=runtimeClasspath
io.netty:netty-handler:4.1.72.Final=runtimeClasspath
io.netty:netty-resolver:4.1.72.Final=runtimeClasspath
io.netty:netty-tcnative-classes:2.0.46.Final=runtimeClasspath
io.netty:netty-transport:4.1.72.Final=runtimeClasspath
io.grpc:grpc-context:1.57.0=runtimeClasspath
io.grpc:grpc-core:1.57.0=runtimeClasspath
io.grpc:grpc-netty:1.57.0=runtimeClasspath
io.grpc:grpc-protobuf-lite:1.57.0=runtimeClasspath
io.grpc:grpc-protobuf:1.57.0=runtimeClasspath
io.grpc:grpc-stub:1.57.0=runtimeClasspath
io.netty:netty-buffer:4.1.93.Final=runtimeClasspath
io.netty:netty-codec-http2:4.1.93.Final=runtimeClasspath
io.netty:netty-codec-http:4.1.93.Final=runtimeClasspath
io.netty:netty-codec-socks:4.1.93.Final=runtimeClasspath
io.netty:netty-codec:4.1.93.Final=runtimeClasspath
io.netty:netty-common:4.1.93.Final=runtimeClasspath
io.netty:netty-handler-proxy:4.1.93.Final=runtimeClasspath
io.netty:netty-handler:4.1.93.Final=runtimeClasspath
io.netty:netty-resolver:4.1.93.Final=runtimeClasspath
io.netty:netty-transport-native-unix-common:4.1.93.Final=runtimeClasspath
io.netty:netty-transport:4.1.93.Final=runtimeClasspath
io.opencensus:opencensus-api:0.31.1=compileClasspath,runtimeClasspath
io.opencensus:opencensus-contrib-http-util:0.31.1=compileClasspath,runtimeClasspath
io.perfmark:perfmark-api:0.23.0=runtimeClasspath
io.perfmark:perfmark-api:0.26.0=runtimeClasspath
jakarta.activation:jakarta.activation-api:1.2.1=runtimeClasspath
jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=runtimeClasspath
javax.annotation:javax.annotation-api:1.3.2=runtimeClasspath
@ -117,71 +121,70 @@ org.apache.httpcomponents:httpmime:4.5.6=runtimeClasspath
org.bitbucket.b_c:jose4j:0.7.0=runtimeClasspath
org.bouncycastle:bcpkix-jdk15on:1.67=runtimeClasspath
org.bouncycastle:bcprov-jdk15on:1.67=runtimeClasspath
org.checkerframework:checker-qual:3.12.0=compileClasspath,runtimeClasspath
org.codehaus.mojo:animal-sniffer-annotations:1.19=runtimeClasspath
org.checkerframework:checker-qual:3.12.0=compileClasspath
org.checkerframework:checker-qual:3.33.0=runtimeClasspath
org.codehaus.mojo:animal-sniffer-annotations:1.23=runtimeClasspath
org.glassfish.jaxb:jaxb-runtime:2.3.2=runtimeClasspath
org.glassfish.jaxb:txw2:2.3.2=runtimeClasspath
org.jdom:jdom2:2.0.6=runtimeClasspath
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-android-extensions:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-assignment-compiler-plugin-embeddable:1.9.20=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.20=kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.20=kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.21=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.21=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.21=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.21=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.21=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-native-utils:1.9.21=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-project-model:1.9.21=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-android-extensions:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-assignment-compiler-plugin-embeddable:1.9.22=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.22=kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.22=kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.23=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.23=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.23=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.23=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.23=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-native-utils:1.9.23=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-project-model:1.9.23=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-reflect:1.8.20-RC2=runtimeClasspath
org.jetbrains.kotlin:kotlin-reflect:1.9.20=compileClasspath
org.jetbrains.kotlin:kotlin-sam-with-receiver-compiler-plugin-embeddable:1.9.20=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-script-runtime:1.9.20=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.20=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.20=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.20=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.20=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.21=runtimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.20-RC2=runtimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20-RC2=runtimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20-RC2=runtimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.8.20-RC2=runtimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.9.20=compileClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-tooling-core:1.9.21=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-util-io:1.9.21=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-util-klib:1.9.21=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-reflect:1.9.20=runtimeClasspath
org.jetbrains.kotlin:kotlin-reflect:1.9.22=compileClasspath
org.jetbrains.kotlin:kotlin-sam-with-receiver-compiler-plugin-embeddable:1.9.22=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-script-runtime:1.9.22=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.22=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.22=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.22=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.22=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.23=runtimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.20=runtimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.20=runtimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.9.20=runtimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.9.22=compileClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-tooling-core:1.9.23=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-util-io:1.9.23=compileClasspath,runtimeClasspath
org.jetbrains.kotlin:kotlin-util-klib:1.9.23=compileClasspath,runtimeClasspath
org.jetbrains.kotlinx.kover:org.jetbrains.kotlinx.kover.gradle.plugin:0.7.3=compileClasspath,runtimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=runtimeClasspath
org.jetbrains.kotlinx:kover-gradle-plugin:0.7.3=compileClasspath,runtimeClasspath
org.jetbrains:annotations:13.0=compileClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,runtimeClasspath
org.json:json:20230227=runtimeClasspath
org.jetbrains:annotations:13.0=compileClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain
org.jetbrains:annotations:23.0.0=runtimeClasspath
org.json:json:20240205=runtimeClasspath
org.jvnet.staxex:stax-ex:1.8.1=runtimeClasspath
org.ow2.asm:asm-analysis:9.2=runtimeClasspath
org.ow2.asm:asm-commons:9.2=runtimeClasspath
org.ow2.asm:asm-tree:9.2=runtimeClasspath
org.ow2.asm:asm-util:9.2=runtimeClasspath
org.ow2.asm:asm:9.2=compileClasspath,runtimeClasspath
org.ow2.asm:asm-analysis:9.6=runtimeClasspath
org.ow2.asm:asm-commons:9.6=runtimeClasspath
org.ow2.asm:asm-tree:9.6=runtimeClasspath
org.ow2.asm:asm-util:9.6=runtimeClasspath
org.ow2.asm:asm:9.6=compileClasspath,runtimeClasspath
org.slf4j:slf4j-api:1.7.30=runtimeClasspath
org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=runtimeClasspath
wtf.emulator:gradle-compat-6-1:0.15.1=runtimeClasspath
wtf.emulator:gradle-compat-6-6:0.15.1=runtimeClasspath
wtf.emulator:gradle-compat-7-6:0.15.1=runtimeClasspath
wtf.emulator:gradle-compat-api:0.15.1=runtimeClasspath
wtf.emulator:gradle-compat:0.15.1=runtimeClasspath
wtf.emulator:gradle-plugin:0.15.1=compileClasspath,runtimeClasspath
xerces:xercesImpl:2.12.0=runtimeClasspath
xml-apis:xml-apis:1.4.01=runtimeClasspath
wtf.emulator:gradle-compat-6-1:0.16.2=runtimeClasspath
wtf.emulator:gradle-compat-6-6:0.16.2=runtimeClasspath
wtf.emulator:gradle-compat-7-6:0.16.2=runtimeClasspath
wtf.emulator:gradle-compat-api:0.16.2=runtimeClasspath
wtf.emulator:gradle-compat:0.16.2=runtimeClasspath
wtf.emulator:gradle-plugin:0.16.2=compileClasspath,runtimeClasspath
empty=annotationProcessor,kotlinScriptDefExtensions

View File

@ -175,7 +175,7 @@ fun com.android.build.gradle.BaseExtension.configureBaseExtension() {
)
}
if (this is CommonExtension<*, *, *, *, *>) {
if (this is CommonExtension<*, *, *, *, *, *>) {
kotlinOptions {
jvmTarget = project.property("ANDROID_JVM_TARGET").toString()
allWarningsAsErrors = project.property("ZCASH_IS_TREAT_WARNINGS_AS_ERRORS").toString().toBoolean()
@ -191,7 +191,7 @@ fun com.android.build.gradle.BaseExtension.configureBaseExtension() {
}
}
fun CommonExtension<*, *, *, *, *>.kotlinOptions(block: KotlinJvmOptions.() -> Unit) {
fun CommonExtension<*, *, *, *, *, *>.kotlinOptions(block: KotlinJvmOptions.() -> Unit) {
(this as ExtensionAware).extensions.configure("kotlinOptions", block)
}

View File

@ -245,6 +245,8 @@ abstract class PublishToGooglePlay @Inject constructor(
track,
Track().setReleases(
listOf(TrackRelease()
// TODO [#1440]: Provide a way to inject in-app-update information
// TODO [#1440]: https://github.com/Electric-Coin-Company/zashi-android/issues/1440
.setName(versionName)
.setVersionCodes(bundleVersionCodes)
.setStatus(status)

View File

@ -4,29 +4,29 @@
junit:junit:4.13.2=commonTestImplementationCopy,jvmTestCompileClasspath,jvmTestImplementationCopy,jvmTestRuntimeClasspath
org.hamcrest:hamcrest-core:1.3=commonTestImplementationCopy,jvmTestCompileClasspath,jvmTestImplementationCopy,jvmTestRuntimeClasspath
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-build-common:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-common:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.6.20=kotlinCompilerClasspathCopy
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.6.20=kotlinKlibCommonizerClasspathCopy
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.21=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.23=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-script-runtime:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.6.20=kotlinCompilerPluginClasspathJvmMainCopy,kotlinCompilerPluginClasspathJvmTestCopy,kotlinCompilerPluginClasspathMetadataCommonMainCopy,kotlinCompilerPluginClasspathMetadataMainCopy
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.6.21=kotlinCompilerPluginClasspathJvmMainCopy2,kotlinCompilerPluginClasspathJvmTestCopy2,kotlinCompilerPluginClasspathMetadataCommonMainCopy2,kotlinCompilerPluginClasspathMetadataMainCopy2
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-stdlib-common:1.6.20=commonTestImplementationCopy,jvmTestImplementationCopy
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.10=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain,metadataCommonMainCompileClasspath
@ -35,14 +35,14 @@ org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.20=commonMainApiCopy,commonMainCompi
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21=jvmTestCompileClasspathCopy2,jvmTestRuntimeClasspathCopy2
org.jetbrains.kotlin:kotlin-stdlib:1.6.20=commonTestImplementationCopy,jvmTestImplementationCopy
org.jetbrains.kotlin:kotlin-stdlib:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-stdlib:1.9.21=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-test-annotations-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-stdlib:1.9.23=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-test-annotations-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-junit:1.6.20=commonTestImplementationCopy,jvmTestImplementationCopy
org.jetbrains.kotlin:kotlin-test-junit:1.9.21=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test-junit:1.9.23=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test:1.6.20=commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestCompileClasspathCopy2,jvmTestImplementationCopy,jvmTestImplementationDependenciesMetadataCopy,jvmTestRuntimeClasspathCopy,jvmTestRuntimeClasspathCopy2
org.jetbrains.kotlin:kotlin-test:1.6.21=commonTestImplementationCopy2,jvmTestImplementationCopy2
org.jetbrains.kotlin:kotlin-test:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=kotlinBuildToolsApiClasspath
org.jetbrains:annotations:13.0=commonTestImplementationCopy,jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestImplementationCopy,jvmTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataCommonMain,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath
empty=allSourceSetsCompileDependenciesMetadataCopy,allSourceSetsRuntimeDependenciesMetadataCopy,archives,archivesCopy,commonMainApiDependenciesMetadataCopy,commonMainCompileOnlyCopy,commonMainImplementationCopy,commonMainIntransitiveDependenciesMetadata,commonMainIntransitiveDependenciesMetadataCopy,commonMainRuntimeOnlyCopy,commonMainRuntimeOnlyDependenciesMetadata,commonTestCompileOnlyCopy,commonTestIntransitiveDependenciesMetadata,commonTestIntransitiveDependenciesMetadataCopy,commonTestRuntimeOnlyCopy,commonTestRuntimeOnlyDependenciesMetadata,default,defaultCopy,jvmCompileOnlyCopy,jvmMainApiCopy,jvmMainCompileOnlyCopy,jvmMainImplementationCopy,jvmMainIntransitiveDependenciesMetadata,jvmMainIntransitiveDependenciesMetadataCopy,jvmMainRuntimeOnlyCopy,jvmMainRuntimeOnlyDependenciesMetadata,jvmRuntimeOnlyCopy,jvmSourceArtifactsCopy,jvmTestCompileOnlyCopy,jvmTestIntransitiveDependenciesMetadata,jvmTestIntransitiveDependenciesMetadataCopy,jvmTestRuntimeOnlyCopy,jvmTestRuntimeOnlyDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathCopy,kotlinNativeCompilerPluginClasspath,kotlinNativeCompilerPluginClasspathCopy,kotlinScriptDef,kotlinScriptDefCopy,kotlinScriptDefExtensions,kotlinScriptDefExtensionsCopy,metadataCommonMainCompileOnlyCopy,metadataCompileOnlyCopy,testKotlinScriptDef,testKotlinScriptDefCopy,testKotlinScriptDefExtensions,testKotlinScriptDefExtensionsCopy

View File

@ -97,6 +97,7 @@ tasks {
"ZCASH_EMULATOR_WTF_API_KEY" to "",
"IS_MINIFY_ENABLED" to "true",
"NDK_DEBUG_SYMBOL_LEVEL" to "symbol_table",
"ZCASH_RELEASE_APP_NAME" to "Zashi",
"ZCASH_RELEASE_PACKAGE_NAME" to "co.electriccoin.zcash",

View File

@ -1,35 +1,35 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
org.gradle.kotlin.kotlin-dsl.base:org.gradle.kotlin.kotlin-dsl.base.gradle.plugin:4.2.1=classpath
org.gradle.kotlin:gradle-kotlin-dsl-plugins:4.2.1=classpath
org.gradle.kotlin.kotlin-dsl.base:org.gradle.kotlin.kotlin-dsl.base.gradle.plugin:4.3.0=classpath
org.gradle.kotlin:gradle-kotlin-dsl-plugins:4.3.0=classpath
org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
org.jetbrains.kotlin:kotlin-android-extensions:1.9.20=classpath
org.jetbrains.kotlin:kotlin-assignment:1.9.20=classpath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.20=classpath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.20=classpath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.20=classpath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.20=classpath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20=classpath
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.20=classpath
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.20=classpath
org.jetbrains.kotlin:kotlin-native-utils:1.9.20=classpath
org.jetbrains.kotlin:kotlin-project-model:1.9.20=classpath
org.jetbrains.kotlin:kotlin-sam-with-receiver:1.9.20=classpath
org.jetbrains.kotlin:kotlin-scripting-common:1.9.20=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.20=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.20=classpath
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.20=classpath
org.jetbrains.kotlin:kotlin-stdlib:1.9.20=classpath
org.jetbrains.kotlin:kotlin-tooling-core:1.9.20=classpath
org.jetbrains.kotlin:kotlin-util-io:1.9.20=classpath
org.jetbrains.kotlin:kotlin-util-klib:1.9.20=classpath
org.jetbrains.kotlin:kotlin-android-extensions:1.9.22=classpath
org.jetbrains.kotlin:kotlin-assignment:1.9.22=classpath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.22=classpath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.22=classpath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.22=classpath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.22=classpath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.22=classpath
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.22=classpath
org.jetbrains.kotlin:kotlin-native-utils:1.9.22=classpath
org.jetbrains.kotlin:kotlin-project-model:1.9.22=classpath
org.jetbrains.kotlin:kotlin-sam-with-receiver:1.9.22=classpath
org.jetbrains.kotlin:kotlin-scripting-common:1.9.22=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.22=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.22=classpath
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.22=classpath
org.jetbrains.kotlin:kotlin-stdlib:1.9.22=classpath
org.jetbrains.kotlin:kotlin-tooling-core:1.9.22=classpath
org.jetbrains.kotlin:kotlin-util-io:1.9.22=classpath
org.jetbrains.kotlin:kotlin-util-klib:1.9.22=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
org.jetbrains:annotations:13.0=classpath
empty=

View File

@ -4,33 +4,28 @@
com.googlecode.javaewah:JavaEWAH:1.1.13=buildScriptClasspath,compileClasspath,testCompileClasspath,testRuntimeClasspath
org.eclipse.jgit:org.eclipse.jgit:6.4.0.202211300538-r=buildScriptClasspath,compileClasspath,testCompileClasspath,testRuntimeClasspath
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-assignment-compiler-plugin-embeddable:1.9.20=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.20=kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.20=kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-assignment-compiler-plugin-embeddable:1.9.22=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.22=kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.22=kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-native-utils:1.7.10=kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-project-model:1.7.10=kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinCompilerClasspath
org.jetbrains.kotlin:kotlin-reflect:1.7.10=testCompileClasspath,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-reflect:1.9.20=compileClasspath
org.jetbrains.kotlin:kotlin-sam-with-receiver-compiler-plugin-embeddable:1.9.20=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-reflect:1.9.22=compileClasspath
org.jetbrains.kotlin:kotlin-sam-with-receiver-compiler-plugin-embeddable:1.9.22=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-sam-with-receiver:1.7.10=kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-script-runtime:1.9.20=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-script-runtime:1.9.22=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-common:1.9.20=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.22=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.20=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.22=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.20=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.22=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.20=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=kotlinCompilerPluginClasspathTest,testCompileClasspath,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=testCompileClasspath,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10=testCompileClasspath,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.7.10=kotlinCompilerPluginClasspathTest,testCompileClasspath,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.9.20=compileClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.22=kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-stdlib:1.9.22=compileClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain
org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-util-io:1.7.10=kotlinCompilerPluginClasspathTest
org.jetbrains:annotations:13.0=compileClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,testCompileClasspath,testRuntimeClasspath

View File

@ -1,81 +1,80 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
androidx.databinding:databinding-common:8.1.1=classpath
androidx.databinding:databinding-compiler-common:8.1.1=classpath
com.android.databinding:baseLibrary:8.1.1=classpath
com.android.tools.analytics-library:crash:31.1.1=classpath
com.android.tools.analytics-library:protos:31.1.1=classpath
com.android.tools.analytics-library:shared:31.1.1=classpath
com.android.tools.analytics-library:tracker:31.1.1=classpath
androidx.databinding:databinding-common:8.3.0=classpath
androidx.databinding:databinding-compiler-common:8.3.0=classpath
com.android.databinding:baseLibrary:8.3.0=classpath
com.android.tools.analytics-library:crash:31.3.0=classpath
com.android.tools.analytics-library:protos:31.3.0=classpath
com.android.tools.analytics-library:shared:31.3.0=classpath
com.android.tools.analytics-library:tracker:31.3.0=classpath
com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
com.android.tools.build:aapt2-proto:8.1.1-10154469=classpath
com.android.tools.build:aaptcompiler:8.1.1=classpath
com.android.tools.build:apksig:8.1.1=classpath
com.android.tools.build:apkzlib:8.1.1=classpath
com.android.tools.build:builder-model:8.1.1=classpath
com.android.tools.build:builder-test-api:8.1.1=classpath
com.android.tools.build:builder:8.1.1=classpath
com.android.tools.build:bundletool:1.14.0=classpath
com.android.tools.build:gradle-api:8.1.1=classpath
com.android.tools.build:gradle-settings-api:8.1.1=classpath
com.android.tools.build:gradle:8.1.1=classpath
com.android.tools.build:manifest-merger:31.1.1=classpath
com.android.tools.build:aapt2-proto:8.3.0-10880808=classpath
com.android.tools.build:aaptcompiler:8.3.0=classpath
com.android.tools.build:apksig:8.3.0=classpath
com.android.tools.build:apkzlib:8.3.0=classpath
com.android.tools.build:builder-model:8.3.0=classpath
com.android.tools.build:builder-test-api:8.3.0=classpath
com.android.tools.build:builder:8.3.0=classpath
com.android.tools.build:bundletool:1.15.6=classpath
com.android.tools.build:gradle-api:8.3.0=classpath
com.android.tools.build:gradle-settings-api:8.3.0=classpath
com.android.tools.build:gradle:8.3.0=classpath
com.android.tools.build:manifest-merger:31.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
com.android.tools.ddms:ddmlib:31.1.1=classpath
com.android.tools.layoutlib:layoutlib-api:31.1.1=classpath
com.android.tools.lint:lint-model:31.1.1=classpath
com.android.tools.lint:lint-typedef-remover:31.1.1=classpath
com.android.tools.utp:android-device-provider-ddmlib-proto:31.1.1=classpath
com.android.tools.utp:android-device-provider-gradle-proto:31.1.1=classpath
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.1.1=classpath
com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.1.1=classpath
com.android.tools.utp:android-test-plugin-host-coverage-proto:31.1.1=classpath
com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.1.1=classpath
com.android.tools.utp:android-test-plugin-host-logcat-proto:31.1.1=classpath
com.android.tools.utp:android-test-plugin-host-retention-proto:31.1.1=classpath
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.1.1=classpath
com.android.tools:annotations:31.1.1=classpath
com.android.tools:common:31.1.1=classpath
com.android.tools:dvlib:31.1.1=classpath
com.android.tools:repository:31.1.1=classpath
com.android.tools:sdk-common:31.1.1=classpath
com.android.tools:sdklib:31.1.1=classpath
com.android:signflinger:8.1.1=classpath
com.android:zipflinger:8.1.1=classpath
com.github.ben-manes.versions:com.github.ben-manes.versions.gradle.plugin:0.42.0=classpathCopy,classpathCopy2
com.github.ben-manes.versions:com.github.ben-manes.versions.gradle.plugin:0.47.0=classpath
com.github.ben-manes:gradle-versions-plugin:0.47.0=classpath
com.android.tools.ddms:ddmlib:31.3.0=classpath
com.android.tools.layoutlib:layoutlib-api:31.3.0=classpath
com.android.tools.lint:lint-model:31.3.0=classpath
com.android.tools.lint:lint-typedef-remover:31.3.0=classpath
com.android.tools.utp:android-device-provider-ddmlib-proto:31.3.0=classpath
com.android.tools.utp:android-device-provider-gradle-proto:31.3.0=classpath
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.3.0=classpath
com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.3.0=classpath
com.android.tools.utp:android-test-plugin-host-coverage-proto:31.3.0=classpath
com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.3.0=classpath
com.android.tools.utp:android-test-plugin-host-logcat-proto:31.3.0=classpath
com.android.tools.utp:android-test-plugin-host-retention-proto:31.3.0=classpath
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.3.0=classpath
com.android.tools:annotations:31.3.0=classpath
com.android.tools:common:31.3.0=classpath
com.android.tools:dvlib:31.3.0=classpath
com.android.tools:repository:31.3.0=classpath
com.android.tools:sdk-common:31.3.0=classpath
com.android.tools:sdklib:31.3.0=classpath
com.android:signflinger:8.3.0=classpath
com.android:zipflinger:8.3.0=classpath
com.github.ben-manes.versions:com.github.ben-manes.versions.gradle.plugin:0.51.0=classpath,classpathCopy,classpathCopy2
com.github.ben-manes:gradle-versions-plugin:0.51.0=classpath
com.google.android.gms:strict-version-matcher-plugin:1.2.4=classpath
com.google.android:annotations:4.1.1.4=classpath
com.google.api-client:google-api-client:2.2.0=classpath
com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.api.grpc:proto-google-common-protos:2.17.0=classpath
com.google.apis:google-api-services-androidpublisher:v3-rev20231030-2.0.0=classpath
com.google.auth:google-auth-library-credentials:1.18.0=classpath
com.google.auth:google-auth-library-oauth2-http:1.18.0=classpath
com.google.auto.value:auto-value-annotations:1.10.1=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
com.google.code.gson:gson:2.10=classpath
com.google.code.gson:gson:2.10.1=classpath
com.google.crypto.tink:tink:1.7.0=classpath
com.google.dagger:dagger:2.28.3=classpath
com.google.errorprone:error_prone_annotations:2.16=classpath
com.google.firebase:firebase-crashlytics-buildtools:2.9.4=classpath
com.google.firebase:firebase-crashlytics-gradle:2.9.4=classpath
com.google.errorprone:error_prone_annotations:2.18.0=classpath
com.google.firebase:firebase-crashlytics-buildtools:2.9.9=classpath
com.google.firebase:firebase-crashlytics-gradle:2.9.9=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.gms:google-services:4.3.15=classpath
com.google.gms:google-services:4.4.1=classpath
com.google.guava:failureaccess:1.0.1=classpath
com.google.guava:guava:31.1-jre=classpath
com.google.guava:guava:32.0.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.http-client:google-http-client-apache-v2:1.42.3=classpath
com.google.http-client:google-http-client-gson:1.42.3=classpath
com.google.http-client:google-http-client:1.42.3=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.j2objc:j2objc-annotations:2.8=classpath
com.google.jimfs:jimfs:1.1=classpath
com.google.oauth-client:google-oauth-client:1.34.1=classpath
com.google.protobuf:protobuf-java-util:3.19.3=classpath
com.google.protobuf:protobuf-java:3.19.3=classpath
com.google.testing.platform:core-proto:0.0.8-alpha08=classpath
com.google.protobuf:protobuf-java-util:3.22.3=classpath
com.google.protobuf:protobuf-java:3.22.3=classpath
com.google.testing.platform:core-proto:0.0.9-alpha02=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
com.osacky.flank.gradle:fladle:0.17.4=classpath
com.osacky.fulladle:com.osacky.fulladle.gradle.plugin:0.17.3=classpathCopy
@ -90,36 +89,34 @@ com.squareup:javawriter:2.5.0=classpath
com.sun.activation:javax.activation:1.2.0=classpath
com.sun.istack:istack-commons-runtime:3.0.8=classpath
com.sun.xml.fastinfoset:FastInfoset:1.2.16=classpath
com.thoughtworks.xstream:xstream:1.4.20=classpath
com.vdurmont:semver4j:3.1.0=classpath
commons-codec:commons-codec:1.15=classpath
commons-io:commons-io:2.12.0=classpath
commons-io:commons-io:2.15.1=classpath
commons-logging:commons-logging:1.2=classpath
io.github.x-stream:mxparser:1.2.2=classpath
io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.0=classpath
io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.6=classpath
io.gitlab.arturbosch.detekt:io.gitlab.arturbosch.detekt.gradle.plugin:1.19.0=classpathCopy
io.gitlab.arturbosch.detekt:io.gitlab.arturbosch.detekt.gradle.plugin:1.20.0=classpathCopy2
io.grpc:grpc-api:1.45.1=classpath
io.grpc:grpc-context:1.45.1=classpath
io.grpc:grpc-core:1.45.1=classpath
io.grpc:grpc-netty:1.45.1=classpath
io.grpc:grpc-protobuf-lite:1.45.1=classpath
io.grpc:grpc-protobuf:1.45.1=classpath
io.grpc:grpc-stub:1.45.1=classpath
io.netty:netty-buffer:4.1.72.Final=classpath
io.netty:netty-codec-http2:4.1.72.Final=classpath
io.netty:netty-codec-http:4.1.72.Final=classpath
io.netty:netty-codec-socks:4.1.72.Final=classpath
io.netty:netty-codec:4.1.72.Final=classpath
io.netty:netty-common:4.1.72.Final=classpath
io.netty:netty-handler-proxy:4.1.72.Final=classpath
io.netty:netty-handler:4.1.72.Final=classpath
io.netty:netty-resolver:4.1.72.Final=classpath
io.netty:netty-tcnative-classes:2.0.46.Final=classpath
io.netty:netty-transport:4.1.72.Final=classpath
io.grpc:grpc-api:1.57.0=classpath
io.grpc:grpc-context:1.57.0=classpath
io.grpc:grpc-core:1.57.0=classpath
io.grpc:grpc-netty:1.57.0=classpath
io.grpc:grpc-protobuf-lite:1.57.0=classpath
io.grpc:grpc-protobuf:1.57.0=classpath
io.grpc:grpc-stub:1.57.0=classpath
io.netty:netty-buffer:4.1.93.Final=classpath
io.netty:netty-codec-http2:4.1.93.Final=classpath
io.netty:netty-codec-http:4.1.93.Final=classpath
io.netty:netty-codec-socks:4.1.93.Final=classpath
io.netty:netty-codec:4.1.93.Final=classpath
io.netty:netty-common:4.1.93.Final=classpath
io.netty:netty-handler-proxy:4.1.93.Final=classpath
io.netty:netty-handler:4.1.93.Final=classpath
io.netty:netty-resolver:4.1.93.Final=classpath
io.netty:netty-transport-native-unix-common:4.1.93.Final=classpath
io.netty:netty-transport:4.1.93.Final=classpath
io.opencensus:opencensus-api:0.31.1=classpath
io.opencensus:opencensus-contrib-http-util:0.31.1=classpath
io.perfmark:perfmark-api:0.23.0=classpath
io.perfmark:perfmark-api:0.26.0=classpath
jakarta.activation:jakarta.activation-api:1.2.1=classpath
jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
javax.annotation:javax.annotation-api:1.3.2=classpath
@ -135,60 +132,57 @@ org.apache.httpcomponents:httpmime:4.5.6=classpath
org.bitbucket.b_c:jose4j:0.7.0=classpath
org.bouncycastle:bcpkix-jdk15on:1.67=classpath
org.bouncycastle:bcprov-jdk15on:1.67=classpath
org.checkerframework:checker-qual:3.12.0=classpath
org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
org.checkerframework:checker-qual:3.33.0=classpath
org.codehaus.mojo:animal-sniffer-annotations:1.23=classpath
org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
org.jetbrains.kotlin:kotlin-android-extensions:1.9.21=classpath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.21=classpath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.21=classpath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.21=classpath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.21=classpath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.21=classpath
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.21=classpath
org.jetbrains.kotlin:kotlin-native-utils:1.9.21=classpath
org.jetbrains.kotlin:kotlin-project-model:1.9.21=classpath
org.jetbrains.kotlin:kotlin-reflect:1.9.20=classpath
org.jetbrains.kotlin:kotlin-scripting-common:1.9.21=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.21=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.21=classpath
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.21=classpath
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.20=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.21=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21=classpath
org.jetbrains.kotlin:kotlin-stdlib:1.9.20=classpath
org.jetbrains.kotlin:kotlin-tooling-core:1.9.21=classpath
org.jetbrains.kotlin:kotlin-util-io:1.9.21=classpath
org.jetbrains.kotlin:kotlin-util-klib:1.9.21=classpath
org.jetbrains.kotlin:kotlin-android-extensions:1.9.23=classpath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.23=classpath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.23=classpath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.23=classpath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.23=classpath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.23=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.23=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.23=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.23=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.23=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.23=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.23=classpath
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.23=classpath
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.23=classpath
org.jetbrains.kotlin:kotlin-native-utils:1.9.23=classpath
org.jetbrains.kotlin:kotlin-project-model:1.9.23=classpath
org.jetbrains.kotlin:kotlin-reflect:1.9.22=classpath
org.jetbrains.kotlin:kotlin-scripting-common:1.9.23=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.23=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.23=classpath
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.23=classpath
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.22=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.20=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.20=classpath
org.jetbrains.kotlin:kotlin-stdlib:1.9.22=classpath
org.jetbrains.kotlin:kotlin-tooling-core:1.9.23=classpath
org.jetbrains.kotlin:kotlin-util-io:1.9.23=classpath
org.jetbrains.kotlin:kotlin-util-klib:1.9.23=classpath
org.jetbrains.kotlinx.kover:org.jetbrains.kotlinx.kover.gradle.plugin:0.7.3=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
org.jetbrains.kotlinx:kover-gradle-plugin:0.7.3=classpath
org.jetbrains:annotations:13.0=classpath
org.json:json:20230227=classpath
org.json:json:20240205=classpath
org.jvnet.staxex:stax-ex:1.8.1=classpath
org.ow2.asm:asm-analysis:9.2=classpath
org.ow2.asm:asm-commons:9.2=classpath
org.ow2.asm:asm-tree:9.2=classpath
org.ow2.asm:asm-util:9.2=classpath
org.ow2.asm:asm:9.2=classpath
org.ow2.asm:asm-analysis:9.6=classpath
org.ow2.asm:asm-commons:9.6=classpath
org.ow2.asm:asm-tree:9.6=classpath
org.ow2.asm:asm-util:9.6=classpath
org.ow2.asm:asm:9.6=classpath
org.slf4j:slf4j-api:1.7.30=classpath
org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
wtf.emulator:gradle-compat-6-1:0.15.1=classpath
wtf.emulator:gradle-compat-6-6:0.15.1=classpath
wtf.emulator:gradle-compat-7-6:0.15.1=classpath
wtf.emulator:gradle-compat-api:0.15.1=classpath
wtf.emulator:gradle-compat:0.15.1=classpath
wtf.emulator:gradle-plugin:0.15.1=classpath
xerces:xercesImpl:2.12.0=classpath
xml-apis:xml-apis:1.4.01=classpath
xmlpull:xmlpull:1.1.3.1=classpath
wtf.emulator:gradle-compat-6-1:0.16.2=classpath
wtf.emulator:gradle-compat-6-6:0.16.2=classpath
wtf.emulator:gradle-compat-7-6:0.16.2=classpath
wtf.emulator:gradle-compat-api:0.16.2=classpath
wtf.emulator:gradle-compat:0.16.2=classpath
wtf.emulator:gradle-plugin:0.16.2=classpath
empty=

View File

@ -8,53 +8,51 @@ org.jetbrains.intellij.deps:coverage-report:1.0.21=koverJvmReporter
org.jetbrains.intellij.deps:intellij-coverage-agent:1.0.724=koverJvmAgent,koverJvmReporter
org.jetbrains.intellij.deps:intellij-coverage-reporter:1.0.724=koverJvmReporter
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-build-common:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.21=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-build-common:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.23=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-script-runtime:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.10=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain,metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCommonMainCompileClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCommonMainCompileClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20=metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20=metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.8.20=metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-stdlib:1.9.21=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-test-annotations-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-junit:1.9.21=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.9.23=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-test-annotations-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-junit:1.9.23=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:atomicfu:0.17.3=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlinx:atomicfu:0.20.2=metadataCommonMainCompileClasspath
org.jetbrains.kotlinx:atomicfu:0.21.0=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.6=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:atomicfu:0.23.1=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.7=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.5=allSourceSetsRuntimeDependenciesMetadata,metadataCommonMainCompileClasspath
org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.6=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=kotlinBuildToolsApiClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1=metadataCommonMainCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.7.3=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.8.0=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.5.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-datetime:0.4.0=allSourceSetsRuntimeDependenciesMetadata,metadataCommonMainCompileClasspath
org.jetbrains.kotlinx:kotlinx-datetime:0.5.0=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCompileClasspath

View File

@ -40,6 +40,8 @@ private data class MergingConfiguration(private val configurations: PersistentLi
return null != configurations.firstWithKey(key)
}
// TODO [#1373]: Catch and log Configuration Key Coercion Failures
// TODO [#1373]: https://github.com/Electric-Coin-Company/zashi-android/issues/1373
override fun getBoolean(
key: ConfigKey,
defaultValue: Boolean
@ -49,6 +51,8 @@ private data class MergingConfiguration(private val configurations: PersistentLi
} ?: defaultValue
}
// TODO [#1373]: Catch and log Configuration Key Coercion Failures
// TODO [#1373]: https://github.com/Electric-Coin-Company/zashi-android/issues/1373
override fun getInt(
key: ConfigKey,
defaultValue: Int

View File

@ -6,5 +6,7 @@ data class BooleanConfigurationEntry(
override val key: ConfigKey,
private val defaultValue: Boolean
) : DefaultEntry<Boolean> {
// TODO [#1373]: Catch and log Configuration Key Coercion Failures
// TODO [#1373]: https://github.com/Electric-Coin-Company/zashi-android/issues/1373
override fun getValue(configuration: Configuration) = configuration.getBoolean(key, defaultValue)
}

View File

@ -6,5 +6,7 @@ data class IntegerConfigurationEntry(
override val key: ConfigKey,
private val defaultValue: Int
) : DefaultEntry<Int> {
// TODO [#1373]: Catch and log Configuration Key Coercion Failures
// TODO [#1373]: https://github.com/Electric-Coin-Company/zashi-android/issues/1373
override fun getValue(configuration: Configuration) = configuration.getInt(key, defaultValue)
}

View File

@ -0,0 +1,7 @@
package co.electriccoin.zcash.configuration.model.exception
/**
* Exception that may occur when parsing a value from the remote configuration. This could mean that someone made an
* error in the remote config console.
*/
class ConfigurationParseException(message: String, cause: Throwable?) : IllegalArgumentException(message, cause)

View File

@ -1,6 +1,7 @@
package co.electriccoin.zcash.configuration.model.map
import co.electriccoin.zcash.configuration.model.entry.ConfigKey
import co.electriccoin.zcash.configuration.model.exception.ConfigurationParseException
import kotlinx.collections.immutable.PersistentMap
import kotlinx.datetime.Instant
@ -10,31 +11,35 @@ data class StringConfiguration(
val configurationMapping: PersistentMap<String, String>,
override val updatedAt: Instant?
) : Configuration {
@Throws(ConfigurationParseException::class)
override fun getBoolean(
key: ConfigKey,
defaultValue: Boolean
) = configurationMapping[key.key]?.let {
try {
it.toBooleanStrict()
} catch (
@Suppress("SwallowedException") e: IllegalArgumentException
) {
// In the future, log coercion failure as this could mean someone made an error in the remote config console
defaultValue
} catch (e: IllegalArgumentException) {
throw ConfigurationParseException(
"Failed while parsing String value to Boolean. This could mean " +
"someone made an error in the remote config console",
e
)
}
} ?: defaultValue
@Throws(ConfigurationParseException::class)
override fun getInt(
key: ConfigKey,
defaultValue: Int
) = configurationMapping[key.key]?.let {
try {
it.toInt()
} catch (
@Suppress("SwallowedException") e: NumberFormatException
) {
// In the future, log coercion failure as this could mean someone made an error in the remote config console
defaultValue
} catch (e: IllegalArgumentException) {
throw ConfigurationParseException(
"Failed while parsing String value to Int. This could mean " +
"someone made an error in the remote config console",
e
)
}
} ?: defaultValue

View File

@ -1,6 +1,7 @@
package co.electriccoin.zcash.configuration.test
import co.electriccoin.zcash.configuration.model.entry.ConfigKey
import co.electriccoin.zcash.configuration.model.exception.ConfigurationParseException
import co.electriccoin.zcash.configuration.model.map.Configuration
import kotlinx.datetime.Instant
@ -13,31 +14,35 @@ import kotlinx.datetime.Instant
class MockConfiguration(private val configurationMapping: Map<String, String> = emptyMap()) : Configuration {
override val updatedAt: Instant? = null
@Throws(ConfigurationParseException::class)
override fun getBoolean(
key: ConfigKey,
defaultValue: Boolean
) = configurationMapping[key.key]?.let {
try {
it.toBooleanStrict()
} catch (
@Suppress("SwallowedException") e: IllegalArgumentException
) {
// In the future, log coercion failure as this could mean someone made an error in the remote config console
defaultValue
} catch (e: IllegalArgumentException) {
throw ConfigurationParseException(
"Failed while parsing String value to Boolean. This could mean " +
"someone made an error in the remote config console",
e
)
}
} ?: defaultValue
@Throws(ConfigurationParseException::class)
override fun getInt(
key: ConfigKey,
defaultValue: Int
) = configurationMapping[key.key]?.let {
try {
it.toInt()
} catch (
@Suppress("SwallowedException") e: NumberFormatException
) {
// In the future, log coercion failure as this could mean someone made an error in the remote config console
defaultValue
} catch (e: IllegalArgumentException) {
throw ConfigurationParseException(
"Failed while parsing String value to Int. This could mean " +
"someone made an error in the remote config console",
e
)
}
} ?: defaultValue

View File

@ -69,7 +69,12 @@ private class FirebaseCrashReporterImpl(
) : CrashReporter {
@AnyThread
override fun reportCaughtException(exception: Throwable) {
firebaseCrashlytics.recordException(exception)
error(
"Although most of the sensitive model objects implement custom [toString] methods to redact information" +
" if they were to be logged (which includes exceptions), we're encouraged to disable caught exception" +
" reporting to the remote Crashlytics service due to its security risk. Use the the local variant of" +
" the reporter to report caught exception - [LocalCrashReporter]."
)
}
override fun enable() {

View File

@ -8,70 +8,70 @@ org.jetbrains.intellij.deps:coverage-report:1.0.21=koverJvmReporter
org.jetbrains.intellij.deps:intellij-coverage-agent:1.0.724=koverJvmAgent,koverJvmReporter
org.jetbrains.intellij.deps:intellij-coverage-reporter:1.0.724=koverJvmReporter
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-build-common:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-common:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.6.20=kotlinCompilerClasspathCopy
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.6.20=kotlinKlibCommonizerClasspathCopy
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.21=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.23=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-script-runtime:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.6.20=kotlinCompilerPluginClasspathJvmMainCopy,kotlinCompilerPluginClasspathJvmTestCopy,kotlinCompilerPluginClasspathMetadataCommonMainCopy,kotlinCompilerPluginClasspathMetadataMainCopy
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.6.21=kotlinCompilerPluginClasspathJvmMainCopy2,kotlinCompilerPluginClasspathJvmTestCopy2,kotlinCompilerPluginClasspathMetadataCommonMainCopy2,kotlinCompilerPluginClasspathMetadataMainCopy2
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-stdlib-common:1.6.20=commonTestImplementationCopy
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.10=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain,metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.0=commonTestImplementationCopy
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCommonMainCompileClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20=metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.0=commonTestImplementationCopy
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.20=allSourceSetsCompileDependenciesMetadataCopy,allSourceSetsRuntimeDependenciesMetadataCopy,commonMainApiCopy,commonTestApiCopy,compileClasspathCopy,jvmApiCopy,jvmApiElementsCopy,jvmCompileClasspathCopy,jvmImplementationCopy,jvmRuntimeClasspathCopy,jvmRuntimeElementsCopy,jvmTestCompileClasspathCopy,jvmTestRuntimeClasspathCopy,metadataApiCopy,metadataApiElementsCopy,metadataCommonMainApiCopy,metadataCommonMainCompileClasspathCopy,metadataCommonMainImplementationCopy,metadataCompileClasspathCopy,metadataImplementationCopy
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21=commonMainApiCopy2,jvmTestCompileClasspathCopy2,jvmTestRuntimeClasspathCopy2
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCommonMainCompileClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20=metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.6.20=commonTestImplementationCopy
org.jetbrains.kotlin:kotlin-stdlib:1.8.20=metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-stdlib:1.9.21=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-test-annotations-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-stdlib:1.9.23=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-test-annotations-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-junit:1.6.20=commonTestImplementationCopy
org.jetbrains.kotlin:kotlin-test-junit:1.9.21=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test-junit:1.9.23=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test:1.6.20=commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlin:kotlin-test:1.6.21=commonTestImplementationCopy2
org.jetbrains.kotlin:kotlin-test:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:atomicfu:0.17.3=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlinx:atomicfu:0.20.2=metadataCommonMainCompileClasspath
org.jetbrains.kotlinx:atomicfu:0.21.0=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlinx:atomicfu:0.23.1=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.1=commonTestImplementationCopy
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=kotlinBuildToolsApiClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.1=commonMainApiCopy,commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.2=commonMainApiCopy2,jvmTestCompileClasspathCopy2,jvmTestRuntimeClasspathCopy2
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1=commonMainApiCopy,commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2=commonMainApiCopy2,jvmTestCompileClasspathCopy2,jvmTestRuntimeClasspathCopy2
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1=metadataCommonMainCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.6.1=commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.6.2=commonTestImplementationCopy2
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.7.3=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.8.0=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.1=commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.2=commonTestImplementationCopy2
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.3.2=commonMainApiCopy,jvmTestCompileClasspathCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.3.3=commonMainApiCopy2,jvmTestCompileClasspathCopy2,jvmTestRuntimeClasspathCopy2
org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.5.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath

View File

@ -50,11 +50,19 @@ ZCASH_FIREBASE_TEST_LAB_PROJECT=
# Optionally disable minification
IS_MINIFY_ENABLED=true
# Optionally change the NDK debug symbols generation level
# Supported values are:
# - none (default, no native debug metadata will be packaged)
# - symbol_table (only the symbol tables will be packaged)
# - full (the debug info and symbol tables will be packaged)
# The result will be placed in app/build/outputs/native-debug-symbols/variant-name/native-debug-symbols.zip
NDK_DEBUG_SYMBOL_LEVEL=symbol_table
# If ZCASH_GOOGLE_PLAY_SERVICE_KEY_FILE_PATH is set and the deployment task is triggered, then
# VERSION_CODE is effectively ignored. VERSION_NAME is suffixed with the version code.
# If not using automated Google Play deployment, then these serve as the actual version numbers.
ZCASH_VERSION_CODE=1
ZCASH_VERSION_NAME=0.2.0
ZCASH_VERSION_NAME=1.0
# Set these fields, as you need them (e.g. with values "Zcash X" and "co.electriccoin.zcash.x")
# to distinguish a different release build that can be installed alongside the official version
@ -133,31 +141,32 @@ ANDROID_COMPILE_SDK_VERSION=34
ANDROID_NDK_VERSION=23.0.7599858
ANDROID_GRADLE_PLUGIN_VERSION=8.1.1
DETEKT_VERSION=1.23.0
DETEKT_COMPOSE_RULES_VERSION=0.3.5
EMULATOR_WTF_GRADLE_PLUGIN_VERSION=0.15.1
FIREBASE_CRASHLYTICS_BUILD_TOOLS_VERSION=2.9.4
ANDROID_GRADLE_PLUGIN_VERSION=8.3.0
DETEKT_VERSION=1.23.6
DETEKT_COMPOSE_RULES_VERSION=0.3.15
EMULATOR_WTF_GRADLE_PLUGIN_VERSION=0.16.2
FIREBASE_CRASHLYTICS_BUILD_TOOLS_VERSION=2.9.9
FLANK_VERSION=23.10.1
FULLADLE_VERSION=0.17.4
GOOGLE_PLAY_SERVICES_GRADLE_PLUGIN_VERSION=4.3.15
GRADLE_VERSIONS_PLUGIN_VERSION=0.47.0
GOOGLE_PLAY_SERVICES_GRADLE_PLUGIN_VERSION=4.4.1
GRADLE_VERSIONS_PLUGIN_VERSION=0.51.0
JGIT_VERSION=6.4.0.202211300538-r
KTLINT_VERSION=1.0.1
KTLINT_VERSION=1.2.1
ACCOMPANIST_PERMISSIONS_VERSION=0.32.0
ANDROIDX_ACTIVITY_VERSION=1.8.1
ANDROIDX_ANNOTATION_VERSION=1.7.0
ACCOMPANIST_PERMISSIONS_VERSION=0.34.0
ANDROIDX_ACTIVITY_VERSION=1.8.2
ANDROIDX_ANNOTATION_VERSION=1.7.1
ANDROIDX_APPCOMPAT_VERSION=1.6.1
ANDROIDX_CAMERA_VERSION=1.3.0
ANDROIDX_COMPOSE_COMPILER_VERSION=1.5.6
ANDROIDX_COMPOSE_MATERIAL3_VERSION=1.1.2
ANDROIDX_COMPOSE_MATERIAL_ICONS_VERSION=1.5.4
ANDROIDX_COMPOSE_VERSION=1.5.4
ANDROIDX_BIOMETRIC_VERSION=1.2.0-alpha05
ANDROIDX_CAMERA_VERSION=1.3.2
ANDROIDX_COMPOSE_COMPILER_VERSION=1.5.11
ANDROIDX_COMPOSE_MATERIAL3_VERSION=1.2.1
ANDROIDX_COMPOSE_MATERIAL_ICONS_VERSION=1.6.5
ANDROIDX_COMPOSE_VERSION=1.6.6
ANDROIDX_CONSTRAINTLAYOUT_VERSION=1.0.1
ANDROIDX_CORE_VERSION=1.9.0
ANDROIDX_CORE_VERSION=1.12.0
ANDROIDX_ESPRESSO_VERSION=3.5.1
ANDROIDX_LIFECYCLE_VERSION=2.6.2
ANDROIDX_LIFECYCLE_VERSION=2.7.0
ANDROIDX_NAVIGATION_COMPOSE_VERSION=2.7.7
ANDROIDX_PROFILE_INSTALLER_VERSION=1.3.1
ANDROIDX_SECURITY_CRYPTO_VERSION=1.1.0-alpha06
@ -165,31 +174,32 @@ ANDROIDX_SPLASH_SCREEN_VERSION=1.0.1
ANDROIDX_TEST_JUNIT_VERSION=1.1.5
ANDROIDX_TEST_ORCHESTRATOR_VERSION=1.4.2
ANDROIDX_TEST_CORE_VERSION=1.5.0
ANDROIDX_TEST_MACROBENCHMARK_VERSION=1.2.2
ANDROIDX_TEST_MACROBENCHMARK_VERSION=1.2.3
ANDROIDX_TEST_RUNNER_VERSION=1.5.2
ANDROIDX_STARTUP_VERSION=1.1.1
ANDROIDX_TEST_SERVICE_VERSION=1.4.2
ANDROIDX_UI_AUTOMATOR_VERSION=2.2.0-alpha1
ANDROIDX_UI_AUTOMATOR_VERSION=2.3.0
ANDROIDX_WORK_MANAGER_VERSION=2.9.0
CORE_LIBRARY_DESUGARING_VERSION=2.0.4
FIREBASE_BOM_VERSION_MATCHER=32.6.0
FIREBASE_BOM_VERSION_MATCHER=32.8.1
GOOGLE_AUTH_LIB_JAVA_VERSION=1.18.0
JACOCO_VERSION=0.8.9
KOTLIN_VERSION=1.9.21
KOTLINX_COROUTINES_VERSION=1.7.3
JACOCO_VERSION=0.8.12
KOTLIN_VERSION=1.9.23
KOTLINX_COROUTINES_VERSION=1.8.0
KOTLINX_DATETIME_VERSION=0.5.0
KOTLINX_IMMUTABLE_COLLECTIONS_VERSION=0.3.6
KOTLINX_IMMUTABLE_COLLECTIONS_VERSION=0.3.7
KOTLINX_SERIALIZABLE_JSON_VERSION=1.6.3
KOVER_VERSION=0.7.3
PLAY_APP_UPDATE_VERSION=2.1.0
PLAY_APP_UPDATE_KTX_VERSION=2.1.0
PLAY_PUBLISHER_API_VERSION=v3-rev20231030-2.0.0
ZCASH_ANDROID_WALLET_PLUGINS_VERSION=1.0.0
ZCASH_BIP39_VERSION=1.0.7
ZXING_VERSION=3.5.2
ZXING_VERSION=3.5.3
# WARNING: Ensure a non-snapshot version is used before releasing to production.
ZCASH_SDK_VERSION=2.0.8-SNAPSHOT
ZCASH_BIP39_VERSION=1.0.8
# WARNING: Ensure a non-snapshot version is used before releasing to production
ZCASH_SDK_VERSION=2.1.1-SNAPSHOT
# Toolchain is the Java version used to build the application, which is separate from the
# Java version used to run the application.

Binary file not shown.

View File

@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

20
gradlew.bat vendored
View File

@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail

View File

@ -8,64 +8,64 @@ org.jetbrains.intellij.deps:coverage-report:1.0.21=koverJvmReporter
org.jetbrains.intellij.deps:intellij-coverage-agent:1.0.724=koverJvmAgent,koverJvmReporter
org.jetbrains.intellij.deps:intellij-coverage-reporter:1.0.724=koverJvmReporter
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-build-common:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-common:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.6.20=kotlinCompilerClasspathCopy
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.6.20=kotlinKlibCommonizerClasspathCopy
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.21=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.23=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-script-runtime:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.6.20=kotlinCompilerPluginClasspathJvmMainCopy,kotlinCompilerPluginClasspathJvmTestCopy,kotlinCompilerPluginClasspathMetadataCommonMainCopy,kotlinCompilerPluginClasspathMetadataMainCopy
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.6.21=kotlinCompilerPluginClasspathJvmMainCopy2,kotlinCompilerPluginClasspathJvmTestCopy2,kotlinCompilerPluginClasspathMetadataCommonMainCopy2,kotlinCompilerPluginClasspathMetadataMainCopy2
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.10=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain,metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCommonMainCompileClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20=metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.20=commonMainApiCopy,commonMainApiCopy2,commonMainCompileOnlyDependenciesMetadataCopy,commonMainImplementationDependenciesMetadataCopy,commonMainRuntimeOnlyDependenciesMetadataCopy,commonTestApiCopy,commonTestApiDependenciesMetadataCopy,commonTestCompileOnlyDependenciesMetadataCopy,commonTestImplementationDependenciesMetadataCopy,commonTestRuntimeOnlyDependenciesMetadataCopy,compileClasspathCopy,jvmApiCopy,jvmApiElementsCopy,jvmCompileClasspathCopy,jvmImplementationCopy,jvmMainApiDependenciesMetadataCopy,jvmMainCompileOnlyDependenciesMetadataCopy,jvmMainImplementationDependenciesMetadataCopy,jvmMainRuntimeOnlyDependenciesMetadataCopy,jvmRuntimeClasspathCopy,jvmRuntimeElementsCopy,jvmTestApiCopy,jvmTestApiDependenciesMetadataCopy,jvmTestCompileClasspathCopy,jvmTestCompileOnlyDependenciesMetadataCopy,jvmTestImplementationCopy,jvmTestImplementationCopy2,jvmTestImplementationDependenciesMetadataCopy,jvmTestRuntimeClasspathCopy,jvmTestRuntimeOnlyDependenciesMetadataCopy,metadataApiCopy,metadataApiElementsCopy,metadataCommonMainApiCopy,metadataCommonMainCompileClasspathCopy,metadataCommonMainImplementationCopy,metadataCompileClasspathCopy,metadataImplementationCopy
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21=jvmTestCompileClasspathCopy2,jvmTestRuntimeClasspathCopy2
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCommonMainCompileClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20=metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.8.20=metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-stdlib:1.9.21=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-test-annotations-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-junit:1.9.21=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.9.23=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-test-annotations-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-junit:1.9.23=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test:1.6.20=commonTestImplementationCopy,commonTestImplementationDependenciesMetadataCopy,jvmTestCompileClasspathCopy,jvmTestCompileClasspathCopy2,jvmTestImplementationCopy,jvmTestImplementationDependenciesMetadataCopy,jvmTestRuntimeClasspathCopy,jvmTestRuntimeClasspathCopy2
org.jetbrains.kotlin:kotlin-test:1.6.21=commonTestImplementationCopy2,jvmTestImplementationCopy2
org.jetbrains.kotlin:kotlin-test:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:atomicfu:0.17.3=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlinx:atomicfu:0.20.2=metadataCommonMainCompileClasspath
org.jetbrains.kotlinx:atomicfu:0.21.0=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:atomicfu:0.23.1=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=kotlinBuildToolsApiClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.1=commonMainApiCopy,jvmTestCompileClasspathCopy,jvmTestImplementationCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.2=commonMainApiCopy2,jvmTestCompileClasspathCopy2,jvmTestRuntimeClasspathCopy2
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1=commonMainApiCopy,jvmTestCompileClasspathCopy,jvmTestImplementationCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2=commonMainApiCopy2,jvmTestCompileClasspathCopy2,jvmTestRuntimeClasspathCopy2
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1=metadataCommonMainCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.6.1=commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestImplementationCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.6.2=commonTestImplementationCopy2
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.7.3=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.8.0=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.1=commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestImplementationCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.2=commonTestImplementationCopy2
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains:annotations:13.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataCommonMain,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,metadataCommonMainCompileClasspath
org.jetbrains:annotations:16.0.2=koverJvmReporter
org.jetbrains:annotations:23.0.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath

View File

@ -14,4 +14,6 @@ interface PreferenceProvider {
suspend fun getString(key: PreferenceKey): String?
fun observe(key: PreferenceKey): Flow<String?>
suspend fun clearPreferences(): Boolean
}

View File

@ -18,6 +18,11 @@ class MockPreferenceProvider(
// For the mock implementation, does not support observability of changes
override fun observe(key: PreferenceKey): Flow<String?> = flow { emit(getString(key)) }
override suspend fun clearPreferences(): Boolean {
map.clear()
return true
}
override suspend fun hasKey(key: PreferenceKey) = map.containsKey(key.key)
override suspend fun putString(

View File

@ -59,6 +59,16 @@ class AndroidPreferenceProvider(
sharedPreferences.getString(key.key, null)
}
@SuppressLint("ApplySharedPref")
override suspend fun clearPreferences() =
withContext(dispatcher) {
val editor = sharedPreferences.edit()
editor.clear()
return@withContext editor.commit()
}
override fun observe(key: PreferenceKey): Flow<String?> =
callbackFlow<Unit> {
val listener =
@ -108,7 +118,6 @@ class AndroidPreferenceProvider(
val mainKey =
withContext(singleThreadedDispatcher) {
@Suppress("BlockingMethodInNonBlockingContext")
MasterKey.Builder(context).apply {
setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
}.build()
@ -116,7 +125,6 @@ class AndroidPreferenceProvider(
val sharedPreferences =
withContext(singleThreadedDispatcher) {
@Suppress("BlockingMethodInNonBlockingContext")
EncryptedSharedPreferences.create(
context,
filename,

View File

@ -33,7 +33,7 @@ class PercentDecimalExtTest {
runTest {
val parsed = PercentDecimal(1f).toPercentageWithDecimal()
assertEquals("100${MonetarySeparators.current(Locale.US).decimal}00", parsed)
assertEquals("100${MonetarySeparators.current(Locale.getDefault()).decimal}00", parsed)
}
@Test

View File

@ -7,13 +7,14 @@ import cash.z.ecc.sdk.fixture.Zip321UriBuildFixture
import cash.z.ecc.sdk.fixture.Zip321UriParseFixture
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import org.junit.Ignore
import org.junit.Test
import kotlin.test.Ignore
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
@Ignore("Disabled until the issue #397 is addressed")
class ZecRequestTest {
companion object {
private const val URI: String = "zcash:tmXuTnE11JojToagTqxXUn6KvdxDE3iLKbp?amount=1&message=Hello%20world!"

View File

@ -1,29 +1,18 @@
@file:Suppress("ktlint:standard:filename")
@file:Suppress("ktlint:standard:filename", "MagicNumber")
package cash.z.ecc.sdk.extension
import cash.z.ecc.android.sdk.model.ZcashNetwork
import co.electriccoin.lightwallet.client.model.LightWalletEndpoint
/*
* This set of extension functions suit for default values for the SDK initialization.
* Used for testing purposes only
*/
fun LightWalletEndpoint.Companion.defaultForNetwork(zcashNetwork: ZcashNetwork): LightWalletEndpoint {
return when (zcashNetwork.id) {
ZcashNetwork.Mainnet.id -> LightWalletEndpoint.Mainnet
ZcashNetwork.Testnet.id -> LightWalletEndpoint.Testnet
else -> error("Unknown network id: ${zcashNetwork.id}")
}
}
private const val DEFAULT_PORT = 9067
val LightWalletEndpoint.Companion.Mainnet
get() =
LightWalletEndpoint(
"mainnet.lightwalletd.com",
DEFAULT_PORT,
"zec.rocks",
443,
isSecure = true
)
@ -31,7 +20,7 @@ val LightWalletEndpoint.Companion.Testnet
get() =
LightWalletEndpoint(
"lightwalletd.testnet.electriccoin.co",
DEFAULT_PORT,
9067,
isSecure = true
)

View File

@ -16,9 +16,7 @@ fun PercentDecimal.toPercentageWithDecimal(decimalFormat: DecimalFormat = prepar
private fun preparePercentDecimalFormat(): DecimalFormat =
DecimalFormat().apply {
// TODO [#1171]: Remove default MonetarySeparators locale
// TODO [#1171]: https://github.com/Electric-Coin-Company/zashi-android/issues/1171
val monetarySeparators = MonetarySeparators.current(Locale.US)
val monetarySeparators = MonetarySeparators.current(Locale.getDefault())
val localizedPattern = "##0${monetarySeparators.decimal}00"
runCatching {
applyLocalizedPattern(localizedPattern)

View File

@ -2,21 +2,20 @@ package cash.z.ecc.sdk.model
import cash.z.ecc.android.sdk.model.WalletAddress
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.sdk.fixture.Zip321UriBuildFixture
import cash.z.ecc.sdk.fixture.Zip321UriParseFixture
data class ZecRequest(val address: WalletAddress.Unified, val amount: Zatoshi, val message: ZecRequestMessage) {
// TODO [#397]: Waiting for an implementation of Uri parser in SDK project
// TODO [#397]: https://github.com/Electric-Coin-Company/zcash-android-wallet-sdk/issues/397
suspend fun toUri(): String {
return Zip321UriBuildFixture.new(this)
TODO("Not implemented yet: Issue #397")
}
companion object {
// TODO [#397]: Waiting for an implementation of Uri parser in SDK project
// TODO [#397]: https://github.com/Electric-Coin-Company/zcash-android-wallet-sdk/issues/397
@Suppress("UNUSED_PARAMETER")
suspend fun fromUri(uriString: String): ZecRequest {
return Zip321UriParseFixture.new(uriString)
TODO("Not implemented yet: Issue #397")
}
}
}

View File

@ -6,13 +6,12 @@ pluginManagement {
val googleGroups = listOf(
"androidx.navigation",
"com.android.tools",
"com.android",
"com.google.testing.platform"
)
val googleRegexes = listOf(
"androidx.*",
"com\\.android.*",
"com\\.android\\.tools.*"
"androidx\\..*",
"com\\.android(\\.|\\:).*"
)
val wtfGroups = listOf("wtf.emulator")
@ -80,7 +79,7 @@ dependencyResolutionManagement {
val googleGroups = listOf(
"androidx.benchmark",
"androidx.navigation",
"com.android.tools",
"com.android",
"com.google.android.datatransport",
"com.google.android.gms",
"com.google.android.material",
@ -90,9 +89,8 @@ dependencyResolutionManagement {
"com.google.android.apps.common.testing.accessibility.framework"
)
val googleRegexes = listOf(
"androidx.*",
"com\\.android.*",
"com\\.android\\.tools.*"
"androidx\\..*",
"com\\.android(\\.|\\:).*",
)
val wtfGroups = listOf("wtf.emulator")
@ -146,6 +144,7 @@ dependencyResolutionManagement {
val androidxActivityVersion = extra["ANDROIDX_ACTIVITY_VERSION"].toString()
val androidxAnnotationVersion = extra["ANDROIDX_ANNOTATION_VERSION"].toString()
val androidxAppcompatVersion = extra["ANDROIDX_APPCOMPAT_VERSION"].toString()
val androidxBiometricVersion = extra["ANDROIDX_BIOMETRIC_VERSION"].toString()
val androidxCameraVersion = extra["ANDROIDX_CAMERA_VERSION"].toString()
val androidxComposeCompilerVersion = extra["ANDROIDX_COMPOSE_COMPILER_VERSION"].toString()
val androidxComposeMaterial3Version = extra["ANDROIDX_COMPOSE_MATERIAL3_VERSION"].toString()
@ -194,6 +193,8 @@ dependencyResolutionManagement {
library("androidx-activity-compose", "androidx.activity:activity-compose:$androidxActivityVersion")
library("androidx-annotation", "androidx.annotation:annotation:$androidxAnnotationVersion")
library("androidx-appcompat", "androidx.appcompat:appcompat:$androidxAppcompatVersion")
library("androidx-biometric", "androidx.biometric:biometric:$androidxBiometricVersion")
library("androidx-biometric-ktx", "androidx.biometric:biometric-ktx:$androidxBiometricVersion")
library("androidx-camera", "androidx.camera:camera-camera2:$androidxCameraVersion")
library("androidx-camera-lifecycle", "androidx.camera:camera-lifecycle:$androidxCameraVersion")
library("androidx-camera-view", "androidx.camera:camera-view:$androidxCameraVersion")
@ -250,9 +251,16 @@ dependencyResolutionManagement {
library("androidx-test-orchestrator", "androidx.test:orchestrator:$androidxTestOrchestratorVersion")
library("androidx-test-runner", "androidx.test:runner:$androidxTestRunnerVersion")
library("androidx-test-services","androidx.test.services:test-services:$androidxTestServices")
library("androidx-uiAutomator", "androidx.test.uiautomator:uiautomator-v18:$androidxUiAutomatorVersion")
library("androidx-uiAutomator", "androidx.test.uiautomator:uiautomator:$androidxUiAutomatorVersion")
library("kotlinx-coroutines-test", "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinxCoroutinesVersion")
// Bundles
bundle(
"androidx-biometric",
listOf(
"androidx-biometric",
"androidx-biometric-ktx",
)
)
bundle(
"androidx-camera",
listOf(

View File

@ -11,12 +11,28 @@ object AndroidApiVersion {
* [sdk].
*/
@ChecksSdkIntAtLeast(parameter = 0)
fun isAtLeast(
private fun isAtLeast(
@IntRange(from = Build.VERSION_CODES.BASE.toLong()) sdk: Int
): Boolean {
return Build.VERSION.SDK_INT >= sdk
}
/**
* @param sdk SDK version number to test against the current environment.
* @return `true` if [android.os.Build.VERSION.SDK_INT] is equal to [sdk].
*/
private fun isExactly(
@IntRange(from = Build.VERSION_CODES.BASE.toLong()) sdk: Int
): Boolean {
return Build.VERSION.SDK_INT == sdk
}
val isExactlyO = isExactly(Build.VERSION_CODES.O_MR1)
val isExactlyP = isExactly(Build.VERSION_CODES.P)
val isExactlyQ = isExactly(Build.VERSION_CODES.Q)
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.P)
val isAtLeastP = isAtLeast(Build.VERSION_CODES.P)

View File

@ -8,69 +8,69 @@ org.jetbrains.intellij.deps:coverage-report:1.0.21=koverJvmReporter
org.jetbrains.intellij.deps:intellij-coverage-agent:1.0.724=koverJvmAgent,koverJvmReporter
org.jetbrains.intellij.deps:intellij-coverage-reporter:1.0.724=koverJvmReporter
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-build-common:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-common:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.6.20=kotlinCompilerClasspathCopy
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.23=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.6.20=kotlinKlibCommonizerClasspathCopy
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.21=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.23=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-script-runtime:1.9.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.9.23=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-common:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.6.20=kotlinCompilerPluginClasspathJvmMainCopy,kotlinCompilerPluginClasspathJvmTestCopy,kotlinCompilerPluginClasspathMetadataCommonMainCopy,kotlinCompilerPluginClasspathMetadataMainCopy
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.6.21=kotlinCompilerPluginClasspathJvmMainCopy2,kotlinCompilerPluginClasspathJvmTestCopy2,kotlinCompilerPluginClasspathMetadataCommonMainCopy2,kotlinCompilerPluginClasspathMetadataMainCopy2
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.21=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.23=kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain
org.jetbrains.kotlin:kotlin-stdlib-common:1.6.20=commonTestImplementationCopy,jvmTestImplementationCopy
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.10=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain,metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.0=commonTestImplementationCopy,jvmTestImplementationCopy
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCommonMainCompileClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20=metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.0=commonTestImplementationCopy,jvmTestImplementationCopy
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.20=commonMainApiCopy,commonMainApiCopy2,commonTestApiCopy,jvmMainApiCopy,jvmTestApiCopy
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCommonMainCompileClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20=metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.6.20=commonTestImplementationCopy,jvmTestImplementationCopy
org.jetbrains.kotlin:kotlin-stdlib:1.8.20=metadataCommonMainCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.8.21=kotlinCompilerPluginClasspathMetadataCommonMain
org.jetbrains.kotlin:kotlin-stdlib:1.9.21=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-test-annotations-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-common:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-stdlib:1.9.23=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,metadataCompileClasspath
org.jetbrains.kotlin:kotlin-test-annotations-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-common:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestResolvableDependenciesMetadata
org.jetbrains.kotlin:kotlin-test-junit:1.6.20=commonTestImplementationCopy,jvmTestImplementationCopy
org.jetbrains.kotlin:kotlin-test-junit:1.9.21=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test-junit:1.9.23=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test:1.6.20=commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestImplementationCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlin:kotlin-test:1.6.21=commonTestImplementationCopy2,jvmTestImplementationCopy2
org.jetbrains.kotlin:kotlin-test:1.9.21=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-test:1.9.23=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:atomicfu:0.17.3=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlinx:atomicfu:0.20.2=metadataCommonMainCompileClasspath
org.jetbrains.kotlinx:atomicfu:0.21.0=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlinx:atomicfu:0.23.1=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.1=commonTestImplementationCopy,jvmTestImplementationCopy
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=kotlinBuildToolsApiClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.1=commonMainApiCopy,commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestImplementationCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.2=commonMainApiCopy2,jvmTestCompileClasspathCopy2,jvmTestRuntimeClasspathCopy2
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1=commonMainApiCopy,commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestImplementationCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2=commonMainApiCopy2,jvmTestCompileClasspathCopy2,jvmTestRuntimeClasspathCopy2
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4=allSourceSetsRuntimeDependenciesMetadata
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1=metadataCommonMainCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0=allSourceSetsCompileDependenciesMetadata,commonMainApiDependenciesMetadata,commonMainCompileOnlyDependenciesMetadata,commonMainImplementationDependenciesMetadata,commonMainResolvableDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmCompileClasspath,jvmMainApiDependenciesMetadata,jvmMainCompileOnlyDependenciesMetadata,jvmMainImplementationDependenciesMetadata,jvmMainResolvableDependenciesMetadata,jvmRuntimeClasspath,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath,metadataCompileClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.6.1=commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestImplementationCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.6.2=commonTestImplementationCopy2
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.7.3=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.8.0=jvmTestCompileClasspath,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.1=commonTestImplementationCopy,jvmTestCompileClasspathCopy,jvmTestImplementationCopy,jvmTestRuntimeClasspathCopy
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.2=commonTestImplementationCopy2
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0=allSourceSetsCompileDependenciesMetadata,commonTestApiDependenciesMetadata,commonTestCompileOnlyDependenciesMetadata,commonTestImplementationDependenciesMetadata,commonTestResolvableDependenciesMetadata,jvmTestApiDependenciesMetadata,jvmTestCompileClasspath,jvmTestCompileOnlyDependenciesMetadata,jvmTestImplementationDependenciesMetadata,jvmTestResolvableDependenciesMetadata,jvmTestRuntimeClasspath
org.jetbrains:annotations:13.0=commonTestImplementationCopy,jvmTestImplementationCopy,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJvmMain,kotlinCompilerPluginClasspathJvmTest,kotlinCompilerPluginClasspathMetadataCommonMain,kotlinCompilerPluginClasspathMetadataMain,kotlinKlibCommonizerClasspath,metadataCommonMainCompileClasspath
org.jetbrains:annotations:16.0.2=koverJvmReporter
org.jetbrains:annotations:23.0.0=jvmCompileClasspath,jvmRuntimeClasspath,jvmTestCompileClasspath,jvmTestRuntimeClasspath

View File

@ -57,7 +57,6 @@ private fun ButtonComposablePreview() {
TertiaryButton(onClick = { }, text = "Tertiary")
TertiaryButton(onClick = { }, text = "Tertiary", enabled = false)
NavigationButton(onClick = { }, text = "Navigation")
DangerousButton(onClick = { }, text = "Dangerous")
@Suppress("MagicNumber")
Row {
PrimaryButton(onClick = { }, text = "Button 1", modifier = Modifier.weight(0.5f))
@ -87,7 +86,7 @@ fun PrimaryButton(
horizontal = ZcashTheme.dimens.spacingNone,
vertical = ZcashTheme.dimens.spacingSmall
),
contentPaddingValues: PaddingValues = PaddingValues(all = 15.dp)
contentPaddingValues: PaddingValues = PaddingValues(all = 16.5.dp)
) {
Button(
shape = RectangleShape,
@ -184,7 +183,7 @@ fun SecondaryButton(
horizontal = ZcashTheme.dimens.spacingNone,
vertical = ZcashTheme.dimens.spacingSmall
),
contentPaddingValues: PaddingValues = PaddingValues(all = 16.dp)
contentPaddingValues: PaddingValues = PaddingValues(all = 16.5.dp)
) {
Button(
shape = RectangleShape,
@ -196,7 +195,8 @@ fun SecondaryButton(
.padding(outerPaddingValues)
.shadow(
contentColor = textColor,
strokeColor = textColor,
strokeColor = buttonColor,
strokeWidth = 1.dp,
offsetX = ZcashTheme.dimens.buttonShadowOffsetX,
offsetY = ZcashTheme.dimens.buttonShadowOffsetY,
spread = ZcashTheme.dimens.buttonShadowSpread,
@ -292,38 +292,6 @@ fun TertiaryButton(
}
}
@Composable
fun DangerousButton(
onClick: () -> Unit,
text: String,
modifier: Modifier = Modifier,
outerPaddingValues: PaddingValues =
PaddingValues(
horizontal = ZcashTheme.dimens.spacingNone,
vertical = ZcashTheme.dimens.spacingSmall
),
) {
Button(
shape = RectangleShape,
onClick = onClick,
modifier =
modifier.then(
Modifier
.fillMaxWidth()
.padding(outerPaddingValues)
.defaultMinSize(ZcashTheme.dimens.buttonWidth, ZcashTheme.dimens.buttonHeight)
),
colors = buttonColors(containerColor = ZcashTheme.colors.dangerous)
) {
Text(
style = MaterialTheme.typography.labelLarge,
textAlign = TextAlign.Center,
text = text,
color = ZcashTheme.colors.onDangerous
)
}
}
@Suppress("LongParameterList")
fun Modifier.shadow(
contentColor: Color = Color.Black,
@ -377,6 +345,9 @@ fun Modifier.shadow(
private enum class ButtonState { Pressed, Idle }
// TODO [#1346]: Rework not-recommended composed{}
// TODO [#1346]: https://github.com/Electric-Coin-Company/zashi-android/issues/1346
@Suppress("ModifierComposed")
fun Modifier.translationClick(
translationX: Dp = 0.dp,
translationY: Dp = 0.dp

View File

@ -57,7 +57,7 @@ fun AppAlertDialog(
onDismissButtonClick: (() -> Unit)? = null,
icon: ImageVector? = null,
title: String? = null,
text: String? = null,
text: @Composable (() -> Unit)? = null,
properties: DialogProperties = DialogProperties()
) {
AlertDialog(
@ -82,9 +82,37 @@ fun AppAlertDialog(
}
},
title = title?.let { { Text(text = title) } },
text = text?.let { { Text(text = text) } },
text = text,
icon = icon?.let { { Icon(imageVector = icon, null) } },
properties = properties,
modifier = modifier,
)
}
@Composable
@Suppress("LongParameterList")
fun AppAlertDialog(
modifier: Modifier = Modifier,
onDismissRequest: (() -> Unit)? = null,
confirmButtonText: String? = null,
onConfirmButtonClick: (() -> Unit)? = null,
dismissButtonText: String? = null,
onDismissButtonClick: (() -> Unit)? = null,
icon: ImageVector? = null,
title: String? = null,
text: String? = null,
properties: DialogProperties = DialogProperties()
) {
AppAlertDialog(
onDismissRequest = onDismissRequest?.let { onDismissRequest } ?: {},
modifier = modifier,
confirmButtonText = confirmButtonText,
title = title,
text = { text?.let { Text(text = text) } },
icon = icon,
properties = properties,
onConfirmButtonClick = onConfirmButtonClick,
dismissButtonText = dismissButtonText,
onDismissButtonClick = onDismissButtonClick
)
}

View File

@ -11,6 +11,7 @@ import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@ -23,7 +24,7 @@ private fun CircularScreenProgressIndicatorComposablePreview() {
GradientSurface {
Column {
CircularScreenProgressIndicator()
CircularSmallProgressIndicator()
CircularMidProgressIndicator()
}
}
}
@ -48,9 +49,24 @@ fun CircularScreenProgressIndicator(modifier: Modifier = Modifier) {
}
@Composable
fun CircularSmallProgressIndicator(modifier: Modifier = Modifier) {
fun CircularMidProgressIndicator(modifier: Modifier = Modifier) {
CircularProgressIndicator(
color = ZcashTheme.colors.circularProgressBarSmall,
color = ZcashTheme.colors.circularProgressBarScreen,
strokeWidth = 3.dp,
modifier =
Modifier
.size(ZcashTheme.dimens.circularMidProgressWidth)
.then(modifier)
)
}
@Composable
fun CircularSmallProgressIndicator(
modifier: Modifier = Modifier,
color: Color = ZcashTheme.colors.circularProgressBarSmall,
) {
CircularProgressIndicator(
color = color,
strokeWidth = 2.dp,
modifier =
Modifier
@ -65,18 +81,18 @@ private fun LinearProgressIndicatorComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
@Suppress("MagicNumber")
LinearProgressIndicator(0.75f)
SmallLinearProgressIndicator(0.75f)
}
}
}
@Composable
fun LinearProgressIndicator(
fun SmallLinearProgressIndicator(
progress: Float,
modifier: Modifier = Modifier
) {
LinearProgressIndicator(
progress = progress,
progress = { progress },
color = ZcashTheme.colors.linearProgressBarBackground,
trackColor = ZcashTheme.colors.linearProgressBarTrack,
strokeCap = StrokeCap.Butt,

View File

@ -3,6 +3,7 @@
package co.electriccoin.zcash.ui.design.component
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
@ -14,6 +15,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.AccountBox
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@ -30,6 +32,7 @@ import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import cash.z.ecc.android.sdk.model.MonetarySeparators
import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@ -189,6 +192,7 @@ fun TitleLarge(
fun Small(
text: String,
modifier: Modifier = Modifier,
textFontWeight: FontWeight = FontWeight.Normal,
maxLines: Int = Int.MAX_VALUE,
overflow: TextOverflow = TextOverflow.Clip,
textAlign: TextAlign = TextAlign.Start,
@ -197,6 +201,7 @@ fun Small(
Text(
text = text,
color = color,
fontWeight = textFontWeight,
maxLines = maxLines,
overflow = overflow,
textAlign = textAlign,
@ -227,16 +232,41 @@ fun Tiny(
}
@Composable
fun ListHeader(
@Suppress("LongParameterList")
fun TextWithIcon(
text: String,
modifier: Modifier = Modifier
iconVector: ImageVector,
modifier: Modifier = Modifier,
iconContentDescription: String? = null,
maxLines: Int = Int.MAX_VALUE,
overflow: TextOverflow = TextOverflow.Clip,
textAlign: TextAlign = TextAlign.Start,
style: TextStyle = LocalTextStyle.current,
color: Color = MaterialTheme.colorScheme.onBackground,
) {
Text(
text = text,
style = ZcashTheme.extendedTypography.listItem,
color = ZcashTheme.colors.onBackgroundHeader,
modifier = modifier
)
Row(
modifier =
Modifier
.wrapContentSize()
.then(modifier),
verticalAlignment = Alignment.CenterVertically
) {
Image(
imageVector = iconVector,
contentDescription = iconContentDescription
)
Spacer(modifier = Modifier.padding(3.dp))
Text(
text = text,
color = color,
maxLines = maxLines,
overflow = overflow,
textAlign = textAlign,
style = style,
)
}
}
@Suppress("LongParameterList")
@ -248,6 +278,7 @@ fun Reference(
fontWeight: FontWeight = FontWeight.SemiBold,
textAlign: TextAlign = TextAlign.Center,
textStyle: TextStyle = ZcashTheme.typography.primary.bodyLarge,
color: Color = ZcashTheme.colors.reference,
imageVector: ImageVector? = null,
imageContentDescription: String? = null
) {
@ -273,7 +304,7 @@ fun Reference(
style =
textStyle.merge(
TextStyle(
color = ZcashTheme.colors.reference,
color = color,
textAlign = textAlign,
textDecoration = TextDecoration.Underline,
fontWeight = fontWeight
@ -345,8 +376,8 @@ private fun splitBalance(
): Pair<String, String> {
Twig.debug { "Balance before split: $balance, prefix: $prefix" }
@Suppress("MAGIC_CONSTANT", "MagicNumber")
val cutPosition = balance.indexOf(MonetarySeparators.current(Locale.US).decimal) + 4
@Suppress("MagicNumber")
val cutPosition = balance.indexOf(MonetarySeparators.current(Locale.getDefault()).decimal) + 4
val firstPart =
(prefix ?: "") +
balance.substring(

View File

@ -1,20 +1,22 @@
@file:Suppress("TooManyFunctions")
package co.electriccoin.zcash.ui.design.component
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.DropdownMenu
@ -34,10 +36,14 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import co.electriccoin.zcash.ui.design.R
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.internal.SecondaryTypography
import co.electriccoin.zcash.ui.design.theme.internal.TopAppBarColors
@Preview
@Composable
@ -49,6 +55,34 @@ private fun TopAppBarTextComposablePreview() {
}
}
@Preview
@Composable
private fun TopAppBarTextRestoringComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
SmallTopAppBar(
titleText = "Screen A",
backText = "Back",
restoringLabel = "[RESTORING YOUR WALLET…]"
)
}
}
}
@Preview
@Composable
private fun TopAppBarTextRestoringLongComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
SmallTopAppBar(
titleText = "Screen A",
backText = "Back",
restoringLabel = "[RESTORING YOUR WALLET LONG TEXT…]"
)
}
}
}
@Preview
@Composable
private fun TopAppBarLogoComposablePreview() {
@ -59,6 +93,20 @@ private fun TopAppBarLogoComposablePreview() {
}
}
@Preview
@Composable
private fun TopAppBarLogoRestoringComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
SmallTopAppBar(
showTitleLogo = true,
backText = "Back",
restoringLabel = "[RESTORING YOUR WALLET…]"
)
}
}
}
@Preview
@Composable
private fun TopAppBarRegularMenuComposablePreview() {
@ -213,31 +261,58 @@ private fun TopBarOneVisibleActionMenuExample(
}
@Composable
@Suppress("LongParameterList")
@Suppress("LongParameterList", "LongMethod")
@OptIn(ExperimentalMaterial3Api::class)
fun SmallTopAppBar(
modifier: Modifier = Modifier,
titleText: String? = null,
showTitleLogo: Boolean = false,
backText: String? = null,
backContentDescriptionText: String? = null,
onBack: (() -> Unit)? = null,
backText: String? = null,
colors: TopAppBarColors = ZcashTheme.colors.topAppBarColors,
hamburgerMenuActions: (@Composable RowScope.() -> Unit)? = null,
onBack: (() -> Unit)? = null,
regularActions: (@Composable RowScope.() -> Unit)? = null,
restoringLabel: String? = null,
showTitleLogo: Boolean = false,
titleText: String? = null,
) {
CenterAlignedTopAppBar(
title = {
if (titleText != null) {
Text(
text = titleText.uppercase(),
style = SecondaryTypography.headlineSmall
)
} else if (showTitleLogo) {
Icon(
painter = painterResource(id = R.drawable.zashi_text_logo),
contentDescription = null,
modifier = Modifier.height(ZcashTheme.dimens.topAppBarZcashLogoHeight)
)
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
var restoringSpacerHeight: Dp = 0.dp
if (titleText != null) {
Text(
text = titleText.uppercase(),
style = SecondaryTypography.headlineSmall,
color = colors.titleColor,
)
restoringSpacerHeight = ZcashTheme.dimens.spacingTiny
} else if (showTitleLogo) {
Icon(
painter = painterResource(id = R.drawable.zashi_text_logo),
contentDescription = null,
tint = colors.titleColor,
modifier = Modifier.height(ZcashTheme.dimens.topAppBarZcashLogoHeight)
)
restoringSpacerHeight = ZcashTheme.dimens.spacingSmall
}
if (restoringLabel != null) {
Spacer(modifier = Modifier.height(restoringSpacerHeight))
@Suppress("MagicNumber")
Text(
text = restoringLabel.uppercase(),
style = ZcashTheme.extendedTypography.restoringTopAppBarStyle,
color = colors.subTitleColor,
modifier = Modifier.fillMaxWidth(0.75f),
textAlign = TextAlign.Center,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
}
},
navigationIcon = {
@ -253,9 +328,10 @@ fun SmallTopAppBar(
modifier = Modifier.padding(all = ZcashTheme.dimens.spacingDefault),
verticalAlignment = Alignment.CenterVertically
) {
Image(
imageVector = Icons.Filled.ArrowBack,
contentDescription = backContentDescriptionText
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = backContentDescriptionText,
tint = colors.navigationColor,
)
Spacer(modifier = Modifier.size(size = ZcashTheme.dimens.spacingSmall))
Text(text = backText.uppercase())
@ -267,6 +343,7 @@ fun SmallTopAppBar(
regularActions?.invoke(this)
hamburgerMenuActions?.invoke(this)
},
colors = colors.toMaterialTopAppBarColors(),
modifier =
Modifier
.testTag(CommonTag.TOP_APP_BAR)

View File

@ -0,0 +1,135 @@
@file:Suppress("MatchingDeclarationName")
package co.electriccoin.zcash.ui.design.component
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.FastOutLinearInEasing
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import co.electriccoin.zcash.ui.design.R
import co.electriccoin.zcash.ui.design.component.AnimationConstants.ANIMATION_DURATION
import co.electriccoin.zcash.ui.design.component.AnimationConstants.INITIAL_DELAY
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.util.screenHeight
import kotlinx.coroutines.delay
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
object AnimationConstants {
const val ANIMATION_DURATION = 700
const val INITIAL_DELAY = 1000
fun together() = (ANIMATION_DURATION + INITIAL_DELAY).toLong()
}
// TODO [#1002]: Welcome screen animation masking
// TODO [#1002]: https://github.com/Electric-Coin-Company/zashi-android/issues/1002
@Composable
fun WelcomeAnimationAutostart(
modifier: Modifier = Modifier,
delay: Duration = INITIAL_DELAY.milliseconds,
) {
var currentAnimationState by remember { mutableStateOf(true) }
WelcomeAnimation(
animationState = currentAnimationState,
modifier = modifier
)
// Let's start the animation automatically in case e.g. authentication is not involved
LaunchedEffect(key1 = currentAnimationState) {
delay(delay)
currentAnimationState = false
}
}
private const val LOGO_RELATIVE_LOCATION = 0.2f
@Composable
fun WelcomeAnimation(
animationState: Boolean,
modifier: Modifier = Modifier,
) {
val screenHeight = screenHeight()
Column(
modifier =
modifier.then(
Modifier
.verticalScroll(
state = rememberScrollState(),
enabled = false
)
.wrapContentSize()
)
) {
AnimatedVisibility(
visible = animationState,
exit =
slideOutVertically(
targetOffsetY = { -it },
animationSpec =
tween(
durationMillis = ANIMATION_DURATION,
easing = FastOutLinearInEasing
)
),
) {
Box(modifier = Modifier.wrapContentSize()) {
Column(modifier = Modifier.wrapContentSize()) {
Image(
painter = ColorPainter(ZcashTheme.colors.welcomeAnimationColor),
contentScale = ContentScale.FillBounds,
modifier =
Modifier
.fillMaxHeight()
.height(screenHeight.overallScreenHeight()),
contentDescription = null
)
Image(
painter = painterResource(id = R.drawable.chart_line),
contentScale = ContentScale.FillBounds,
contentDescription = null,
)
}
Column(
modifier =
Modifier
.fillMaxSize()
.height(screenHeight.overallScreenHeight()),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.fillMaxHeight(LOGO_RELATIVE_LOCATION))
Image(
painter = painterResource(id = R.drawable.logo_with_hi),
contentDescription = null,
)
}
}
}
}
}

View File

@ -12,6 +12,7 @@ data class Dimens(
// Default spacings:
val spacingNone: Dp,
val spacingXtiny: Dp,
val spacingMin: Dp,
val spacingTiny: Dp,
val spacingSmall: Dp,
val spacingMid: Dp,
@ -33,6 +34,7 @@ data class Dimens(
val chipStroke: Dp,
// Progress
val circularScreenProgressWidth: Dp,
val circularMidProgressWidth: Dp,
val circularSmallProgressWidth: Dp,
val linearProgressHeight: Dp,
// TopAppBar:
@ -46,12 +48,14 @@ data class Dimens(
val layoutStroke: Dp,
val regularRippleEffectCorner: Dp,
val smallRippleEffectCorner: Dp,
val tinyRippleEffectCorner: Dp,
// Screen custom spacings:
val inScreenZcashLogoHeight: Dp,
val inScreenZcashLogoWidth: Dp,
val inScreenZcashTextLogoHeight: Dp,
val screenHorizontalSpacingBig: Dp,
val screenHorizontalSpacingRegular: Dp,
val cameraTorchButton: Dp,
)
private val defaultDimens =
@ -59,6 +63,7 @@ private val defaultDimens =
spacingNone = 0.dp,
spacingXtiny = 2.dp,
spacingTiny = 4.dp,
spacingMin = 6.dp,
spacingSmall = 8.dp,
spacingMid = 12.dp,
spacingDefault = 16.dp,
@ -75,6 +80,7 @@ private val defaultDimens =
chipShadowElevation = 4.dp,
chipStroke = 0.5.dp,
circularScreenProgressWidth = 48.dp,
circularMidProgressWidth = 22.dp,
circularSmallProgressWidth = 14.dp,
linearProgressHeight = 14.dp,
topAppBarZcashLogoHeight = 24.dp,
@ -85,11 +91,13 @@ private val defaultDimens =
divider = 1.dp,
regularRippleEffectCorner = 28.dp,
smallRippleEffectCorner = 10.dp,
tinyRippleEffectCorner = 8.dp,
inScreenZcashLogoHeight = 100.dp,
inScreenZcashLogoWidth = 60.dp,
inScreenZcashTextLogoHeight = 30.dp,
screenHorizontalSpacingBig = 64.dp,
screenHorizontalSpacingRegular = 32.dp,
cameraTorchButton = 20.dp,
)
private val normalDimens = defaultDimens

View File

@ -5,6 +5,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import co.electriccoin.zcash.ui.design.theme.internal.TopAppBarColors
@Immutable
data class ExtendedColors(
@ -15,22 +16,24 @@ data class ExtendedColors(
val callout: Color,
val onCallout: Color,
val circularProgressBarSmall: Color,
val circularProgressBarSmallDark: Color,
val circularProgressBarScreen: Color,
val linearProgressBarTrack: Color,
val linearProgressBarBackground: Color,
val chipIndex: Color,
val textCommon: Color,
val textMedium: Color,
val textDisabled: Color,
val textFieldHint: Color,
val textFieldError: Color,
val textFieldWarning: Color,
val textFieldFrame: Color,
val textDescription: Color,
val textDescriptionDark: Color,
val textPending: Color,
val layoutStroke: Color,
val overlay: Color,
val highlight: Color,
val dangerous: Color,
val onDangerous: Color,
val reference: Color,
val disabledButtonColor: Color,
val disabledButtonTextColor: Color,
@ -43,10 +46,15 @@ data class ExtendedColors(
val darkDividerColor: Color,
val tabTextColor: Color,
val panelBackgroundColor: Color,
val cameraDisabledBackgroundColor: Color,
val cameraDisabledFrameColor: Color,
val radioButtonColor: Color,
val radioButtonTextColor: Color,
val historyBackgroundColor: Color,
val historySendColor: Color,
val historyRedColor: Color,
val historySyncingColor: Color,
val topAppBarColors: TopAppBarColors,
val transparentTopAppBarColors: TopAppBarColors
) {
@Composable
fun surfaceGradient() =

View File

@ -24,12 +24,15 @@ internal object Dark {
val textSecondaryButton = Color(0xFF000000)
val textTertiaryButton = Color.White
val textCommon = Color(0xFFFFFFFF)
val textMedium = Color(0xFF353535)
val textDisabled = Color(0xFFB7B7B7)
val textChipIndex = Color(0xFFFFB900)
val textFieldFrame = Color(0xFF231F20)
val textFieldError = Color(0xFFFF0000)
val textFieldWarning = Color(0xFFF40202)
val textFieldHint = Color(0xFFB7B7B7)
val textDescription = Color(0xFF777777)
val textDescriptionDark = Color(0xFF4D4D4D)
val textProgress = Color(0xFF8B8A8A)
val aboutTextColor = Color(0xFF4E4E4E)
@ -41,28 +44,21 @@ internal object Dark {
val tabTextColor = Color(0xFF040404)
val layoutStroke = Color(0xFFFFFFFF)
val panelBackgroundColor = Color(0xFFEAEAEA)
val cameraDisabledBackgroundColor = Color(0xFF5E5C5C)
val cameraDisabledFrameColor = Color(0xFFFFFFFF)
val primaryButton = Color(0xFFFFFFFF)
val primaryButtonPressed = Color(0xFFFFFFFF)
val primaryButtonDisabled = Color(0xFFFFFFFF)
val secondaryButton = Color(0xFFFFFFFF)
val secondaryButtonPressed = Color(0xFFFFFFFF)
val secondaryButtonDisabled = Color(0xFFFFFFFF)
val tertiaryButton = Color.Transparent
val tertiaryButtonPressed = Color(0xFFFFFFFF)
val navigationButton = Color(0xFFFFFFFF)
val navigationButtonPressed = Color(0xFFFFFFFF)
val radioButtonColor = Color(0xFF070707)
val radioButtonTextColor = Color(0xFF4E4E4E)
val circularProgressBarSmall = Color(0xFF8B8A8A)
val circularProgressBarSmallDark = textBodyOnBackground
val circularProgressBarScreen = Color(0xFFFFFFFF)
val linearProgressBarTrack = Color(0xFFD9D9D9)
val linearProgressBarBackground = Light.complementaryColor
val linearProgressBarBackground = complementaryColor
val callout = Color(0xFFFFFFFF)
val onCallout = Color(0xFFFFFFFF)
@ -70,9 +66,6 @@ internal object Dark {
val overlay = Color(0x22000000)
val highlight = Color(0xFFFFD800)
val dangerous = Color(0xFFFF0B0B)
val onDangerous = Color(0xFFFFFFFF)
val reference = Color(0xFFFFFFFF)
val disabledButtonColor = Color(0xFFB7B7B7)
@ -81,7 +74,11 @@ internal object Dark {
val buttonShadowColor = Color(0xFFFFFFFF)
val historyBackgroundColor = Color(0xFFF6F6F6)
val historySendColor = Color(0xFFF40202)
val historyRedColor = textFieldWarning
val historySyncingColor = panelBackgroundColor
val topAppBarColors = DarkTopAppBarColors()
val transparentTopAppBarColors = TransparentTopAppBarColors()
}
internal object Light {
@ -94,12 +91,15 @@ internal object Light {
val textSecondaryButton = Color(0xFF000000)
val textTertiaryButton = Color(0xFF000000)
val textCommon = Color(0xFF000000)
val textMedium = Color(0xFF353535)
val textDisabled = Color(0xFFB7B7B7)
val textFieldFrame = Color(0xFF231F20)
val textFieldError = Color(0xFFCD0002)
val textFieldWarning = Color(0xFFF40202)
val textFieldHint = Color(0xFFB7B7B7)
val textChipIndex = Color(0xFFEE8592)
val textDescription = Color(0xFF777777)
val textDescriptionDark = Color(0xFF4D4D4D)
val textProgress = Color(0xFF8B8A8A)
val screenTitleColor = Color(0xFF040404)
@ -111,26 +111,19 @@ internal object Light {
val tabTextColor = Color(0xFF040404)
val layoutStroke = Color(0xFF000000)
val panelBackgroundColor = Color(0xFFEAEAEA)
val cameraDisabledBackgroundColor = Color(0xFF5E5C5C)
val cameraDisabledFrameColor = Color(0xFFFFFFFF)
val primaryButton = Color(0xFF000000)
val primaryButtonPressed = Color(0xFF000000)
val primaryButtonDisabled = Color(0xFF000000)
val secondaryButton = Color(0xFFFFFFFF)
val secondaryButtonPressed = Color(0xFFFFFFFF)
val secondaryButtonDisabled = Color(0xFFFFFFFF)
val tertiaryButton = Color.Transparent
val tertiaryButtonPressed = Color(0xFFFFFFFF)
val navigationButton = Color(0xFFFFFFFF)
val navigationButtonPressed = Color(0xFFFFFFFF)
val radioButtonColor = Color(0xFF070707)
val radioButtonTextColor = Color(0xFF4E4E4E)
val circularProgressBarSmall = Color(0xFF8B8A8A)
val circularProgressBarScreen = Color(0xFF000000)
val circularProgressBarSmallDark = textBodyOnBackground
val linearProgressBarTrack = Color(0xFFD9D9D9)
val linearProgressBarBackground = complementaryColor
@ -140,9 +133,6 @@ internal object Light {
val overlay = Color(0x22000000)
val highlight = Color(0xFFFFD800)
val dangerous = Color(0xFFFF0B0B)
val onDangerous = Color(0xFFFFFFFF)
val reference = Color(0xFF000000)
val disabledButtonColor = Color(0xFFB7B7B7)
@ -150,7 +140,11 @@ internal object Light {
val buttonShadowColor = Color(0xFF000000)
val historyBackgroundColor = Color(0xFFF6F6F6)
val historySendColor = Color(0xFFF40202)
val historyRedColor = textFieldWarning
val historySyncingColor = Dark.panelBackgroundColor
val topAppBarColors = LightTopAppBarColors()
val transparentTopAppBarColors = TransparentTopAppBarColors()
}
internal val DarkColorPalette =
@ -186,22 +180,24 @@ internal val DarkExtendedColorPalette =
callout = Dark.callout,
onCallout = Dark.onCallout,
circularProgressBarSmall = Dark.circularProgressBarSmall,
circularProgressBarSmallDark = Dark.circularProgressBarSmallDark,
circularProgressBarScreen = Dark.circularProgressBarScreen,
linearProgressBarTrack = Dark.linearProgressBarTrack,
linearProgressBarBackground = Dark.linearProgressBarBackground,
chipIndex = Dark.textChipIndex,
textCommon = Dark.textCommon,
textMedium = Dark.textMedium,
textDisabled = Dark.textDisabled,
textFieldFrame = Dark.textFieldFrame,
textFieldError = Dark.textFieldError,
textFieldWarning = Dark.textFieldWarning,
textFieldHint = Dark.textFieldHint,
textDescription = Dark.textDescription,
textDescriptionDark = Dark.textDescriptionDark,
textPending = Dark.textProgress,
layoutStroke = Dark.layoutStroke,
overlay = Dark.overlay,
highlight = Dark.highlight,
dangerous = Dark.dangerous,
onDangerous = Dark.onDangerous,
disabledButtonTextColor = Dark.disabledButtonTextColor,
disabledButtonColor = Dark.disabledButtonColor,
reference = Dark.reference,
@ -214,10 +210,15 @@ internal val DarkExtendedColorPalette =
darkDividerColor = Dark.darkDividerColor,
tabTextColor = Dark.tabTextColor,
panelBackgroundColor = Dark.panelBackgroundColor,
cameraDisabledBackgroundColor = Dark.cameraDisabledBackgroundColor,
cameraDisabledFrameColor = Dark.cameraDisabledFrameColor,
radioButtonColor = Dark.radioButtonColor,
radioButtonTextColor = Dark.radioButtonTextColor,
historyBackgroundColor = Dark.historyBackgroundColor,
historySendColor = Dark.historySendColor,
historyRedColor = Dark.historyRedColor,
historySyncingColor = Dark.historySyncingColor,
topAppBarColors = Dark.topAppBarColors,
transparentTopAppBarColors = Dark.transparentTopAppBarColors
)
internal val LightExtendedColorPalette =
@ -230,21 +231,23 @@ internal val LightExtendedColorPalette =
onCallout = Light.onCallout,
circularProgressBarScreen = Light.circularProgressBarScreen,
circularProgressBarSmall = Light.circularProgressBarSmall,
circularProgressBarSmallDark = Light.circularProgressBarSmallDark,
linearProgressBarTrack = Light.linearProgressBarTrack,
linearProgressBarBackground = Light.linearProgressBarBackground,
chipIndex = Light.textChipIndex,
textCommon = Light.textCommon,
textMedium = Light.textMedium,
textDisabled = Light.textDisabled,
textFieldFrame = Light.textFieldFrame,
textFieldError = Light.textFieldError,
textFieldWarning = Light.textFieldWarning,
textFieldHint = Light.textFieldHint,
textDescription = Light.textDescription,
textDescriptionDark = Light.textDescriptionDark,
textPending = Light.textProgress,
layoutStroke = Light.layoutStroke,
overlay = Light.overlay,
highlight = Light.highlight,
dangerous = Light.dangerous,
onDangerous = Light.onDangerous,
disabledButtonTextColor = Light.disabledButtonTextColor,
disabledButtonColor = Light.disabledButtonColor,
reference = Light.reference,
@ -257,10 +260,15 @@ internal val LightExtendedColorPalette =
darkDividerColor = Light.darkDividerColor,
tabTextColor = Light.tabTextColor,
panelBackgroundColor = Light.panelBackgroundColor,
cameraDisabledBackgroundColor = Light.cameraDisabledBackgroundColor,
cameraDisabledFrameColor = Light.cameraDisabledFrameColor,
radioButtonColor = Light.radioButtonColor,
radioButtonTextColor = Light.radioButtonTextColor,
historyBackgroundColor = Light.historyBackgroundColor,
historySendColor = Light.historySendColor,
historyRedColor = Light.historyRedColor,
historySyncingColor = Light.historySyncingColor,
topAppBarColors = Light.topAppBarColors,
transparentTopAppBarColors = Light.transparentTopAppBarColors
)
@Suppress("CompositionLocalAllowlist")
@ -275,21 +283,23 @@ internal val LocalExtendedColors =
onCallout = Color.Unspecified,
circularProgressBarScreen = Color.Unspecified,
circularProgressBarSmall = Color.Unspecified,
circularProgressBarSmallDark = Color.Unspecified,
linearProgressBarTrack = Color.Unspecified,
linearProgressBarBackground = Color.Unspecified,
chipIndex = Color.Unspecified,
textCommon = Color.Unspecified,
textMedium = Color.Unspecified,
textDisabled = Color.Unspecified,
textFieldHint = Color.Unspecified,
textFieldError = Color.Unspecified,
textFieldWarning = Color.Unspecified,
textFieldFrame = Color.Unspecified,
textDescription = Color.Unspecified,
textDescriptionDark = Color.Unspecified,
textPending = Color.Unspecified,
layoutStroke = Color.Unspecified,
overlay = Color.Unspecified,
highlight = Color.Unspecified,
dangerous = Color.Unspecified,
onDangerous = Color.Unspecified,
disabledButtonTextColor = Color.Unspecified,
disabledButtonColor = Color.Unspecified,
reference = Color.Unspecified,
@ -302,9 +312,14 @@ internal val LocalExtendedColors =
darkDividerColor = Color.Unspecified,
tabTextColor = Color.Unspecified,
panelBackgroundColor = Color.Unspecified,
cameraDisabledBackgroundColor = Color.Unspecified,
cameraDisabledFrameColor = Color.Unspecified,
radioButtonColor = Color.Unspecified,
radioButtonTextColor = Color.Unspecified,
historyBackgroundColor = Color.Unspecified,
historySendColor = Color.Unspecified,
historyRedColor = Color.Unspecified,
historySyncingColor = Color.Unspecified,
topAppBarColors = DefaultTopAppBarColors(),
transparentTopAppBarColors = DefaultTopAppBarColors(),
)
}

View File

@ -0,0 +1,62 @@
@file:Suppress("MagicNumber")
package co.electriccoin.zcash.ui.design.theme.internal
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Immutable
import androidx.compose.ui.graphics.Color
@Immutable
interface TopAppBarColors {
val containerColor: Color
val navigationColor: Color
val titleColor: Color
val subTitleColor: Color
val actionColor: Color
@OptIn(ExperimentalMaterial3Api::class)
fun toMaterialTopAppBarColors() =
androidx.compose.material3.TopAppBarColors(
containerColor = containerColor,
scrolledContainerColor = containerColor,
navigationIconContentColor = navigationColor,
titleContentColor = titleColor,
actionIconContentColor = actionColor
)
}
@Immutable
internal data class DefaultTopAppBarColors(
override val containerColor: Color = Color.Unspecified,
override val navigationColor: Color = Color.Unspecified,
override val titleColor: Color = Color.Unspecified,
override val subTitleColor: Color = Color.Unspecified,
override val actionColor: Color = Color.Unspecified,
) : TopAppBarColors
@Immutable
internal data class LightTopAppBarColors(
override val containerColor: Color = Color(0xFFFFFFFF),
override val navigationColor: Color = Color(0xFF000000),
override val titleColor: Color = Color(0xFF000000),
override val subTitleColor: Color = Color(0xFF8A8888),
override val actionColor: Color = Color(0xFF000000),
) : TopAppBarColors
@Immutable
internal data class DarkTopAppBarColors(
override val containerColor: Color = Color(0xFF000000),
override val navigationColor: Color = Color(0xFFFFFFFF),
override val titleColor: Color = Color(0xFFFFFFFF),
override val subTitleColor: Color = Color(0xFF8A8888),
override val actionColor: Color = Color(0xFFFFFFFF),
) : TopAppBarColors
@Immutable
internal data class TransparentTopAppBarColors(
override val containerColor: Color = Color(0x00000000),
override val navigationColor: Color = Color(0xFFFFFFFF),
override val titleColor: Color = Color(0xFFFFFFFF),
override val subTitleColor: Color = Color(0xFFFFFFFF),
override val actionColor: Color = Color(0xFFFFFFFF),
) : TopAppBarColors

View File

@ -162,12 +162,17 @@ data class TransactionItemTextStyles(
val addressCollapsed: TextStyle,
val valueFirstPart: TextStyle,
val valueSecondPart: TextStyle,
val date: TextStyle,
val content: TextStyle,
val contentItalic: TextStyle,
val contentMedium: TextStyle,
val contentUnderline: TextStyle,
val contentLineThrough: TextStyle,
val feeFirstPart: TextStyle,
val feeSecondPart: TextStyle,
)
@Immutable
data class ExtendedTypography(
val listItem: TextStyle,
// Grouping balances text styles to a wrapper class for BalanceWidget
val balanceWidgetStyles: BalanceWidgetTextStyles,
// Grouping balances text styles to a wrapper class for single balance use case
@ -178,7 +183,7 @@ data class ExtendedTypography(
val buttonTextSmall: TextStyle,
val checkboxText: TextStyle,
val securityWarningText: TextStyle,
val securityWarningFootnote: TextStyle,
val footnote: TextStyle,
val textFieldHint: TextStyle,
val textFieldValue: TextStyle,
val textFieldBirthday: TextStyle,
@ -187,6 +192,9 @@ data class ExtendedTypography(
val radioButton: TextStyle,
// Grouping transaction item text styles to a wrapper class
val transactionItemStyles: TransactionItemTextStyles,
val restoringTopAppBarStyle: TextStyle,
val deleteWalletWarnStyle: TextStyle,
val updateTitleStyle: TextStyle,
)
@Suppress("CompositionLocalAllowlist")
@ -202,10 +210,6 @@ val LocalTypographies =
val LocalExtendedTypography =
staticCompositionLocalOf {
ExtendedTypography(
listItem =
PrimaryTypography.bodyLarge.copy(
fontSize = 24.sp
),
// Note: the order here matters, be careful when reordering
balanceWidgetStyles =
BalanceWidgetTextStyles(
@ -270,7 +274,7 @@ val LocalExtendedTypography =
fontSize = 16.sp,
fontWeight = FontWeight.Medium
),
securityWarningFootnote =
footnote =
PrimaryTypography.bodySmall.copy(
fontSize = 11.sp,
fontWeight = FontWeight.Medium
@ -330,10 +334,54 @@ val LocalExtendedTypography =
PrimaryTypography.bodySmall.copy(
fontSize = 8.sp
),
date =
content =
PrimaryTypography.bodySmall.copy(
fontSize = 13.sp
),
contentItalic =
PrimaryTypography.bodySmall.copy(
fontSize = 13.sp,
fontStyle = FontStyle.Italic
),
contentMedium =
PrimaryTypography.bodySmall.copy(
fontSize = 13.sp,
fontWeight = FontWeight.Medium
),
contentUnderline =
PrimaryTypography.bodySmall.copy(
fontSize = 13.sp,
fontStyle = FontStyle.Italic,
textDecoration = TextDecoration.Underline
),
contentLineThrough =
PrimaryTypography.bodySmall.copy(
fontSize = 13.sp,
textDecoration = TextDecoration.LineThrough
),
feeFirstPart =
PrimaryTypography.bodySmall.copy(
fontSize = 13.sp,
fontWeight = FontWeight.SemiBold
),
feeSecondPart =
PrimaryTypography.bodySmall.copy(
fontSize = 8.sp,
fontWeight = FontWeight.SemiBold
),
),
restoringTopAppBarStyle =
SecondaryTypography.labelMedium.copy(
fontSize = 12.sp,
fontWeight = FontWeight.SemiBold
),
deleteWalletWarnStyle =
PrimaryTypography.bodyLarge.copy(
fontWeight = FontWeight.Bold
),
updateTitleStyle =
PrimaryTypography.titleLarge.copy(
fontWeight = FontWeight.Bold
)
)
}

View File

@ -1,54 +1,60 @@
package co.electriccoin.zcash.ui.design.util
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.statusBars
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.navigationBarsIgnoringVisibility
import androidx.compose.foundation.layout.statusBarsIgnoringVisibility
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import co.electriccoin.zcash.spackle.Twig
import kotlin.math.roundToInt
/**
* This operation performs calculation of the screen height together with remembering its result for a further calls.
* This operation performs calculation of the screen height.
*
* @param cacheKey The cache defining key. Use a different one for recalculation.
*
* @return Wrapper object of the calculated heights in density pixels.
* @return [ScreenHeight] a wrapper object of the calculated heights in density pixels.
*/
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun screenHeight(cacheKey: Any = true): ScreenHeight {
val density = LocalDensity.current
fun screenHeight(): ScreenHeight {
val configuration = LocalConfiguration.current
val statusBars = WindowInsets.statusBars
val navigationBars = WindowInsets.navigationBars
val cachedResult =
remember(cacheKey) {
val contentHeightPx = with(density) { configuration.screenHeightDp.dp.roundToPx() }
Twig.debug { "Screen content height in pixels: $contentHeightPx" }
val statusBars = WindowInsets.statusBarsIgnoringVisibility.asPaddingValues().calculateTopPadding()
Twig.debug { "Screen height: Status bar height raw: $statusBars" }
val statusBarHeight = statusBars.getTop(density).dp
Twig.debug { "Status bar height: $statusBarHeight" }
val navigationBars = WindowInsets.navigationBarsIgnoringVisibility.asPaddingValues().calculateBottomPadding()
Twig.debug { "Screen height: Navigation bar height raw: $navigationBars" }
val navigationBarHeight = navigationBars.getBottom(density).dp
Twig.debug { "Navigation bar height: $navigationBarHeight" }
val contentHeight = configuration.screenHeightDp.dp
Twig.debug { "Screen height: Screen content height: $contentHeight" }
val contentHeight = (contentHeightPx / density.density.roundToInt()).dp
Twig.debug { "Screen content height in dps: $contentHeight" }
ScreenHeight(
contentHeight = contentHeight,
systemStatusBarHeight = statusBarHeight,
systemNavigationBarHeight = navigationBarHeight,
)
val statusBarHeight =
statusBars.run {
if (value <= 0f) {
24.dp
} else {
this
}
}
Twig.debug { "Screen total height: $cachedResult" }
Twig.debug { "Screen height: Status bar height: $statusBarHeight" }
return cachedResult
val navigationBarHeight =
navigationBars.run {
if (value <= 0f) {
88.dp
} else {
this
}
}
Twig.debug { "Screen height: Navigation bar height: $navigationBarHeight" }
return ScreenHeight(
contentHeight = contentHeight,
systemStatusBarHeight = statusBarHeight,
systemNavigationBarHeight = navigationBarHeight
)
}
data class ScreenHeight(
@ -56,7 +62,15 @@ data class ScreenHeight(
val systemStatusBarHeight: Dp,
val systemNavigationBarHeight: Dp
) {
fun overallScreenHeight() = contentHeight + systemBarsHeight()
fun overallScreenHeight(): Dp {
return (contentHeight + systemBarsHeight()).also {
Twig.debug { "Screen height: Overall height: $it" }
}
}
fun systemBarsHeight() = systemStatusBarHeight + systemNavigationBarHeight
fun systemBarsHeight(): Dp {
return (systemStatusBarHeight + systemNavigationBarHeight).also {
Twig.debug { "Screen height: System bars height: $it" }
}
}
}

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48">
<path
android:fillColor="@android:color/black"
android:pathData="M22.55,42V37.8Q19.7,37.3 17.875,35.625Q16.05,33.95 15.25,31.4L18.05,30.25Q18.9,32.65 20.5,33.825Q22.1,35 24.35,35Q26.75,35 28.3,33.8Q29.85,32.6 29.85,30.5Q29.85,28.3 28.475,27.1Q27.1,25.9 23.3,24.65Q19.7,23.5 17.925,21.6Q16.15,19.7 16.15,16.85Q16.15,14.1 17.925,12.25Q19.7,10.4 22.55,10.15V6H25.55V10.15Q27.8,10.4 29.425,11.625Q31.05,12.85 31.9,14.75L29.1,15.95Q28.4,14.35 27.225,13.625Q26.05,12.9 24.15,12.9Q21.85,12.9 20.5,13.95Q19.15,15 19.15,16.8Q19.15,18.7 20.65,19.875Q22.15,21.05 26.2,22.3Q29.6,23.35 31.225,25.325Q32.85,27.3 32.85,30.3Q32.85,33.45 31,35.375Q29.15,37.3 25.55,37.85V42Z"/>
</vector>

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="3.17dp"
android:height="5.57dp"
android:viewportWidth="3.17"
android:viewportHeight="5.57">
<path
android:pathData="M1.96,5.57l0,-0.75l1.21,0l0,-0.84l-1.96,0l1.62,-2.18l0.34,-0.44l0,0l0,-0.61l-1.21,0l0,-0.75l-0.75,0l0,0.75l-1.21,0l0,0.84l1.96,0l-1.62,2.12l-0.34,0.44l0,0.67l1.21,0l0,0.75l0.75,0z"
android:fillColor="#1d181a"/>
</vector>

View File

@ -57,6 +57,8 @@ android {
}
dependencies {
implementation(libs.zcash.sdk)
implementation(projects.uiLib)
implementation(projects.uiDesignLib)
implementation(projects.testLib)

View File

@ -2,9 +2,7 @@ package co.electriccoin.zcash.ui.integration.test.screen.scan.view
import androidx.compose.ui.test.assertHasClickAction
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
@ -14,6 +12,7 @@ import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.integration.test.common.IntegrationTestingActivity
import co.electriccoin.zcash.ui.integration.test.common.getPermissionPositiveButtonUiObject
import co.electriccoin.zcash.ui.integration.test.common.getStringResource
import co.electriccoin.zcash.ui.integration.test.common.getStringResourceWithArgs
import co.electriccoin.zcash.ui.integration.test.common.waitForDeviceIdle
import co.electriccoin.zcash.ui.screen.scan.ScanTag
import co.electriccoin.zcash.ui.screen.scan.model.ScanState
@ -71,21 +70,10 @@ class ScanViewTest : UiTestPrerequisites() {
testSetup.grantPermission()
composeTestRule.onNodeWithContentDescription(
getStringResource(R.string.scan_back_content_description)
).also {
composeTestRule.onNodeWithText(getStringResource(R.string.scan_cancel_button).uppercase()).also {
it.assertIsDisplayed()
}
composeTestRule.onNodeWithText(getStringResource(R.string.scan_hint)).also {
it.assertIsDisplayed()
}
composeTestRule.onNodeWithTag(ScanTag.TEXT_STATE).also {
it.assertIsDisplayed()
it.assertTextEquals(getStringResource(R.string.scan_state_scanning))
}
composeTestRule.onNodeWithTag(ScanTag.QR_FRAME).also {
it.assertIsDisplayed()
}
@ -109,23 +97,19 @@ class ScanViewTest : UiTestPrerequisites() {
assertEquals(ScanState.Permission, testSetup.getScanState())
composeTestRule.onNodeWithTag(ScanTag.QR_FRAME).also {
it.assertDoesNotExist()
}
composeTestRule.onNodeWithTag(ScanTag.CAMERA_VIEW).also {
it.assertDoesNotExist()
}
composeTestRule.onNodeWithText(getStringResource(R.string.scan_hint)).also {
composeTestRule.onNodeWithText(
getStringResourceWithArgs(
resId = R.string.scan_state_permission,
getStringResource(R.string.app_name)
)
).also {
it.assertIsDisplayed()
}
composeTestRule.onNodeWithTag(ScanTag.TEXT_STATE).also {
it.assertIsDisplayed()
it.assertTextEquals(getStringResource(R.string.scan_state_permission))
}
composeTestRule.onNodeWithText(getStringResource(R.string.scan_settings_button), ignoreCase = true).also {
it.assertIsDisplayed()
it.assertHasClickAction()

View File

@ -3,6 +3,8 @@ package co.electriccoin.zcash.ui.integration.test.screen.scan.view
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import cash.z.ecc.android.sdk.type.AddressType
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.integration.test.common.getPermissionNegativeButtonUiObject
import co.electriccoin.zcash.ui.integration.test.common.getPermissionPositiveButtonUiObject
@ -56,7 +58,9 @@ class ScanViewTestSetup(
},
onScanStateChanged = {
scanState.set(it)
}
},
walletRestoringState = WalletRestoringState.NONE,
addressValidationResult = AddressType.Unified
)
}

View File

@ -7,6 +7,7 @@ import co.electriccoin.zcash.test.UiTestPrerequisites
import co.electriccoin.zcash.ui.fixture.UpdateInfoFixture
import co.electriccoin.zcash.ui.integration.test.common.IntegrationTestingActivity
import co.electriccoin.zcash.ui.screen.update.AppUpdateChecker
import co.electriccoin.zcash.ui.screen.update.AppUpdateCheckerMock
import co.electriccoin.zcash.ui.screen.update.model.UpdateInfo
import co.electriccoin.zcash.ui.screen.update.model.UpdateState
import co.electriccoin.zcash.ui.screen.update.viewmodel.UpdateViewModel

View File

@ -33,15 +33,16 @@ android {
"src/main/res/ui/about",
"src/main/res/ui/advanced_settings",
"src/main/res/ui/account",
"src/main/res/ui/authentication",
"src/main/res/ui/balances",
"src/main/res/ui/common",
"src/main/res/ui/delete_wallet",
"src/main/res/ui/export_data",
"src/main/res/ui/home",
"src/main/res/ui/choose_server",
"src/main/res/ui/new_wallet_recovery",
"src/main/res/ui/onboarding",
"src/main/res/ui/receive",
"src/main/res/ui/request",
"src/main/res/ui/restore",
"src/main/res/ui/scan",
"src/main/res/ui/seed_recovery",
@ -92,6 +93,7 @@ dependencies {
implementation(libs.androidx.lifecycle.livedata)
implementation(libs.androidx.splash)
implementation(libs.androidx.workmanager)
implementation(libs.bundles.androidx.biometric)
implementation(libs.bundles.androidx.camera)
implementation(libs.bundles.androidx.compose.core)
implementation(libs.bundles.androidx.compose.extended)

View File

@ -11,12 +11,10 @@ import org.junit.Test
import kotlin.test.assertTrue
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
import kotlin.time.ExperimentalTime
import kotlin.time.TimeMark
import kotlin.time.TimeSource
class FlowExtTest {
@OptIn(ExperimentalTime::class)
@Test
@SmallTest
fun throttle_one_sec() =
@ -40,7 +38,6 @@ class FlowExtTest {
}
}
@OptIn(ExperimentalTime::class)
private fun raceConditionTest(duration: Duration): Boolean =
runBlocking {
val flow = (0..1000).asFlow().throttle(duration)

View File

@ -11,8 +11,8 @@ import co.electriccoin.zcash.test.UiTestPrerequisites
import co.electriccoin.zcash.ui.common.compose.BrightenScreen
import co.electriccoin.zcash.ui.common.compose.LocalScreenBrightness
import co.electriccoin.zcash.ui.common.compose.ScreenBrightness
import co.electriccoin.zcash.ui.common.compose.ScreenBrightnessState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.test.runTest
@ -20,7 +20,6 @@ import org.junit.Rule
import org.junit.Test
import kotlin.test.assertEquals
@OptIn(ExperimentalCoroutinesApi::class)
class ScreenBrightnessTest : UiTestPrerequisites() {
@get:Rule
val composeTestRule = createComposeRule()
@ -31,19 +30,19 @@ class ScreenBrightnessTest : UiTestPrerequisites() {
runTest {
val testSetup = TestSetup(composeTestRule)
assertEquals(1, testSetup.getSecureBrightnessCount())
assertEquals(ScreenBrightnessState.FULL, testSetup.getSecureBrightnessCount())
testSetup.mutableScreenBrightnessFlag.update { false }
composeTestRule.awaitIdle()
assertEquals(0, testSetup.getSecureBrightnessCount())
assertEquals(ScreenBrightnessState.NORMAL, testSetup.getSecureBrightnessCount())
}
private class TestSetup(composeTestRule: ComposeContentTestRule) {
val mutableScreenBrightnessFlag = MutableStateFlow(true)
private val screenBrightness = ScreenBrightness()
private val screenBrightness = ScreenBrightness
fun getSecureBrightnessCount() = screenBrightness.referenceCount.value
fun getSecureBrightnessCount() = screenBrightness.referenceSwitch.value
init {
runTest {

View File

@ -3,6 +3,7 @@ package co.electriccoin.zcash.ui.screen.about.view
import androidx.compose.material3.SnackbarHostState
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import co.electriccoin.zcash.ui.common.model.VersionInfo
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.support.model.ConfigInfo
import java.util.concurrent.atomic.AtomicInteger
@ -24,10 +25,11 @@ class AboutViewTestSetup(
ZcashTheme {
About(
onBack = { onBackCount.incrementAndGet() },
versionInfo = versionInfo,
configInfo = configInfo,
onPrivacyPolicy = {},
snackbarHostState = SnackbarHostState()
snackbarHostState = SnackbarHostState(),
versionInfo = versionInfo,
walletRestoringState = WalletRestoringState.NONE
)
}
}

View File

@ -2,10 +2,13 @@ package co.electriccoin.zcash.ui.screen.account
import androidx.compose.runtime.Composable
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.account.history.fixture.TransactionHistorySyncStateFixture
import co.electriccoin.zcash.ui.screen.account.state.TransactionHistorySyncState
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.account.history.fixture.TransactionHistoryUiStateFixture
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
import co.electriccoin.zcash.ui.screen.account.view.Account
import java.util.concurrent.atomic.AtomicInteger
@ -16,7 +19,7 @@ class AccountTestSetup(
// TODO [#1282]: Update AccountView Tests #1282
// TODO [#1282]: https://github.com/Electric-Coin-Company/zashi-android/issues/1282
val initialHistorySyncState: TransactionHistorySyncState = TransactionHistorySyncStateFixture.new()
val initialTransactionState: TransactionUiState = TransactionHistoryUiStateFixture.new()
private val onSettingsCount = AtomicInteger(0)
private val onReceiveCount = AtomicInteger(0)
@ -58,19 +61,17 @@ class AccountTestSetup(
@Suppress("TestFunctionName")
fun DefaultContent() {
Account(
walletSnapshot = walletSnapshot,
isKeepScreenOnWhileSyncing = false,
balanceState = BalanceStateFixture.new(),
goSettings = {
onSettingsCount.incrementAndGet()
},
goBalances = {},
transactionState = initialHistorySyncState,
onItemClick = {
transactionsUiState = initialTransactionState,
onTransactionItemAction = {
onItemClickCount.incrementAndGet()
},
onTransactionIdClick = {
onItemIdClickCount.incrementAndGet()
}
walletRestoringState = WalletRestoringState.NONE,
walletSnapshot = WalletSnapshotFixture.new()
)
}

View File

@ -1,14 +1,16 @@
package co.electriccoin.zcash.ui.screen.account.history
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.account.state.TransactionHistorySyncState
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
import co.electriccoin.zcash.ui.screen.account.view.HistoryContainer
import java.util.concurrent.atomic.AtomicInteger
class HistoryTestSetup(
private val composeTestRule: ComposeContentTestRule,
initialHistorySyncState: TransactionHistorySyncState
initialHistoryUiState: TransactionUiState
) {
private val onItemClickCount = AtomicInteger(0)
private val onItemIdClickCount = AtomicInteger(0)
@ -27,13 +29,12 @@ class HistoryTestSetup(
composeTestRule.setContent {
ZcashTheme {
HistoryContainer(
transactionState = initialHistorySyncState,
onItemClick = {
onItemClickCount.incrementAndGet()
},
onTransactionIdClick = {
transactionState = initialHistoryUiState,
onTransactionItemAction = {
onItemIdClickCount.incrementAndGet()
}
},
walletRestoringState = WalletRestoringState.NONE,
walletSnapshot = WalletSnapshotFixture.new()
)
}
}

View File

@ -3,17 +3,30 @@ package co.electriccoin.zcash.ui.screen.account.history.fixture
import cash.z.ecc.android.sdk.fixture.TransactionOverviewFixture
import cash.z.ecc.android.sdk.model.Account
import cash.z.ecc.android.sdk.model.TransactionRecipient
import cash.z.ecc.android.sdk.type.AddressType
import co.electriccoin.zcash.ui.screen.account.ext.TransactionOverviewExt
import co.electriccoin.zcash.ui.screen.account.state.TransactionHistorySyncState
import co.electriccoin.zcash.ui.screen.account.state.TransactionOverviewExt
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
internal object TransactionHistorySyncStateFixture {
val TRANSACTIONS =
persistentListOf(
TransactionOverviewExt(TransactionOverviewFixture.new(), TransactionRecipient.Account(Account.DEFAULT)),
TransactionOverviewExt(TransactionOverviewFixture.new(), TransactionRecipient.Account(Account(1))),
TransactionOverviewExt(TransactionOverviewFixture.new(), null),
TransactionOverviewExt(
TransactionOverviewFixture.new(),
TransactionRecipient.Account(Account.DEFAULT),
AddressType.Shielded
),
TransactionOverviewExt(
TransactionOverviewFixture.new(),
TransactionRecipient.Account(Account(1)),
AddressType.Transparent
),
TransactionOverviewExt(
TransactionOverviewFixture.new(),
null,
AddressType.Unified
),
)
val STATE = TransactionHistorySyncState.Syncing(TRANSACTIONS)

View File

@ -0,0 +1,22 @@
package co.electriccoin.zcash.ui.screen.account.history.fixture
import co.electriccoin.zcash.ui.screen.account.fixture.TransactionsFixture
import co.electriccoin.zcash.ui.screen.account.model.TransactionUi
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
import kotlinx.collections.immutable.ImmutableList
internal object TransactionHistoryUiStateFixture {
val TRANSACTIONS = TransactionsFixture.new()
val STATE = TransactionUiState.Done(TRANSACTIONS)
fun new(
transactions: ImmutableList<TransactionUi> = TRANSACTIONS,
state: TransactionUiState = STATE
) = when (state) {
is TransactionUiState.Loading -> state
is TransactionUiState.Syncing -> state.copy(transactions)
is TransactionUiState.Done -> state.copy(transactions)
TransactionUiState.DoneEmpty -> state
TransactionUiState.SyncingEmpty -> state
}
}

View File

@ -11,7 +11,8 @@ import androidx.test.filters.MediumTest
import co.electriccoin.zcash.ui.screen.account.HistoryTag
import co.electriccoin.zcash.ui.screen.account.history.HistoryTestSetup
import co.electriccoin.zcash.ui.screen.account.history.fixture.TransactionHistorySyncStateFixture
import co.electriccoin.zcash.ui.screen.account.state.TransactionHistorySyncState
import co.electriccoin.zcash.ui.screen.account.history.fixture.TransactionHistoryUiStateFixture
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
import kotlinx.collections.immutable.persistentListOf
import org.junit.Assert.assertEquals
import org.junit.Rule
@ -26,7 +27,7 @@ class HistoryViewTest {
@Test
@MediumTest
fun check_loading_state() {
newTestSetup(TransactionHistorySyncState.Loading)
newTestSetup(TransactionUiState.Loading)
composeTestRule.onNodeWithTag(HistoryTag.PROGRESS).also {
it.assertExists()
@ -37,9 +38,9 @@ class HistoryViewTest {
@MediumTest
fun check_syncing_state() {
newTestSetup(
TransactionHistorySyncStateFixture.new(
state = TransactionHistorySyncStateFixture.STATE,
transactions = TransactionHistorySyncStateFixture.TRANSACTIONS
TransactionHistoryUiStateFixture.new(
state = TransactionUiState.Syncing(persistentListOf()),
transactions = TransactionHistoryUiStateFixture.TRANSACTIONS
)
)
@ -60,9 +61,9 @@ class HistoryViewTest {
@MediumTest
fun check_done_state_no_transactions() {
newTestSetup(
TransactionHistorySyncStateFixture.new(
state = TransactionHistorySyncState.Done(persistentListOf()),
transactions = persistentListOf()
TransactionHistoryUiStateFixture.new(
state = TransactionUiState.Syncing(persistentListOf()),
transactions = TransactionHistoryUiStateFixture.TRANSACTIONS
)
)
// composeTestRule.onNodeWithText(getStringResource(R.string.history_syncing)).also {
@ -83,9 +84,9 @@ class HistoryViewTest {
@MediumTest
fun check_done_state_with_transactions() {
newTestSetup(
TransactionHistorySyncStateFixture.new(
state = TransactionHistorySyncState.Done(persistentListOf()),
transactions = TransactionHistorySyncStateFixture.TRANSACTIONS
TransactionHistoryUiStateFixture.new(
state = TransactionUiState.Syncing(persistentListOf()),
transactions = TransactionHistoryUiStateFixture.TRANSACTIONS
)
)
// composeTestRule.onNodeWithText(getStringResource(R.string.history_syncing)).also {
@ -106,7 +107,7 @@ class HistoryViewTest {
@Test
@MediumTest
fun item_click_test() {
val testSetup = newTestSetup(TransactionHistorySyncStateFixture.STATE)
val testSetup = newTestSetup(TransactionHistoryUiStateFixture.STATE)
assertEquals(0, testSetup.getOnItemClickCount())
@ -124,7 +125,7 @@ class HistoryViewTest {
@Test
@MediumTest
fun transaction_id_click_test() {
val testSetup = newTestSetup(TransactionHistorySyncStateFixture.STATE)
val testSetup = newTestSetup(TransactionHistoryUiStateFixture.STATE)
assertEquals(0, testSetup.getOnItemIdClickCount())
@ -139,12 +140,10 @@ class HistoryViewTest {
assertEquals(TransactionHistorySyncStateFixture.TRANSACTIONS.size, testSetup.getOnItemIdClickCount())
}
private fun newTestSetup(
transactionHistorySyncState: TransactionHistorySyncState = TransactionHistorySyncStateFixture.new()
): HistoryTestSetup {
private fun newTestSetup(state: TransactionUiState = TransactionHistoryUiStateFixture.new()): HistoryTestSetup {
return HistoryTestSetup(
composeTestRule = composeTestRule,
initialHistorySyncState = transactionHistorySyncState
initialHistoryUiState = state
)
}
}

View File

@ -2,8 +2,10 @@ package co.electriccoin.zcash.ui.screen.balances
import androidx.compose.runtime.Composable
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.screen.balances.model.ShieldState
import co.electriccoin.zcash.ui.screen.balances.view.Balances
import java.util.concurrent.atomic.AtomicInteger
@ -29,17 +31,19 @@ class BalancesTestSetup(
@Suppress("TestFunctionName")
fun DefaultContent() {
Balances(
balanceState = BalanceStateFixture.new(),
onSettings = {
onSettingsCount.incrementAndGet()
},
isDetailedStatus = false,
isFiatConversionEnabled = isShowFiatConversion,
isKeepScreenOnWhileSyncing = false,
isUpdateAvailable = false,
isShowingErrorDialog = false,
setShowErrorDialog = {},
onShielding = {},
shieldState = ShieldState.Available,
walletSnapshot = walletSnapshot,
isShowingErrorDialog = false,
setShowErrorDialog = {}
walletRestoringState = WalletRestoringState.NONE,
)
}

View File

@ -29,9 +29,10 @@ class WalletDisplayValuesTest {
)
val values =
WalletDisplayValues.getNextValues(
getAppContext(),
walletSnapshot,
false
context = getAppContext(),
walletSnapshot = walletSnapshot,
isUpdateAvailable = false,
isDetailedStatus = false
)
assertNotNull(values)

View File

@ -3,6 +3,7 @@ package co.electriccoin.zcash.ui.screen.exportdata.view
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
@ -33,7 +34,7 @@ class ExportPrivateDataViewTestSetup(private val composeTestRule: ComposeContent
@Suppress("TestFunctionName")
fun DefaultContent() {
ExportPrivateData(
SnackbarHostState(),
snackbarHostState = SnackbarHostState(),
onBack = {
onBackCount.incrementAndGet()
},
@ -42,7 +43,8 @@ class ExportPrivateDataViewTestSetup(private val composeTestRule: ComposeContent
},
onConfirm = {
onConfirmCount.incrementAndGet()
}
},
walletRestoringState = WalletRestoringState.NONE
)
}

View File

@ -3,7 +3,7 @@ package co.electriccoin.zcash.ui.screen.onboarding
import androidx.compose.runtime.Composable
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.onboarding.view.ShortOnboarding
import co.electriccoin.zcash.ui.screen.onboarding.view.Onboarding
import java.util.concurrent.atomic.AtomicInteger
class OnboardingTestSetup(
@ -26,9 +26,7 @@ class OnboardingTestSetup(
@Suppress("TestFunctionName")
fun DefaultContent() {
ZcashTheme {
ShortOnboarding(
// It's fine to test the screen UI after the welcome animation
showWelcomeAnim = false,
Onboarding(
// Debug only UI state does not need to be tested
isDebugMenuEnabled = false,
onImportWallet = { onImportWalletCallbackCount.incrementAndGet() },

View File

@ -13,6 +13,7 @@ import co.electriccoin.zcash.ui.test.getStringResource
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import kotlin.test.Ignore
class OnboardingViewTest : UiTestPrerequisites() {
@get:Rule
@ -66,6 +67,7 @@ class OnboardingViewTest : UiTestPrerequisites() {
@Test
@MediumTest
@Ignore("Disabling this until [SemanticNodeInteraction.performScrollTo] works as expected")
fun click_import_wallet() {
val testSetup = newTestSetup()

View File

@ -5,6 +5,7 @@ import androidx.test.filters.MediumTest
import cash.z.ecc.android.sdk.fixture.WalletAddressesFixture
import cash.z.ecc.android.sdk.model.WalletAddresses
import co.electriccoin.zcash.test.UiTestPrerequisites
import co.electriccoin.zcash.ui.common.compose.ScreenBrightnessState
import co.electriccoin.zcash.ui.common.model.VersionInfo
import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
import kotlinx.coroutines.test.runTest
@ -27,7 +28,7 @@ class ReceiveViewScreenBrightnessTest : UiTestPrerequisites() {
VersionInfoFixture.new(isDebuggable = true)
)
assertEquals(0, testSetup.getScreenBrightnessCount())
assertEquals(ScreenBrightnessState.NORMAL, testSetup.getScreenBrightness())
}
@Test
@ -41,13 +42,11 @@ class ReceiveViewScreenBrightnessTest : UiTestPrerequisites() {
VersionInfoFixture.new(isDebuggable = true)
)
assertEquals(false, testSetup.getOnAdjustBrightness())
assertEquals(0, testSetup.getScreenBrightnessCount())
assertEquals(ScreenBrightnessState.NORMAL, testSetup.getOnAdjustBrightness())
composeTestRule.clickAdjustBrightness()
assertEquals(true, testSetup.getOnAdjustBrightness())
assertEquals(1, testSetup.getScreenBrightnessCount())
assertEquals(ScreenBrightnessState.FULL, testSetup.getOnAdjustBrightness())
}
private fun newTestSetup(

View File

@ -40,12 +40,10 @@ class ReceiveViewScreenTimeoutTest : UiTestPrerequisites() {
VersionInfoFixture.new(isDebuggable = true)
)
assertEquals(false, testSetup.getOnAdjustBrightness())
assertEquals(0, testSetup.getScreenTimeoutCount())
composeTestRule.clickAdjustBrightness()
assertEquals(true, testSetup.getOnAdjustBrightness())
assertEquals(1, testSetup.getScreenTimeoutCount())
}

View File

@ -10,12 +10,13 @@ import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.compose.LocalScreenBrightness
import co.electriccoin.zcash.ui.common.compose.LocalScreenTimeout
import co.electriccoin.zcash.ui.common.compose.ScreenBrightness
import co.electriccoin.zcash.ui.common.compose.ScreenBrightnessState
import co.electriccoin.zcash.ui.common.compose.ScreenTimeout
import co.electriccoin.zcash.ui.common.model.VersionInfo
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
import co.electriccoin.zcash.ui.test.getStringResource
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
class ReceiveViewTestSetup(
@ -25,17 +26,17 @@ class ReceiveViewTestSetup(
) {
private val onSettingsCount = AtomicInteger(0)
private val onAddressDetailsCount = AtomicInteger(0)
private val screenBrightness = ScreenBrightness()
private val screenBrightness = ScreenBrightness
private val screenTimeout = ScreenTimeout()
private val onAdjustBrightness = AtomicBoolean(false)
private var onAdjustBrightness: ScreenBrightnessState = ScreenBrightnessState.NORMAL
fun getScreenBrightnessCount() = screenBrightness.referenceCount.value
fun getScreenBrightness() = screenBrightness.referenceSwitch.value
fun getScreenTimeoutCount() = screenTimeout.referenceCount.value
fun getOnAdjustBrightness(): Boolean {
fun getOnAdjustBrightness(): ScreenBrightnessState {
composeTestRule.waitForIdle()
return onAdjustBrightness.get()
return onAdjustBrightness
}
fun getOnSettingsCount(): Int {
@ -63,11 +64,14 @@ class ReceiveViewTestSetup(
onSettingsCount.getAndIncrement()
},
onAdjustBrightness = {
onAdjustBrightness.getAndSet(it)
onAdjustBrightness = onAdjustBrightness.getChange()
screenTimeout.disableScreenTimeout()
},
onAddrCopyToClipboard = {},
onQrImageShare = {},
versionInfo = versionInfo
screenBrightnessState = ScreenBrightnessState.NORMAL,
versionInfo = versionInfo,
walletRestoringState = WalletRestoringState.NONE
)
}
}

View File

@ -1,294 +0,0 @@
package co.electriccoin.zcash.ui.screen.request.view
import androidx.compose.ui.test.assertIsNotEnabled
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performTextClearance
import androidx.compose.ui.test.performTextInput
import androidx.test.filters.MediumTest
import cash.z.ecc.android.sdk.fixture.WalletAddressFixture
import cash.z.ecc.android.sdk.model.MonetarySeparators
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.sdk.fixture.ZecRequestFixture
import cash.z.ecc.sdk.model.ZecRequest
import cash.z.ecc.sdk.model.ZecRequestMessage
import co.electriccoin.zcash.test.UiTestPrerequisites
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.test.getStringResource
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
import java.util.concurrent.atomic.AtomicInteger
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
class RequestViewTest : UiTestPrerequisites() {
@get:Rule
val composeTestRule = createComposeRule()
@Test
@MediumTest
fun create_button_disabled() {
@Suppress("UNUSED_VARIABLE")
val testSetup = TestSetup(composeTestRule)
composeTestRule.assertSendDisabled()
}
@Test
@MediumTest
@OptIn(ExperimentalCoroutinesApi::class)
fun create_request_no_message() =
runTest {
val testSetup = TestSetup(composeTestRule)
assertEquals(0, testSetup.getOnCreateCount())
assertEquals(null, testSetup.getLastCreateZecRequest())
composeTestRule.setValidAmount()
composeTestRule.clickCreateAndSend()
assertEquals(1, testSetup.getOnCreateCount())
testSetup.getLastCreateZecRequest().also {
assertNotNull(it)
assertEquals(WalletAddressFixture.unified(), it.address)
assertEquals(Zatoshi(12345600000), it.amount)
assertTrue(it.message.value.isEmpty())
}
}
@Test
@MediumTest
@OptIn(ExperimentalCoroutinesApi::class)
fun create_request_with_message() =
runTest {
val testSetup = TestSetup(composeTestRule)
assertEquals(0, testSetup.getOnCreateCount())
assertEquals(null, testSetup.getLastCreateZecRequest())
composeTestRule.setValidAmount()
composeTestRule.setValidMessage()
composeTestRule.clickCreateAndSend()
assertEquals(1, testSetup.getOnCreateCount())
testSetup.getLastCreateZecRequest().also {
assertNotNull(it)
assertEquals(WalletAddressFixture.unified(), it.address)
assertEquals(Zatoshi(12345600000), it.amount)
assertEquals(ZecRequestFixture.MESSAGE.value, it.message.value)
}
}
@Test
@MediumTest
fun check_regex_functionality_valid_inputs() {
val testSetup = TestSetup(composeTestRule)
val separators = MonetarySeparators.current()
assertEquals(0, testSetup.getOnCreateCount())
assertEquals(null, testSetup.getLastCreateZecRequest())
composeTestRule.setAmount("123")
composeTestRule.clickCreateAndSend()
assertEquals(1, testSetup.getOnCreateCount())
// e.g. 123,456
composeTestRule.setAmount("123${separators.grouping}456")
composeTestRule.clickCreateAndSend()
assertEquals(2, testSetup.getOnCreateCount())
// e.g. 123.
composeTestRule.setAmount("123${separators.decimal}")
composeTestRule.clickCreateAndSend()
assertEquals(3, testSetup.getOnCreateCount())
// e.g. 123,456.
composeTestRule.setAmount("123${separators.grouping}456${separators.decimal}")
composeTestRule.clickCreateAndSend()
assertEquals(4, testSetup.getOnCreateCount())
// e.g. 123,456.789
composeTestRule.setAmount("123${separators.grouping}456${separators.decimal}789")
composeTestRule.clickCreateAndSend()
assertEquals(5, testSetup.getOnCreateCount())
}
@Test
@MediumTest
fun check_regex_functionality_invalid_inputs() {
val testSetup = TestSetup(composeTestRule)
val separators = MonetarySeparators.current()
assertEquals(0, testSetup.getOnCreateCount())
assertEquals(null, testSetup.getLastCreateZecRequest())
composeTestRule.setAmount("aaa")
composeTestRule.clickCreateAndSend()
assertEquals(0, testSetup.getOnCreateCount())
composeTestRule.setAmount("123aaa")
composeTestRule.clickCreateAndSend()
assertEquals(0, testSetup.getOnCreateCount())
// e.g. ,.
composeTestRule.setAmount("${separators.grouping}${separators.decimal}")
composeTestRule.clickCreateAndSend()
assertEquals(0, testSetup.getOnCreateCount())
// e.g. 123,.
composeTestRule.setAmount("123${separators.grouping}${separators.decimal}")
composeTestRule.clickCreateAndSend()
assertEquals(0, testSetup.getOnCreateCount())
// e.g. 1,2,3
composeTestRule.setAmount("1${separators.grouping}2${separators.grouping}3")
composeTestRule.clickCreateAndSend()
assertEquals(0, testSetup.getOnCreateCount())
// e.g. 1.2.3
composeTestRule.setAmount("1${separators.decimal}2${separators.decimal}3")
composeTestRule.clickCreateAndSend()
assertEquals(0, testSetup.getOnCreateCount())
}
@Test
@MediumTest
@OptIn(ExperimentalCoroutinesApi::class)
fun max_message_length() =
runTest {
val testSetup = TestSetup(composeTestRule)
composeTestRule.setValidAmount()
composeTestRule.setMessage(
buildString {
repeat(ZecRequestMessage.MAX_MESSAGE_LENGTH + 1) { number ->
append("$number")
}
}
)
composeTestRule.clickCreateAndSend()
assertEquals(1, testSetup.getOnCreateCount())
testSetup.getLastCreateZecRequest().also {
assertNotNull(it)
assertEquals(WalletAddressFixture.unified(), it.address)
assertEquals(Zatoshi(12345600000), it.amount)
assertTrue(it.message.value.isEmpty())
}
}
@Test
@MediumTest
fun back() {
val testSetup = TestSetup(composeTestRule)
assertEquals(0, testSetup.getOnBackCount())
composeTestRule.clickBack()
assertEquals(1, testSetup.getOnBackCount())
}
private class TestSetup(private val composeTestRule: ComposeContentTestRule) {
private val onBackCount = AtomicInteger(0)
private val onCreateCount = AtomicInteger(0)
@Volatile
private var onCreateZecRequest: ZecRequest? = null
fun getOnBackCount(): Int {
composeTestRule.waitForIdle()
return onBackCount.get()
}
fun getOnCreateCount(): Int {
composeTestRule.waitForIdle()
return onCreateCount.get()
}
fun getLastCreateZecRequest(): ZecRequest? {
composeTestRule.waitForIdle()
return onCreateZecRequest
}
init {
composeTestRule.setContent {
ZcashTheme {
Request(
myAddress = runBlocking { WalletAddressFixture.unified() },
goBack = {
onBackCount.incrementAndGet()
},
onCreateAndSend = {
onCreateCount.incrementAndGet()
onCreateZecRequest = it
}
)
}
}
}
}
}
private fun ComposeContentTestRule.clickBack() {
onNodeWithContentDescription(getStringResource(R.string.request_back_content_description)).also {
it.performClick()
}
}
private fun ComposeContentTestRule.setValidAmount() {
onNodeWithText(getStringResource(R.string.request_amount)).also {
val separators = MonetarySeparators.current()
it.performTextClearance()
it.performTextInput("123${separators.decimal}456")
}
}
private fun ComposeContentTestRule.setAmount(amount: String) {
onNodeWithText(getStringResource(R.string.request_amount)).also {
it.performTextClearance()
it.performTextInput(amount)
}
}
private fun ComposeContentTestRule.setValidMessage() {
onNodeWithText(getStringResource(R.string.request_message)).also {
it.performTextClearance()
it.performTextInput(ZecRequestFixture.MESSAGE.value)
}
}
private fun ComposeContentTestRule.setMessage(message: String) {
onNodeWithText(getStringResource(R.string.request_message)).also {
it.performTextClearance()
it.performTextInput(message)
}
}
private fun ComposeContentTestRule.clickCreateAndSend() {
onNodeWithText(getStringResource(R.string.request_create), ignoreCase = true).also {
it.performClick()
}
}
private fun ComposeContentTestRule.assertSendDisabled() {
onNodeWithText(getStringResource(R.string.request_create), ignoreCase = true).also {
it.assertIsNotEnabled()
}
}

View File

@ -2,7 +2,6 @@ package co.electriccoin.zcash.ui.screen.scan.view
import android.Manifest
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
@ -33,12 +32,12 @@ class ScanViewBasicTest : UiTestPrerequisites() {
@Test
@MediumTest
fun back() {
fun cancel() {
val testSetup = newTestSetup()
assertEquals(0, testSetup.getOnBackCount())
composeTestRule.onNodeWithContentDescription(getStringResource(R.string.scan_back_content_description)).also {
composeTestRule.onNodeWithText(getStringResource(R.string.scan_cancel_button).uppercase()).also {
it.performClick()
}
@ -52,7 +51,7 @@ class ScanViewBasicTest : UiTestPrerequisites() {
// Permission granted ui items (visible):
composeTestRule.onNodeWithText(getStringResource(R.string.scan_header)).also {
composeTestRule.onNodeWithText(getStringResource(R.string.scan_cancel_button).uppercase()).also {
it.assertIsDisplayed()
}
@ -62,12 +61,7 @@ class ScanViewBasicTest : UiTestPrerequisites() {
it.assertIsDisplayed()
}
composeTestRule.onNodeWithTag(ScanTag.TEXT_STATE).also {
it.assertIsDisplayed()
it.assertTextEquals(getStringResource(R.string.scan_state_scanning))
}
composeTestRule.onNodeWithText(getStringResource(R.string.scan_hint)).also {
composeTestRule.onNodeWithContentDescription(getStringResource(R.string.scan_torch_content_description)).also {
it.assertIsDisplayed()
}

View File

@ -3,6 +3,8 @@ package co.electriccoin.zcash.ui.screen.scan.view
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import cash.z.ecc.android.sdk.type.AddressType
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.scan.model.ScanState
import java.util.concurrent.atomic.AtomicInteger
@ -36,7 +38,9 @@ class ScanViewBasicTestSetup(
onOpenSettings = {},
onScanStateChanged = {
scanState.set(it)
}
},
walletRestoringState = WalletRestoringState.NONE,
addressValidationResult = AddressType.Shielded
)
}

View File

@ -17,7 +17,7 @@ import org.junit.Rule
import kotlin.test.Test
import kotlin.test.assertEquals
class SeedRecoveryViewTest : UiTestPrerequisites() {
class SeedRecoveryRecoveryViewTest : UiTestPrerequisites() {
@get:Rule
val composeTestRule = createComposeRule()

View File

@ -8,6 +8,7 @@ import cash.z.ecc.sdk.fixture.PersistableWalletFixture
import co.electriccoin.zcash.test.UiTestPrerequisites
import co.electriccoin.zcash.ui.common.compose.LocalScreenSecurity
import co.electriccoin.zcash.ui.common.compose.ScreenSecurity
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
import kotlinx.coroutines.test.runTest
@ -15,7 +16,7 @@ import org.junit.Rule
import org.junit.Test
import kotlin.test.assertEquals
class SeedRecoveryViewsSecuredScreenTest : UiTestPrerequisites() {
class SeedRecoveryRecoveryViewsSecuredScreenTest : UiTestPrerequisites() {
@get:Rule
val composeTestRule = createComposeRule()
@ -45,10 +46,11 @@ class SeedRecoveryViewsSecuredScreenTest : UiTestPrerequisites() {
SeedRecovery(
PersistableWalletFixture.new(),
onBack = {},
onSeedCopy = {},
onBirthdayCopy = {},
onDone = {},
versionInfo = VersionInfoFixture.new()
onSeedCopy = {},
versionInfo = VersionInfoFixture.new(),
walletRestoringState = WalletRestoringState.NONE
)
}
}

View File

@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import cash.z.ecc.sdk.fixture.PersistableWalletFixture
import co.electriccoin.zcash.ui.common.model.VersionInfo
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import java.util.concurrent.atomic.AtomicInteger
@ -39,10 +40,11 @@ class SeedRecoveryTestSetup(
SeedRecovery(
PersistableWalletFixture.new(),
onBack = { onBackCount.incrementAndGet() },
onSeedCopy = { /* Not tested - debug mode feature only */ },
onBirthdayCopy = { onBirthdayCopyCount.incrementAndGet() },
onDone = { onCompleteCallbackCount.incrementAndGet() },
onSeedCopy = { /* Not tested - debug mode feature only */ },
versionInfo = versionInfo,
walletRestoringState = WalletRestoringState.NONE,
)
}
}

View File

@ -18,12 +18,6 @@ import co.electriccoin.zcash.ui.test.getAppContext
import co.electriccoin.zcash.ui.test.getStringResource
import co.electriccoin.zcash.ui.test.getStringResourceWithArgs
internal fun ComposeContentTestRule.clickBack() {
onNodeWithContentDescription(getStringResource(R.string.send_back_content_description)).also {
it.performClick()
}
}
internal fun ComposeContentTestRule.clickSettingsTopAppBarMenu() {
onNodeWithContentDescription(getStringResource(R.string.settings_menu_content_description)).also {
it.performClick()

View File

@ -12,7 +12,9 @@ import cash.z.ecc.android.sdk.model.MonetarySeparators
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.model.ZecSend
import cash.z.ecc.android.sdk.type.AddressType
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.send.ext.Saver
import co.electriccoin.zcash.ui.screen.send.model.AmountState
@ -77,9 +79,7 @@ class SendViewTestSetup(
fun DefaultContent() {
val context = LocalContext.current
// TODO [#1171]: Remove default MonetarySeparators locale
// TODO [#1171]: https://github.com/Electric-Coin-Company/zashi-android/issues/1171
val monetarySeparators = MonetarySeparators.current(Locale.US)
val monetarySeparators = MonetarySeparators.current(Locale.getDefault())
val (sendStage, setSendStage) =
rememberSaveable(stateSaver = SendStage.Saver) { mutableStateOf(initialState) }
@ -108,13 +108,7 @@ class SendViewTestSetup(
// TODO [#1260]: Cover Send.Form screen UI with tests
// TODO [#1260]: https://github.com/Electric-Coin-Company/zashi-android/issues/1260
Send(
walletSnapshot =
WalletSnapshotFixture.new(
saplingBalance =
WalletBalanceFixture.new(
available = Zatoshi(Zatoshi.MAX_INCLUSIVE.div(100))
)
),
balanceState = BalanceStateFixture.new(),
sendStage = sendStage,
onCreateZecSend = setZecSend,
focusManager = LocalFocusManager.current,
@ -133,10 +127,18 @@ class SendViewTestSetup(
// TODO [#1260]: Cover Send.Form screen UI with tests
// TODO [#1260]: https://github.com/Electric-Coin-Company/zashi-android/issues/1260
},
amountState = AmountState.new(context, "", monetarySeparators),
setAmountState = {},
memoState = MemoState.new(""),
amountState = AmountState.new(context, monetarySeparators, "", false),
setMemoState = {},
memoState = MemoState.new(""),
walletRestoringState = WalletRestoringState.NONE,
walletSnapshot =
WalletSnapshotFixture.new(
saplingBalance =
WalletBalanceFixture.new(
available = Zatoshi(Zatoshi.MAX_INCLUSIVE.div(100))
)
),
)
}
}

View File

@ -11,12 +11,13 @@ import cash.z.ecc.android.sdk.model.MonetarySeparators
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.model.ZcashNetwork
import cash.z.ecc.sdk.fixture.ZecSendFixture
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.fixture.MockSynchronizer
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.send.WrapSend
import co.electriccoin.zcash.ui.screen.send.assertOnConfirmation
import co.electriccoin.zcash.ui.screen.send.assertOnForm
import co.electriccoin.zcash.ui.screen.send.clickBack
import co.electriccoin.zcash.ui.screen.send.clickCreateAndSend
import co.electriccoin.zcash.ui.screen.send.setAddress
import co.electriccoin.zcash.ui.screen.send.setAmount
@ -49,9 +50,7 @@ class SendViewIntegrationTest {
)
)
// TODO [#1171]: Remove default MonetarySeparators locale
// TODO [#1171]: https://github.com/Electric-Coin-Company/zashi-android/issues/1171
private val monetarySeparators = MonetarySeparators.current(Locale.US)
private val monetarySeparators = MonetarySeparators.current(Locale.getDefault())
// TODO [#1260]: Cover Send screens UI with tests
// TODO [#1260]: https://github.com/Electric-Coin-Company/zashi-android/issues/1260
@ -67,18 +66,20 @@ class SendViewIntegrationTest {
restorationTester.setContent {
WrapSend(
balanceState = BalanceStateFixture.new(),
sendArguments = null,
focusManager = LocalFocusManager.current,
synchronizer = synchronizer,
walletSnapshot = walletSnapshot,
spendingKey = spendingKey,
focusManager = LocalFocusManager.current,
goToQrScanner = {},
goBack = {},
goBalances = {},
hasCameraFeature = true,
goSettings = {},
goSendConfirmation = {},
hasCameraFeature = true,
monetarySeparators = monetarySeparators,
goSendConfirmation = {}
walletRestoringState = WalletRestoringState.NONE,
)
}
@ -98,7 +99,6 @@ class SendViewIntegrationTest {
composeTestRule.assertOnConfirmation()
// Move back to form
composeTestRule.clickBack()
composeTestRule.assertOnForm()
composeTestRule.onNodeWithText(ZecSendFixture.ADDRESS).also {

View File

@ -25,7 +25,6 @@ import co.electriccoin.zcash.ui.screen.send.assertOnForm
import co.electriccoin.zcash.ui.screen.send.assertOnSendFailure
import co.electriccoin.zcash.ui.screen.send.assertSendDisabled
import co.electriccoin.zcash.ui.screen.send.assertSendEnabled
import co.electriccoin.zcash.ui.screen.send.clickBack
import co.electriccoin.zcash.ui.screen.send.clickCreateAndSend
import co.electriccoin.zcash.ui.screen.send.clickScanner
import co.electriccoin.zcash.ui.screen.send.clickSettingsTopAppBarMenu
@ -310,7 +309,6 @@ class SendViewTest : UiTestPrerequisites() {
composeTestRule.setValidAddress()
composeTestRule.clickCreateAndSend()
composeTestRule.assertOnConfirmation()
composeTestRule.clickBack()
composeTestRule.assertOnForm()
assertEquals(1, testSetup.getOnBackCount())

View File

@ -1,6 +1,7 @@
package co.electriccoin.zcash.ui.screen.settings
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.settings.model.TroubleshootingParameters
import co.electriccoin.zcash.ui.screen.settings.view.Settings
@ -87,7 +88,8 @@ class SettingsViewTestSetup(
},
onAnalyticsSettingsChanged = {
onAnalyticsChangedCount.incrementAndGet()
}
},
walletRestoringState = WalletRestoringState.NONE
)
}
}

View File

@ -3,6 +3,7 @@ package co.electriccoin.zcash.ui.screen.support.view
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicReference
@ -36,7 +37,8 @@ class SupportViewTestSetup(private val composeTestRule: ComposeContentTestRule)
@Suppress("TestFunctionName")
fun DefaultContent() {
Support(
snackbarHostState = SnackbarHostState(),
isShowingDialog = false,
setShowDialog = {},
onBack = {
onBackCount.incrementAndGet()
},
@ -44,8 +46,8 @@ class SupportViewTestSetup(private val composeTestRule: ComposeContentTestRule)
onSendCount.incrementAndGet()
onSendMessage.set(it)
},
isShowingDialog = false,
setShowDialog = {}
snackbarHostState = SnackbarHostState(),
walletRestoringState = WalletRestoringState.NONE
)
}

View File

@ -6,6 +6,7 @@ import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollTo
import androidx.test.filters.MediumTest
import co.electriccoin.zcash.test.UiTestPrerequisites
import co.electriccoin.zcash.ui.R
@ -147,6 +148,7 @@ class UpdateViewTest : UiTestPrerequisites() {
composeTestRule.onNodeWithText(getStringResource(R.string.update_link_text)).also {
it.assertExists()
it.performScrollTo()
it.performClick()
}

View File

@ -4,15 +4,16 @@ import android.annotation.SuppressLint
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.os.SystemClock
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.annotation.VisibleForTesting
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
@ -26,23 +27,33 @@ import cash.z.ecc.android.sdk.model.SeedPhrase
import cash.z.ecc.android.sdk.model.ZcashNetwork
import cash.z.ecc.sdk.type.fromResources
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.common.compose.BindCompLocalProvider
import co.electriccoin.zcash.ui.common.model.OnboardingState
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.viewmodel.AuthenticationUIState
import co.electriccoin.zcash.ui.common.viewmodel.AuthenticationViewModel
import co.electriccoin.zcash.ui.common.viewmodel.HomeViewModel
import co.electriccoin.zcash.ui.common.viewmodel.SecretState
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
import co.electriccoin.zcash.ui.configuration.RemoteConfig
import co.electriccoin.zcash.ui.design.component.AnimationConstants
import co.electriccoin.zcash.ui.design.component.ConfigurationOverride
import co.electriccoin.zcash.ui.design.component.GradientSurface
import co.electriccoin.zcash.ui.design.component.Override
import co.electriccoin.zcash.ui.design.component.WelcomeAnimationAutostart
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.authentication.AuthenticationUseCase
import co.electriccoin.zcash.ui.screen.authentication.WrapAuthentication
import co.electriccoin.zcash.ui.screen.newwalletrecovery.WrapNewWalletRecovery
import co.electriccoin.zcash.ui.screen.onboarding.WrapOnboarding
import co.electriccoin.zcash.ui.screen.onboarding.persistExistingWalletWithSeedPhrase
import co.electriccoin.zcash.ui.screen.securitywarning.WrapSecurityWarning
import co.electriccoin.zcash.ui.screen.support.WrapSupport
import co.electriccoin.zcash.ui.screen.warning.WrapNotEnoughSpace
import co.electriccoin.zcash.ui.screen.warning.viewmodel.StorageCheckViewModel
import co.electriccoin.zcash.work.WorkIds
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
@ -52,14 +63,18 @@ import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
class MainActivity : ComponentActivity() {
val homeViewModel by viewModels<HomeViewModel>()
class MainActivity : AppCompatActivity() {
private val homeViewModel by viewModels<HomeViewModel>()
val walletViewModel by viewModels<WalletViewModel>()
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
val storageCheckViewModel by viewModels<StorageCheckViewModel>()
internal val authenticationViewModel by viewModels<AuthenticationViewModel> {
AuthenticationViewModel.AuthenticationViewModelFactory(application)
}
lateinit var navControllerForTesting: NavHostController
val configurationOverrideFlow = MutableStateFlow<ConfigurationOverride?>(null)
@ -129,6 +144,8 @@ class MainActivity : ComponentActivity() {
} else {
MainContent()
}
AuthenticationForAppAccess()
}
}
}
@ -140,6 +157,67 @@ class MainActivity : ComponentActivity() {
}
}
@Composable
private fun AuthenticationForAppAccess() {
val authState = authenticationViewModel.appAccessAuthenticationResultState.collectAsStateWithLifecycle().value
val animateAppAccess = authenticationViewModel.showWelcomeAnimation.collectAsStateWithLifecycle().value
when (authState) {
AuthenticationUIState.Initial -> {
Twig.debug { "Authentication initial state" }
// Wait for the state update
}
AuthenticationUIState.NotRequired -> {
Twig.debug { "App access authentication NOT required - welcome animation only" }
if (animateAppAccess) {
WelcomeAnimationAutostart(
delay = AnimationConstants.INITIAL_DELAY.milliseconds
)
// Wait until the welcome animation finishes then mark it was shown
LaunchedEffect(key1 = authenticationViewModel.showWelcomeAnimation) {
delay(AnimationConstants.together())
authenticationViewModel.setWelcomeAnimationDisplayed()
}
}
}
AuthenticationUIState.Required -> {
Twig.debug { "App access authentication required" }
// Check and trigger app access authentication if required
// Note that the Welcome animation is part of its logic
WrapAuthentication(
goSupport = {
authenticationViewModel.appAccessAuthentication.value = AuthenticationUIState.SupportedRequired
},
onSuccess = {
lifecycleScope.launch {
// Wait until the welcome animation finishes, then mark it as presented to the user
delay((AnimationConstants.together()).milliseconds)
authenticationViewModel.appAccessAuthentication.value = AuthenticationUIState.Successful
}
},
onCancel = {
finish()
},
onFailed = {
// No subsequent action required. User is prompted with an explanation dialog.
},
useCase = AuthenticationUseCase.AppAccess
)
}
AuthenticationUIState.SupportedRequired -> {
Twig.debug { "Authentication support required" }
WrapSupport(
goBack = { finish() }
)
}
AuthenticationUIState.Successful -> {
Twig.debug { "Authentication successful - entering the app" }
// No action is needed - the main app content is laid out now
}
}
}
@Composable
private fun MainContent() {
val configuration = homeViewModel.configurationFlow.collectAsStateWithLifecycle().value
@ -173,6 +251,7 @@ class MainActivity : ComponentActivity() {
)
} else {
walletViewModel.persistNewWallet()
walletViewModel.persistWalletRestoringState(WalletRestoringState.INITIATING)
}
}
)

View File

@ -1,13 +1,20 @@
package co.electriccoin.zcash.ui
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavHostController
import androidx.navigation.NavOptionsBuilder
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import cash.z.ecc.android.sdk.model.ZecSend
import co.electriccoin.zcash.ui.NavigationArguments.MULTIPLE_SUBMISSION_CLEAR_FORM
import co.electriccoin.zcash.ui.NavigationArguments.SEND_CONFIRM_AMOUNT
import co.electriccoin.zcash.ui.NavigationArguments.SEND_CONFIRM_INITIAL_STAGE
import co.electriccoin.zcash.ui.NavigationArguments.SEND_CONFIRM_MEMO
import co.electriccoin.zcash.ui.NavigationArguments.SEND_CONFIRM_PROPOSAL
import co.electriccoin.zcash.ui.NavigationArguments.SEND_CONFIRM_RECIPIENT_ADDRESS
@ -15,9 +22,9 @@ import co.electriccoin.zcash.ui.NavigationArguments.SEND_SCAN_RECIPIENT_ADDRESS
import co.electriccoin.zcash.ui.NavigationTargets.ABOUT
import co.electriccoin.zcash.ui.NavigationTargets.ADVANCED_SETTINGS
import co.electriccoin.zcash.ui.NavigationTargets.CHOOSE_SERVER
import co.electriccoin.zcash.ui.NavigationTargets.DELETE_WALLET
import co.electriccoin.zcash.ui.NavigationTargets.EXPORT_PRIVATE_DATA
import co.electriccoin.zcash.ui.NavigationTargets.HOME
import co.electriccoin.zcash.ui.NavigationTargets.REQUEST
import co.electriccoin.zcash.ui.NavigationTargets.SCAN
import co.electriccoin.zcash.ui.NavigationTargets.SEED_RECOVERY
import co.electriccoin.zcash.ui.NavigationTargets.SEND_CONFIRMATION
@ -32,19 +39,25 @@ import co.electriccoin.zcash.ui.design.animation.ScreenAnimation.popEnterTransit
import co.electriccoin.zcash.ui.design.animation.ScreenAnimation.popExitTransition
import co.electriccoin.zcash.ui.screen.about.WrapAbout
import co.electriccoin.zcash.ui.screen.advancedsettings.WrapAdvancedSettings
import co.electriccoin.zcash.ui.screen.authentication.AuthenticationUseCase
import co.electriccoin.zcash.ui.screen.authentication.WrapAuthentication
import co.electriccoin.zcash.ui.screen.chooseserver.WrapChooseServer
import co.electriccoin.zcash.ui.screen.deletewallet.WrapDeleteWallet
import co.electriccoin.zcash.ui.screen.exportdata.WrapExportPrivateData
import co.electriccoin.zcash.ui.screen.home.WrapHome
import co.electriccoin.zcash.ui.screen.request.WrapRequest
import co.electriccoin.zcash.ui.screen.scan.WrapScanValidator
import co.electriccoin.zcash.ui.screen.seedrecovery.WrapSeedRecovery
import co.electriccoin.zcash.ui.screen.send.ext.toSerializableAddress
import co.electriccoin.zcash.ui.screen.send.model.SendArguments
import co.electriccoin.zcash.ui.screen.sendconfirmation.WrapSendConfirmation
import co.electriccoin.zcash.ui.screen.sendconfirmation.model.SendConfirmationArguments
import co.electriccoin.zcash.ui.screen.sendconfirmation.model.SendConfirmationStage
import co.electriccoin.zcash.ui.screen.settings.WrapSettings
import co.electriccoin.zcash.ui.screen.support.WrapSupport
import co.electriccoin.zcash.ui.screen.update.WrapCheckForUpdate
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
// TODO [#1297]: Consider: Navigation passing complex data arguments different way
@ -58,6 +71,14 @@ internal fun MainActivity.Navigation() {
navControllerForTesting = it
}
// Helper properties for triggering the system security UI from callbacks
val (exportPrivateDataAuthentication, setExportPrivateDataAuthentication) =
rememberSaveable { mutableStateOf(false) }
val (seedRecoveryAuthentication, setSeedRecoveryAuthentication) =
rememberSaveable { mutableStateOf(false) }
val (deleteWalletAuthentication, setDeleteWalletAuthentication) =
rememberSaveable { mutableStateOf(false) }
NavHost(
navController = navController,
startDestination = HOME,
@ -70,23 +91,21 @@ internal fun MainActivity.Navigation() {
WrapHome(
goBack = { finish() },
goScan = { navController.navigateJustOnce(SCAN) },
onPageChange = {
homeViewModel.screenIndex.value = it
},
goSendConfirmation = { zecSend ->
navController.currentBackStackEntry?.savedStateHandle?.let { handle ->
handle[SEND_CONFIRM_RECIPIENT_ADDRESS] =
Json.encodeToString(
serializer = SerializableAddress.serializer(),
value = zecSend.destination.toSerializableAddress()
)
handle[SEND_CONFIRM_AMOUNT] = zecSend.amount.value
handle[SEND_CONFIRM_MEMO] = zecSend.memo.value
handle[SEND_CONFIRM_PROPOSAL] = zecSend.proposal?.toByteArray()
fillInHandleForConfirmation(handle, zecSend, SendConfirmationStage.Confirmation)
}
navController.navigateJustOnce(SEND_CONFIRMATION)
},
goSettings = { navController.navigateJustOnce(SETTINGS) },
goMultiTrxSubmissionFailure = {
// Ultimately we could approach reworking the MultipleTrxFailure screen into a separate
// navigation endpoint
navController.currentBackStackEntry?.savedStateHandle?.let { handle ->
fillInHandleForConfirmation(handle, null, SendConfirmationStage.MultipleTrxFailure)
}
navController.navigateJustOnce(SEND_CONFIRMATION)
},
sendArguments =
SendArguments(
recipientAddress =
@ -128,15 +147,60 @@ internal fun MainActivity.Navigation() {
navController.popBackStackJustOnce(ADVANCED_SETTINGS)
},
goExportPrivateData = {
navController.navigateJustOnce(EXPORT_PRIVATE_DATA)
navController.checkProtectedDestination(
scope = lifecycleScope,
propertyToCheck = authenticationViewModel.isExportPrivateDataAuthenticationRequired,
setCheckedProperty = setExportPrivateDataAuthentication,
unProtectedDestination = EXPORT_PRIVATE_DATA
)
},
goSeedRecovery = {
navController.navigateJustOnce(SEED_RECOVERY)
navController.checkProtectedDestination(
scope = lifecycleScope,
propertyToCheck = authenticationViewModel.isSeedAuthenticationRequired,
setCheckedProperty = setSeedRecoveryAuthentication,
unProtectedDestination = SEED_RECOVERY
)
},
goChooseServer = {
navController.navigateJustOnce(CHOOSE_SERVER)
}
},
goDeleteWallet = {
navController.checkProtectedDestination(
scope = lifecycleScope,
propertyToCheck = authenticationViewModel.isDeleteWalletAuthenticationRequired,
setCheckedProperty = setDeleteWalletAuthentication,
unProtectedDestination = DELETE_WALLET
)
},
)
when {
deleteWalletAuthentication -> {
ShowSystemAuthentication(
navHostController = navController,
protectedDestination = DELETE_WALLET,
protectedUseCase = AuthenticationUseCase.DeleteWallet,
setCheckedProperty = setDeleteWalletAuthentication
)
}
exportPrivateDataAuthentication -> {
ShowSystemAuthentication(
navHostController = navController,
protectedDestination = EXPORT_PRIVATE_DATA,
protectedUseCase = AuthenticationUseCase.ExportPrivateData,
setCheckedProperty = setExportPrivateDataAuthentication
)
}
seedRecoveryAuthentication -> {
ShowSystemAuthentication(
navHostController = navController,
protectedDestination = SEED_RECOVERY,
protectedUseCase = AuthenticationUseCase.SeedRecovery,
setCheckedProperty = setSeedRecoveryAuthentication
)
}
}
}
composable(CHOOSE_SERVER) {
WrapChooseServer(
@ -148,20 +212,27 @@ internal fun MainActivity.Navigation() {
composable(SEED_RECOVERY) {
WrapSeedRecovery(
goBack = {
setSeedRecoveryAuthentication(false)
navController.popBackStackJustOnce(SEED_RECOVERY)
},
onDone = {
setSeedRecoveryAuthentication(false)
navController.popBackStackJustOnce(SEED_RECOVERY)
}
},
)
}
composable(REQUEST) {
WrapRequest(goBack = { navController.popBackStackJustOnce(REQUEST) })
}
composable(SUPPORT) {
// Pop back stack won't be right if we deep link into support
WrapSupport(goBack = { navController.popBackStackJustOnce(SUPPORT) })
}
composable(DELETE_WALLET) {
WrapDeleteWallet(
goBack = {
setDeleteWalletAuthentication(false)
navController.popBackStackJustOnce(DELETE_WALLET)
}
)
}
composable(ABOUT) {
WrapAbout(goBack = { navController.popBackStackJustOnce(ABOUT) })
}
@ -181,8 +252,14 @@ internal fun MainActivity.Navigation() {
}
composable(EXPORT_PRIVATE_DATA) {
WrapExportPrivateData(
goBack = { navController.popBackStackJustOnce(EXPORT_PRIVATE_DATA) },
onConfirm = { navController.popBackStackJustOnce(EXPORT_PRIVATE_DATA) }
goBack = {
setExportPrivateDataAuthentication(false)
navController.popBackStackJustOnce(EXPORT_PRIVATE_DATA)
},
onConfirm = {
setExportPrivateDataAuthentication(false)
navController.popBackStackJustOnce(EXPORT_PRIVATE_DATA)
}
)
}
composable(route = SEND_CONFIRMATION) {
@ -195,21 +272,79 @@ internal fun MainActivity.Navigation() {
navController.popBackStackJustOnce(SEND_CONFIRMATION)
},
goHome = { navController.navigateJustOnce(HOME) },
arguments =
SendConfirmationArguments.fromSavedStateHandle(backStackEntry.savedStateHandle).also {
// Remove SendConfirmation screen arguments passed from the Send screen if some exist
// after we use them
backStackEntry.savedStateHandle.remove<String>(SEND_CONFIRM_RECIPIENT_ADDRESS)
backStackEntry.savedStateHandle.remove<Long>(SEND_CONFIRM_AMOUNT)
backStackEntry.savedStateHandle.remove<String>(SEND_CONFIRM_MEMO)
backStackEntry.savedStateHandle.remove<ByteArray>(SEND_CONFIRM_PROPOSAL)
}
goSupport = { navController.navigateJustOnce(SUPPORT) },
arguments = SendConfirmationArguments.fromSavedStateHandle(backStackEntry.savedStateHandle)
)
}
}
}
}
@Composable
private fun MainActivity.ShowSystemAuthentication(
navHostController: NavHostController,
protectedDestination: String,
protectedUseCase: AuthenticationUseCase,
setCheckedProperty: (Boolean) -> Unit,
) {
WrapAuthentication(
goSupport = {
setCheckedProperty(false)
navHostController.navigateJustOnce(SUPPORT)
},
onSuccess = {
navHostController.navigateJustOnce(protectedDestination)
},
onCancel = {
setCheckedProperty(false)
},
onFailed = {
setCheckedProperty(false)
},
useCase = protectedUseCase
)
}
/**
* Check and trigger authentication if required, navigate to the destination otherwise
*/
private fun NavHostController.checkProtectedDestination(
scope: LifecycleCoroutineScope,
propertyToCheck: StateFlow<Boolean?>,
setCheckedProperty: (Boolean) -> Unit,
unProtectedDestination: String
) {
scope.launch {
propertyToCheck
.filterNotNull()
.collect { isProtected ->
if (isProtected) {
setCheckedProperty(true)
} else {
navigateJustOnce(unProtectedDestination)
}
}
}
}
private fun fillInHandleForConfirmation(
handle: SavedStateHandle,
zecSend: ZecSend?,
initialStage: SendConfirmationStage
) {
if (zecSend != null) {
handle[SEND_CONFIRM_RECIPIENT_ADDRESS] =
Json.encodeToString(
serializer = SerializableAddress.serializer(),
value = zecSend.destination.toSerializableAddress()
)
handle[SEND_CONFIRM_AMOUNT] = zecSend.amount.value
handle[SEND_CONFIRM_MEMO] = zecSend.memo.value
handle[SEND_CONFIRM_PROPOSAL] = zecSend.proposal?.toByteArray()
}
handle[SEND_CONFIRM_INITIAL_STAGE] = initialStage.toStringName()
}
private fun NavHostController.navigateJustOnce(
route: String,
navOptionsBuilder: (NavOptionsBuilder.() -> Unit)? = null
@ -245,6 +380,7 @@ object NavigationArguments {
const val SEND_CONFIRM_AMOUNT = "send_confirm_amount"
const val SEND_CONFIRM_MEMO = "send_confirm_memo"
const val SEND_CONFIRM_PROPOSAL = "send_confirm_proposal"
const val SEND_CONFIRM_INITIAL_STAGE = "send_confirm_initial_stage"
const val MULTIPLE_SUBMISSION_CLEAR_FORM = "multiple_submission_clear_form"
}
@ -252,10 +388,10 @@ object NavigationArguments {
object NavigationTargets {
const val ABOUT = "about"
const val ADVANCED_SETTINGS = "advanced_settings"
const val DELETE_WALLET = "delete_wallet"
const val EXPORT_PRIVATE_DATA = "export_private_data"
const val HOME = "home"
const val CHOOSE_SERVER = "choose_server"
const val REQUEST = "request"
const val SCAN = "scan"
const val SEED_RECOVERY = "seed_recovery"
const val SEND_CONFIRMATION = "send_confirmation"

View File

@ -1,5 +1,6 @@
package co.electriccoin.zcash.ui.common.compose
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@ -17,20 +18,16 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.model.toZecString
import cash.z.ecc.sdk.type.ZcashCurrency
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.common.model.spendableBalance
import co.electriccoin.zcash.ui.common.model.totalBalance
import co.electriccoin.zcash.ui.design.R
import co.electriccoin.zcash.ui.design.component.Body
import co.electriccoin.zcash.ui.design.component.CircularSmallProgressIndicator
import co.electriccoin.zcash.ui.design.component.GradientSurface
import co.electriccoin.zcash.ui.design.component.Reference
import co.electriccoin.zcash.ui.design.component.StyledBalance
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
@Preview(device = Devices.PIXEL_2)
@Composable
@ -42,14 +39,10 @@ private fun BalanceWidgetPreview() {
@Suppress("MagicNumber")
(
BalanceWidget(
walletSnapshot =
WalletSnapshotFixture.new(
saplingBalance =
WalletBalance(
Zatoshi(1234567891234567),
Zatoshi(123456789),
Zatoshi(123)
)
balanceState =
BalanceState.Available(
totalBalance = Zatoshi(1234567891234567L),
spendableBalance = Zatoshi(1234567891234567L)
),
isReferenceToBalances = true,
onReferenceClick = {},
@ -60,9 +53,35 @@ private fun BalanceWidgetPreview() {
}
}
@Preview(device = Devices.PIXEL_2)
@Composable
private fun BalanceWidgetNotAvailableYetPreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface(
modifier = Modifier.fillMaxWidth()
) {
@Suppress("MagicNumber")
BalanceWidget(
balanceState = BalanceState.Loading(Zatoshi(0L)),
isReferenceToBalances = true,
onReferenceClick = {},
modifier = Modifier
)
}
}
}
sealed class BalanceState(open val totalBalance: Zatoshi) {
data object None : BalanceState(Zatoshi(0L))
data class Loading(override val totalBalance: Zatoshi) : BalanceState(totalBalance)
data class Available(override val totalBalance: Zatoshi, val spendableBalance: Zatoshi) : BalanceState(totalBalance)
}
@Composable
fun BalanceWidget(
walletSnapshot: WalletSnapshot,
balanceState: BalanceState,
isReferenceToBalances: Boolean,
onReferenceClick: () -> Unit,
modifier: Modifier = Modifier
@ -74,10 +93,11 @@ fun BalanceWidget(
.then(modifier),
horizontalAlignment = Alignment.CenterHorizontally
) {
BalanceWidgetBigLineOnly(text = walletSnapshot.totalBalance().toZecString())
BalanceWidgetBigLineOnly(text = balanceState.totalBalance.toZecString())
Row(
verticalAlignment = Alignment.CenterVertically
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.animateContentSize()
) {
if (isReferenceToBalances) {
Reference(
@ -94,16 +114,23 @@ fun BalanceWidget(
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingTiny))
StyledBalance(
balanceString = walletSnapshot.spendableBalance().toZecString(),
textStyles =
Pair(
ZcashTheme.extendedTypography.balanceWidgetStyles.third,
ZcashTheme.extendedTypography.balanceWidgetStyles.fourth
when (balanceState) {
BalanceState.None, is BalanceState.Loading -> {
CircularSmallProgressIndicator(color = ZcashTheme.colors.circularProgressBarSmallDark)
}
is BalanceState.Available -> {
StyledBalance(
balanceString = balanceState.spendableBalance.toZecString(),
textStyles =
Pair(
ZcashTheme.extendedTypography.balanceWidgetStyles.third,
ZcashTheme.extendedTypography.balanceWidgetStyles.fourth
)
)
)
}
}
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingTiny))
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingMin))
Body(
text = ZcashCurrency.getLocalizedName(LocalContext.current),

View File

@ -15,7 +15,7 @@ fun ComponentActivity.BindCompLocalProvider(content: @Composable () -> Unit) {
val screenSecurity = ScreenSecurity()
observeScreenSecurityFlag(screenSecurity)
val screenBrightness = ScreenBrightness()
val screenBrightness = ScreenBrightness
observeScreenBrightnessFlag(screenBrightness)
val screenTimeout = ScreenTimeout()
@ -46,19 +46,21 @@ private fun ComponentActivity.observeScreenSecurityFlag(screenSecurity: ScreenSe
}
private fun ComponentActivity.observeScreenBrightnessFlag(screenBrightness: ScreenBrightness) {
screenBrightness.referenceCount.map { it > 0 }.collectWith(lifecycleScope) { maxBrightness ->
if (maxBrightness) {
window.attributes =
window.attributes.apply {
this.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL
}
} else {
window.attributes =
window.attributes.apply {
this.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE
}
screenBrightness.referenceSwitch
.map { it == ScreenBrightnessState.FULL }
.collectWith(lifecycleScope) { maxBrightness ->
if (maxBrightness) {
window.attributes =
window.attributes.apply {
this.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL
}
} else {
window.attributes =
window.attributes.apply {
this.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE
}
}
}
}
}
private fun ComponentActivity.observeScreenTimeoutFlag(screenTimeout: ScreenTimeout) {

View File

@ -6,28 +6,32 @@ import androidx.compose.runtime.compositionLocalOf
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.flow.updateAndGet
class ScreenBrightness {
private val mutableReferenceCount: MutableStateFlow<Int> = MutableStateFlow(0)
val referenceCount = mutableReferenceCount.asStateFlow()
fun fullBrightness() {
mutableReferenceCount.update { it + 1 }
}
fun restoreBrightness() {
val after = mutableReferenceCount.updateAndGet { it - 1 }
if (after < 0) {
error("Released brightness reference count too many times")
sealed class ScreenBrightnessState {
fun getChange(): ScreenBrightnessState {
return when (this) {
NORMAL -> FULL
FULL -> NORMAL
}
}
data object FULL : ScreenBrightnessState()
data object NORMAL : ScreenBrightnessState()
}
object ScreenBrightness {
private val mutableSwitch: MutableStateFlow<ScreenBrightnessState> = MutableStateFlow(ScreenBrightnessState.NORMAL)
val referenceSwitch = mutableSwitch.asStateFlow()
fun fullBrightness() = mutableSwitch.update { ScreenBrightnessState.FULL }
fun restoreBrightness() = mutableSwitch.update { ScreenBrightnessState.NORMAL }
}
@Suppress("CompositionLocalAllowlist")
val LocalScreenBrightness = compositionLocalOf { ScreenBrightness() }
val LocalScreenBrightness = compositionLocalOf { ScreenBrightness }
@Composable
fun BrightenScreen() {
@ -37,3 +41,9 @@ fun BrightenScreen() {
onDispose { screenBrightness.restoreBrightness() }
}
}
@Composable
fun RestoreScreenBrightness() {
val screenBrightness = LocalScreenBrightness.current
screenBrightness.restoreBrightness()
}

View File

@ -0,0 +1,93 @@
package co.electriccoin.zcash.ui.common.compose
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import cash.z.ecc.sdk.extension.toPercentageWithDecimal
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.design.component.BodySmall
import co.electriccoin.zcash.ui.design.component.GradientSurface
import co.electriccoin.zcash.ui.design.component.SmallLinearProgressIndicator
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.balances.model.WalletDisplayValues
@Preview(device = Devices.PIXEL_4_XL)
@Composable
private fun BalanceWidgetPreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface(
modifier = Modifier.fillMaxWidth()
) {
SynchronizationStatus(
isUpdateAvailable = false,
isDetailedStatus = false,
walletSnapshot = WalletSnapshotFixture.new()
)
}
}
}
@Composable
fun SynchronizationStatus(
isUpdateAvailable: Boolean,
isDetailedStatus: Boolean,
walletSnapshot: WalletSnapshot,
modifier: Modifier = Modifier,
testTag: String? = null,
) {
val walletDisplayValues =
WalletDisplayValues.getNextValues(
context = LocalContext.current,
walletSnapshot = walletSnapshot,
isUpdateAvailable = isUpdateAvailable,
isDetailedStatus = isDetailedStatus
)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
) {
if (walletDisplayValues.statusText.isNotEmpty()) {
BodySmall(
text = walletDisplayValues.statusText,
modifier = testTag?.let { Modifier.testTag(testTag) } ?: Modifier,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall))
}
BodySmall(
text =
stringResource(
id = R.string.balances_status_syncing_percentage,
walletSnapshot.progress.toPercentageWithDecimal()
),
textFontWeight = FontWeight.Black
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall))
SmallLinearProgressIndicator(
progress = walletSnapshot.progress.decimal,
modifier =
Modifier.padding(
horizontal = ZcashTheme.dimens.spacingUpLarge
)
)
}
}

View File

@ -0,0 +1,23 @@
package co.electriccoin.zcash.ui.common.model
/**
* Common wallet restoring state enum. This describes whether the current block synchronization run is in the
* restoring state or a subsequent synchronization state.
*
* WARN: Do NOT reorder or change the values; doing so would update their ordinal numbers, which could break the
* wallet UI.
*/
enum class WalletRestoringState {
NONE,
INITIATING, // New wallet syncing
RESTORING, // Existing wallet syncing
SYNCING; // Follow-up syncing
fun isRunningRestoring() = this == NONE || this == RESTORING
fun toNumber() = ordinal
companion object {
fun fromNumber(ordinal: Int) = entries[ordinal]
}
}

View File

@ -18,21 +18,28 @@ data class WalletSnapshot(
val progress: PercentDecimal,
val synchronizerError: SynchronizerError?
) {
// Note that both [hasSaplingFunds] and [hasTransparentFunds] checks are not entirely correct - they do not
// calculate the resulting fee using the new Proposal API. It's fine for now, but it's subject to improvement
// later once we figure out how to handle it in such cases.
// Note: the wallet's transparent balance is effectively empty if it cannot cover the miner's fee
val hasTransparentFunds = transparentBalance.value > 0L
// Note: the wallet is effectively empty if it cannot cover the miner's fee
val hasSaplingFunds = saplingBalance.available.value > 0L
val hasSaplingBalance = saplingBalance.total.value > 0L
// Note: the wallet's transparent balance is effectively empty if it cannot cover the miner's fee
val hasTransparentFunds = transparentBalance.value > 0L
// Note: the wallet is effectively empty if it cannot cover the miner's fee
val hasOrchardFunds = orchardBalance.available.value > 0L
val isSendEnabled: Boolean get() = status == Synchronizer.Status.SYNCED && hasSaplingFunds
val hasOrchardBalance = orchardBalance.total.value > 0L
val isSendEnabled: Boolean get() = hasSaplingFunds && hasOrchardFunds
}
// TODO [#1370]: WalletSnapshot.canSpend() calculation limitation
// TODO [#1370]: https://github.com/Electric-Coin-Company/zashi-android/issues/1370
// Note this check is not entirely correct - it does not calculate the resulting fee using the new Proposal API. It's
// fine for now, but it's subject to improvement later once we figure out how to handle it in such cases.
fun WalletSnapshot.canSpend(amount: Zatoshi): Boolean = spendableBalance() >= amount
fun WalletSnapshot.totalBalance() = orchardBalance.total + saplingBalance.total + transparentBalance
// Note that considering both to be spendable is subject to change.
@ -43,5 +50,9 @@ fun WalletSnapshot.spendableBalance() = orchardBalance.available + saplingBalanc
// Note that summing both values could be confusing, and we might prefer dividing them in the future
fun WalletSnapshot.changePendingBalance() = orchardBalance.changePending + saplingBalance.changePending
fun WalletSnapshot.hasChangePending() = changePendingBalance().value > 0L
// Note that summing both values could be confusing, and we might prefer dividing them in the future
fun WalletSnapshot.valuePendingBalance() = orchardBalance.valuePending + saplingBalance.valuePending
fun WalletSnapshot.hasValuePending() = valuePendingBalance().value > 0L

View File

@ -0,0 +1,415 @@
package co.electriccoin.zcash.ui.common.viewmodel
import android.annotation.SuppressLint
import android.app.Application
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators
import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import co.electriccoin.zcash.preference.model.entry.BooleanPreferenceDefault
import co.electriccoin.zcash.spackle.AndroidApiVersion
import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.MainActivity
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.ANDROID_STATE_FLOW_TIMEOUT
import co.electriccoin.zcash.ui.preference.StandardPreferenceKeys
import co.electriccoin.zcash.ui.preference.StandardPreferenceSingleton
import co.electriccoin.zcash.ui.screen.authentication.AuthenticationUseCase
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.WhileSubscribed
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import java.util.concurrent.Executor
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
private const val DEFAULT_INITIAL_DELAY = 0
class AuthenticationViewModel(
private val application: Application,
) : AndroidViewModel(application) {
private val executor: Executor by lazy { ContextCompat.getMainExecutor(application) }
private lateinit var biometricPrompt: BiometricPrompt
private lateinit var promptInfo: BiometricPrompt.PromptInfo
// This provides [allowedAuthenticators] on the current user device according to Android Compatibility Definition
// Document (CDD). See https://source.android.com/docs/compatibility/cdd
private val allowedAuthenticators: Int =
when {
// Android SDK version == 27
(AndroidApiVersion.isExactlyO) -> Authenticators.BIOMETRIC_STRONG or Authenticators.DEVICE_CREDENTIAL
// Android SDK version >= 30
(AndroidApiVersion.isAtLeastR) -> Authenticators.BIOMETRIC_STRONG or Authenticators.DEVICE_CREDENTIAL
// Android SDK version == 28 || 29
(AndroidApiVersion.isExactlyP || AndroidApiVersion.isExactlyQ) ->
Authenticators.BIOMETRIC_WEAK or Authenticators.DEVICE_CREDENTIAL
else -> error("Unsupported Android SDK version")
}
/**
* Welcome animation display state
*/
internal val showWelcomeAnimation: MutableStateFlow<Boolean> = MutableStateFlow(true)
internal fun setWelcomeAnimationDisplayed() {
showWelcomeAnimation.value = false
}
/**
* App access authentication logic values
*/
private val isAppAccessAuthenticationRequired: StateFlow<Boolean?> =
booleanStateFlow(StandardPreferenceKeys.IS_APP_ACCESS_AUTHENTICATION)
internal val appAccessAuthentication: MutableStateFlow<AuthenticationUIState> =
MutableStateFlow(AuthenticationUIState.Initial)
internal val appAccessAuthenticationResultState: StateFlow<AuthenticationUIState> =
combine(
isAppAccessAuthenticationRequired.filterNotNull(),
appAccessAuthentication,
) { required: Boolean, state: AuthenticationUIState ->
when {
!required -> AuthenticationUIState.NotRequired
state == AuthenticationUIState.Initial -> AuthenticationUIState.Required
else -> state
}
}.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
AuthenticationUIState.Initial
)
/**
* Other authentication use cases
*/
val isExportPrivateDataAuthenticationRequired: StateFlow<Boolean?> =
booleanStateFlow(StandardPreferenceKeys.IS_EXPORT_PRIVATE_DATA_AUTHENTICATION)
val isDeleteWalletAuthenticationRequired: StateFlow<Boolean?> =
booleanStateFlow(StandardPreferenceKeys.IS_DELETE_WALLET_AUTHENTICATION)
val isSeedAuthenticationRequired: StateFlow<Boolean?> =
booleanStateFlow(StandardPreferenceKeys.IS_SEED_AUTHENTICATION)
val isSendFundsAuthenticationRequired: StateFlow<Boolean?> =
booleanStateFlow(StandardPreferenceKeys.IS_SEND_FUNDS_AUTHENTICATION)
/**
* Authentication framework result
*/
internal val authenticationResult: MutableStateFlow<AuthenticationResult> =
MutableStateFlow(AuthenticationResult.None)
internal fun resetAuthenticationResult() {
authenticationResult.value = AuthenticationResult.None
}
fun authenticate(
activity: MainActivity,
initialAuthSystemWindowDelay: Duration = DEFAULT_INITIAL_DELAY.milliseconds,
useCase: AuthenticationUseCase
) {
val biometricsSupportResult = getBiometricAuthenticationSupport(allowedAuthenticators)
Twig.debug { "Authentication getBiometricAuthenticationSupport: $biometricsSupportResult" }
when (biometricsSupportResult) {
BiometricSupportResult.Success -> {
// No action needed, let user proceed to the authentication steps
}
else -> {
// Otherwise biometric authentication might not be available, but users still can use the
// device credential authentication path
}
}
biometricPrompt =
BiometricPrompt(
activity,
executor,
object : BiometricPrompt.AuthenticationCallback() {
/**
* Called when an unrecoverable error has been encountered and authentication has stopped.
*
* After this method is called, no further events will be sent for the current
* authentication session.
*
* @param errorCode An integer ID associated with the error.
* @param errorString A human-readable string that describes the error.
*/
override fun onAuthenticationError(
errorCode: Int,
errorString: CharSequence
) {
super.onAuthenticationError(errorCode, errorString)
Twig.warn { "Authentication error: $errorCode: $errorString" }
// Note that we process most of the following authentication errors the same. A potential
// improvement in the future could be let user take a different action for a different error.
// All available error codes are implemented
@SuppressLint("SwitchIntDef")
when (errorCode) {
// The hardware is unavailable. Try again later
BiometricPrompt.ERROR_HW_UNAVAILABLE,
// The sensor was unable to process the current image
BiometricPrompt.ERROR_UNABLE_TO_PROCESS,
// The current operation has been running too long and has timed out. This is intended to
// prevent programs from waiting for the biometric sensor indefinitely. The timeout is
// platform and sensor-specific, but is generally on the order of ~30 seconds.
BiometricPrompt.ERROR_TIMEOUT,
// The operation can't be completed because there is not enough device storage remaining
BiometricPrompt.ERROR_NO_SPACE,
// The operation was canceled because the API is locked out due to too many attempts. This
// occurs after 5 failed attempts, and lasts for 30 seconds.
BiometricPrompt.ERROR_LOCKOUT,
// The operation failed due to a vendor-specific error. This error code may be used by
// hardware vendors to extend this list to cover errors that don't fall under one of the
// other predefined categories. Vendors are responsible for providing the strings for these
// errors. These messages are typically reserved for internal operations such as enrollment
// but may be used to express any error that is not otherwise covered. In this case,
// applications are expected to show the error message, but they are advised not to rely on
// the message ID, since this may vary by vendor and device.
BiometricPrompt.ERROR_VENDOR,
// Biometric authentication is disabled until the user unlocks with their device credential
// (i.e. PIN, pattern, or password).
BiometricPrompt.ERROR_LOCKOUT_PERMANENT,
// The user does not have any biometrics enrolled
BiometricPrompt.ERROR_NO_BIOMETRICS,
// The device does not have the required authentication hardware
BiometricPrompt.ERROR_HW_NOT_PRESENT,
// The user pressed the negative button
BiometricPrompt.ERROR_NEGATIVE_BUTTON,
// A security vulnerability has been discovered with one or more hardware sensors. The
// affected sensor(s) are unavailable until a security update has addressed the issue
BiometricPrompt.ERROR_SECURITY_UPDATE_REQUIRED -> {
authenticationResult.value =
AuthenticationResult.Error(errorCode, errorString.toString())
}
// The user canceled the operation. Upon receiving this, applications should use alternate
// authentication, such as a password. The application should also provide the user a way of
// returning to biometric authentication, such as a button. The operation was canceled
// because [BiometricPrompt.ERROR_LOCKOUT] occurred too many times.
BiometricPrompt.ERROR_USER_CANCELED -> {
authenticationResult.value = AuthenticationResult.Canceled
// The following values are just for testing purposes, so we can easier reproduce other
// non-success results obtained from [BiometricPrompt]
// = AuthenticationResult.Failed
// = AuthenticationResult.Error(errorCode, errorString.toString())
}
// The operation was canceled because the biometric sensor is unavailable. This may happen
// when user is switched, the device is locked, or another pending operation prevents it.
BiometricPrompt.ERROR_CANCELED -> {
// We could consider splitting ERROR_CANCELED from ERROR_USER_CANCELED
authenticationResult.value = AuthenticationResult.Canceled
}
// The device does not have pin, pattern, or password set up
BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL -> {
// Allow unauthenticated access if no authentication method is available on the device
authenticationResult.value = AuthenticationResult.Success
}
}
}
/**
* Called when a biometric (e.g. fingerprint, face, etc.) is recognized, indicating that the
* user has successfully authenticated.
*
* <p>After this method is called, no further events will be sent for the current
* authentication session.
*
* @param result An object containing authentication-related data.
*/
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
Twig.info { "Authentication successful: $result" }
authenticationResult.value = AuthenticationResult.Success
}
/**
* Called when a biometric (e.g. fingerprint, face, etc.) is presented but not recognized as
* belonging to the user.
*/
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
Twig.error { "Authentication failed" }
authenticationResult.value = AuthenticationResult.Failed
}
}
)
promptInfo =
BiometricPrompt.PromptInfo.Builder()
.setTitle(
application.applicationContext.run {
getString(R.string.authentication_system_ui_title, getString(R.string.app_name))
}
)
.setSubtitle(
application.applicationContext.run {
getString(
R.string.authentication_system_ui_subtitle,
getString(
when (useCase) {
AuthenticationUseCase.AppAccess ->
R.string.app_name
AuthenticationUseCase.DeleteWallet ->
R.string.authentication_use_case_delete_wallet
AuthenticationUseCase.ExportPrivateData ->
R.string.authentication_use_case_export_data
AuthenticationUseCase.SeedRecovery ->
R.string.authentication_use_case_seed_recovery
AuthenticationUseCase.SendFunds ->
R.string.authentication_use_case_send_funds
}
)
)
}
)
.setConfirmationRequired(false)
.setAllowedAuthenticators(allowedAuthenticators)
.build()
// TODO [#7]: Consider integrating with the keystore to unlock cryptographic operations
// TODO [#7]: https://github.com/Electric-Coin-Company/zashi/issues/7
viewModelScope.launch {
delay(initialAuthSystemWindowDelay)
biometricPrompt.authenticate(promptInfo)
}
}
private fun getBiometricAuthenticationSupport(allowedAuthenticators: Int): BiometricSupportResult {
val biometricManager = BiometricManager.from(application)
return when (biometricManager.canAuthenticate(allowedAuthenticators)) {
BiometricManager.BIOMETRIC_SUCCESS -> {
Twig.debug { "Auth canAuthenticate BIOMETRIC_SUCCESS: App can authenticate using biometrics." }
BiometricSupportResult.Success
}
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> {
Twig.info {
"Auth canAuthenticate BIOMETRIC_ERROR_NO_HARDWARE: No biometric features available on " +
"this device."
}
BiometricSupportResult.ErrorNoHardware
}
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE -> {
Twig.error {
"Auth canAuthenticate BIOMETRIC_ERROR_HW_UNAVAILABLE: Biometric features are currently " +
"unavailable."
}
BiometricSupportResult.ErrorHwUnavailable
}
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
Twig.warn {
"Auth canAuthenticate BIOMETRIC_ERROR_NONE_ENROLLED: Prompts the user to create " +
"credentials that your app accepts."
}
BiometricSupportResult.ErrorNoneEnrolled
}
BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED -> {
Twig.error {
"Auth canAuthenticate BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED: The user can't authenticate " +
"because a security vulnerability has been discovered with one or more hardware sensors. The " +
"affected sensor(s) are unavailable until a security update has addressed the issue."
}
BiometricSupportResult.ErrorSecurityUpdateRequired
}
BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED -> {
Twig.error {
"Auth canAuthenticate BIOMETRIC_ERROR_UNSUPPORTED: The user can't authenticate because " +
"the specified options are incompatible with the current Android version."
}
BiometricSupportResult.ErrorUnsupported
}
BiometricManager.BIOMETRIC_STATUS_UNKNOWN -> {
Twig.error {
"Auth canAuthenticate BIOMETRIC_STATUS_UNKNOWN: Unable to determine whether the user can" +
" authenticate. This status code may be returned on older Android versions due to partial " +
"incompatibility with a newer API. Applications that wish to enable biometric authentication " +
"on affected devices may still call BiometricPrompt#authenticate() after receiving this " +
"status code but should be prepared to handle possible errors."
}
BiometricSupportResult.StatusUnknown
}
else -> {
Twig.error { "Unexpected biometric framework status" }
BiometricSupportResult.StatusExpected
}
}
}
@Suppress("UNCHECKED_CAST")
class AuthenticationViewModelFactory(
private val application: Application
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
require(modelClass.isAssignableFrom(AuthenticationViewModel::class.java)) { "ViewModel Not Found." }
return AuthenticationViewModel(application) as T
}
}
private fun booleanStateFlow(default: BooleanPreferenceDefault): StateFlow<Boolean?> =
flow<Boolean?> {
val preferenceProvider = StandardPreferenceSingleton.getInstance(getApplication())
emitAll(default.observe(preferenceProvider))
}.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
null
)
}
sealed class AuthenticationUIState {
data object Initial : AuthenticationUIState()
data object Required : AuthenticationUIState()
data object NotRequired : AuthenticationUIState()
data object SupportedRequired : AuthenticationUIState()
data object Successful : AuthenticationUIState()
}
sealed class AuthenticationResult {
data object None : AuthenticationResult()
data object Success : AuthenticationResult()
data class Error(val errorCode: Int, val errorMessage: String) : AuthenticationResult()
data object Canceled : AuthenticationResult()
data object Failed : AuthenticationResult()
}
private sealed class BiometricSupportResult {
data object Success : BiometricSupportResult()
data object ErrorNoHardware : BiometricSupportResult()
data object ErrorHwUnavailable : BiometricSupportResult()
data object ErrorNoneEnrolled : BiometricSupportResult()
data object ErrorSecurityUpdateRequired : BiometricSupportResult()
data object ErrorUnsupported : BiometricSupportResult()
data object StatusUnknown : BiometricSupportResult()
data object StatusExpected : BiometricSupportResult()
}

Some files were not shown because too many files have changed in this diff Show More