Compare commits

...

67 Commits

Author SHA1 Message Date
Honza Rychnovský cc07535f44
Release Zashi Android version 1.1.1 (660)
Closes #1465
2024-06-05 15:01:22 +02:00
Honza Rychnovský 6f878ea609
[#1463] Display Disconnected app state
- Closes #1463
- Disconnected dialog text update
- Changelog updated
2024-06-05 12:52:43 +02:00
Honza Rychnovský d813c1a9da
[#1458] Detect unavailable service and show a dialog
* [#1458] Detect unavailable service and show a dialog

- Closes #1458
- Changelog update

* Provide unsorted trx list when disconnected

- These changes also improve the app’s ability to use the SDK’s APIs to provide a transaction history list, even in a disconnected state. In such a case, the list is sorted by its original order.
- Changelog update
2024-06-03 18:41:06 +02:00
Honza Rychnovský 75e90607d1
[#1456] runCreateTransactions on lifecycleScope
- Closes #1456
- Also, these changes leverage updated snapshot Zcash SDK version  2.1.2
- Changelog update
2024-06-03 08:12:07 +02:00
Honza Rychnovský 030d2e20b0
[#1085] Grid pattern in the screen background
- Closes #1085
- Closes #1091
- These are prerequisites for the Dark mode adoption within #1011
- A few unused UI components have been removed to simplify the dark mode adoption
- BlankSurface and GridSurface have been added and used instead of the previous GradientSurface
- A new BlankBgScaffold, GridBgScaffold, BlankBgColumn, and GridBgColumn UI components have been prepared to provide an easy grid or blank screen background adoption across the whole app
- Several colors from resources have been eliminated, as the design doc simplified its color palette
- The grid pattern has been added to the screens according to the design doc and iOS platform
- Changelog updated
2024-05-30 13:32:35 +02:00
Honza Rychnovský fbf4a73208
[#1451] Release Zashi version 1.1 (655)
Closes #1451
2024-05-24 15:05:15 +02:00
Honza Rychnovský 7e9e89725b
[#1449] Display Synchronizer details in dialog
- Closes #1449
- Synchronizer status details are now available to users by pressing the simple status view. The details are displayed within the predefined Zashi dialog on the Balances and Account screens
- As this view also presents information about Zashi app updates available on Google Play, by pressing the view, the app redirects users to Google Play Zashi’s page
- As agreed, we’re moving towards more rounded corners in dialogs, which is part of these changes, too
- Added also several minor Balances screen UI improvements
- Improved biometric flow without any authentication method set on older Android versions
- Changelog update
2024-05-24 10:41:57 +02:00
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
187 changed files with 6103 additions and 3178 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@bdf99f9dada2506e990bac6de8ec5e3de34a04f1
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@bdf99f9dada2506e990bac6de8ec5e3de34a04f1
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@bdf99f9dada2506e990bac6de8ec5e3de34a04f1
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@bdf99f9dada2506e990bac6de8ec5e3de34a04f1
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@bdf99f9dada2506e990bac6de8ec5e3de34a04f1
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@bdf99f9dada2506e990bac6de8ec5e3de34a04f1
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@bdf99f9dada2506e990bac6de8ec5e3de34a04f1
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@bdf99f9dada2506e990bac6de8ec5e3de34a04f1
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@bdf99f9dada2506e990bac6de8ec5e3de34a04f1
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@bdf99f9dada2506e990bac6de8ec5e3de34a04f1
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@bdf99f9dada2506e990bac6de8ec5e3de34a04f1
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@bdf99f9dada2506e990bac6de8ec5e3de34a04f1
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

2
.gitignore vendored
View File

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

View File

@ -9,7 +9,88 @@ directly impact users rather than highlighting other key architectural updates.*
## [Unreleased]
## [0.2.0 (593)] - 2024-04-09
## [1.1.1 (660)] - 2024-06-05
### Added
- Grid pattern background has been added to several screens
- A new disconnected dialog reminder has been added to inform users about possible server issues
- When the app is experiencing such server connection issues, a new DISCONNECTED label will be displayed below the
screen title
- The transaction history list will be displayed when the app has server connection issues. Such a list might have a
slightly different order.
### Changed
- The color palette used across the app has been reworked to align with the updated design document
### Fixed
- An updated snapshot Zcash SDK version has been adopted to improve unstable lightwalletd communication
- Transaction submission has been slightly refactored to improve its stability
## [1.1 (655)] - 2024-05-24
### 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.
- Synchronizer status details are now available to users by pressing the simple status view placed above the
synchronization progress bar. The details are displayed within a dialog window on the Balances and Account screens.
This view also occasionally presents information about a possible Zashi app update available on Google Play. The
app redirects users to the Google Play Zashi page by pressing the view.
### Changed
- The app dialog window has now a bit more rounded corners
- A few more minor UI improvements
## [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
@ -21,8 +102,8 @@ 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 has been added to all post-onboarding screens to notify users about the current
state of the wallet-restoring process.
- 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 and completely reworked according to the
@ -34,6 +115,7 @@ directly impact users rather than highlighting other key architectural updates.*
- 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.1.1
# 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.1.0-SNAPSHOT
ZCASH_BIP39_VERSION=1.0.8
# WARNING: Ensure a non-snapshot version is used before releasing to production
ZCASH_SDK_VERSION=2.1.2-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

@ -15,7 +15,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ButtonDefaults.buttonColors
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
@ -48,14 +47,12 @@ import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@Composable
private fun ButtonComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
Column(Modifier.padding(ZcashTheme.dimens.spacingDefault)) {
PrimaryButton(onClick = { }, text = "Primary")
PrimaryButton(onClick = { }, text = "Primary...", showProgressBar = true)
PrimaryButton(onClick = { }, text = "Primary Small", minHeight = ZcashTheme.dimens.buttonHeightSmall)
SecondaryButton(onClick = { }, text = "Secondary")
TertiaryButton(onClick = { }, text = "Tertiary")
TertiaryButton(onClick = { }, text = "Tertiary", enabled = false)
NavigationButton(onClick = { }, text = "Navigation")
@Suppress("MagicNumber")
Row {
@ -86,7 +83,7 @@ fun PrimaryButton(
horizontal = ZcashTheme.dimens.spacingNone,
vertical = ZcashTheme.dimens.spacingSmall
),
contentPaddingValues: PaddingValues = PaddingValues(all = 15.5.dp)
contentPaddingValues: PaddingValues = PaddingValues(all = 16.5.dp)
) {
Button(
shape = RectangleShape,
@ -183,7 +180,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,
@ -195,7 +192,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,
@ -256,41 +254,6 @@ fun NavigationButton(
}
}
@Composable
fun TertiaryButton(
onClick: () -> Unit,
text: String,
modifier: Modifier = Modifier,
outerPaddingValues: PaddingValues =
PaddingValues(
horizontal = ZcashTheme.dimens.spacingNone,
vertical = ZcashTheme.dimens.spacingSmall
),
enabled: Boolean = true
) {
Button(
shape = RectangleShape,
onClick = onClick,
modifier =
modifier.then(
Modifier
.fillMaxWidth()
.padding(outerPaddingValues)
.defaultMinSize(ZcashTheme.dimens.buttonWidth, ZcashTheme.dimens.buttonHeight)
),
enabled = enabled,
elevation = ButtonDefaults.buttonElevation(0.dp, 0.dp, 0.dp),
colors = buttonColors(containerColor = ZcashTheme.colors.tertiary)
) {
Text(
style = MaterialTheme.typography.labelLarge,
textAlign = TextAlign.Center,
text = text,
color = ZcashTheme.colors.onTertiary
)
}
}
@Suppress("LongParameterList")
fun Modifier.shadow(
contentColor: Color = Color.Black,
@ -344,6 +307,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

@ -0,0 +1,64 @@
package co.electriccoin.zcash.ui.design.component
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@Preview("Column with blank background")
@Composable
private fun BlankBgColumnComposablePreview() {
ZcashTheme(forceDarkMode = false) {
BlankBgColumn {
Text(text = "Blank background column")
}
}
}
@Preview("Column with grip pattern background")
@Composable
private fun GridBgScaffoldComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GridBgColumn {
Text(text = "Grid pattern background column")
}
}
}
@Composable
fun BlankBgColumn(
modifier: Modifier = Modifier,
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
content: @Composable ColumnScope.() -> Unit
) {
Column(
modifier = modifier.then(Modifier.background(ZcashTheme.colors.backgroundColor)),
horizontalAlignment = horizontalAlignment,
verticalArrangement = verticalArrangement,
content = content,
)
}
@Composable
fun GridBgColumn(
modifier: Modifier = Modifier,
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
content: @Composable ColumnScope.() -> Unit
) {
GridSurface {
Column(
horizontalAlignment = horizontalAlignment,
verticalArrangement = verticalArrangement,
content = content,
modifier = modifier,
)
}
}

View File

@ -18,7 +18,7 @@ import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@Composable
private fun TopScreenLogoRegularComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
TopScreenLogoTitle(
title = "Test screen title",
logoContentDescription = "Test logo content description"
@ -31,7 +31,7 @@ private fun TopScreenLogoRegularComposablePreview() {
@Composable
private fun TopScreenLogoLongComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
TopScreenLogoTitle(
title = "Test screen title which is very very long and can overflow the allowed title length",
logoContentDescription = "Test logo content description"

View File

@ -1,12 +1,13 @@
package co.electriccoin.zcash.ui.design.component
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@ -61,7 +62,7 @@ fun AppAlertDialog(
properties: DialogProperties = DialogProperties()
) {
AlertDialog(
shape = RectangleShape,
shape = RoundedCornerShape(corner = CornerSize(ZcashTheme.dimens.regularRippleEffectCorner)),
onDismissRequest = onDismissRequest?.let { onDismissRequest } ?: {},
confirmButton = {
confirmButtonText?.let {

View File

@ -1,24 +0,0 @@
package co.electriccoin.zcash.ui.design.component
import androidx.compose.foundation.background
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@Composable
fun GradientSurface(
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
Surface(
color = Color.Transparent,
modifier =
modifier
.background(ZcashTheme.colors.surfaceGradient()),
shape = RectangleShape,
content = content
)
}

View File

@ -21,7 +21,7 @@ import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@Composable
private fun CircularScreenProgressIndicatorComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
Column {
CircularScreenProgressIndicator()
CircularMidProgressIndicator()
@ -79,20 +79,20 @@ fun CircularSmallProgressIndicator(
@Composable
private fun LinearProgressIndicatorComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
@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

@ -0,0 +1,68 @@
package co.electriccoin.zcash.ui.design.component
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@Preview("Scaffold with blank background")
@Composable
private fun BlankBgScaffoldComposablePreview() {
ZcashTheme(forceDarkMode = false) {
BlankBgScaffold {
Text(text = "Blank background scaffold")
}
}
}
@Preview("Scaffold with grip pattern background")
@Composable
private fun GridBgScaffoldComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GridBgScaffold {
Text(text = "Grid pattern background scaffold")
}
}
}
@Composable
fun BlankBgScaffold(
modifier: Modifier = Modifier,
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
snackbarHost: @Composable () -> Unit = {},
content: @Composable (PaddingValues) -> Unit
) {
Scaffold(
containerColor = ZcashTheme.colors.backgroundColor,
topBar = topBar,
snackbarHost = snackbarHost,
bottomBar = bottomBar,
content = content,
modifier = modifier,
)
}
@Composable
fun GridBgScaffold(
modifier: Modifier = Modifier,
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
snackbarHost: @Composable () -> Unit = {},
content: @Composable (PaddingValues) -> Unit
) {
GridSurface {
Scaffold(
containerColor = Color.Transparent,
topBar = topBar,
snackbarHost = snackbarHost,
bottomBar = bottomBar,
content = content,
modifier = modifier,
)
}
}

View File

@ -0,0 +1,116 @@
package co.electriccoin.zcash.ui.design.component
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@Preview("Blank background")
@Composable
private fun BlankSurfacePreview() {
ZcashTheme(forceDarkMode = false) {
BlankSurface {
Text(
text = "Test text on the blank app background",
modifier = Modifier.fillMaxSize()
)
}
}
}
@Preview("Grid background")
@Composable
private fun GridSurfacePreview() {
ZcashTheme(forceDarkMode = false) {
GridSurface {
Text(
text = "Test text on the grip app background",
modifier = Modifier.fillMaxSize()
)
}
}
}
@Composable
fun BlankSurface(
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
Surface(
color = ZcashTheme.colors.backgroundColor,
shape = RectangleShape,
content = content,
modifier = modifier
)
}
@Composable
fun GridSurface(
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
Surface(
color = Color.Transparent,
shape = RectangleShape,
content = content,
modifier =
modifier.then(
Modifier
.gridBackground(
backgroundColor = ZcashTheme.colors.backgroundColor,
gridSize = ZcashTheme.dimens.gridCellSize,
gridColor = ZcashTheme.colors.gridColor,
gridLineWidth = ZcashTheme.dimens.gridLineWidth
)
)
)
}
fun Modifier.gridBackground(
backgroundColor: Color,
gridSize: Dp,
gridColor: Color,
gridLineWidth: Dp
): Modifier {
return then(
background(backgroundColor)
.drawBehind {
val gridWidth = size.width
val gridHeight = size.height
val stepX = gridSize.toPx()
val stepY = gridSize.toPx()
val xSteps = (gridWidth / stepX).toInt()
val ySteps = (gridHeight / stepY).toInt()
for (i in 0..xSteps) {
val x = i * stepX
drawLine(
start = Offset(x, 0f),
end = Offset(x, gridHeight),
color = gridColor,
strokeWidth = gridLineWidth.toPx()
)
}
for (i in 0..ySteps) {
val y = i * stepY
drawLine(
start = Offset(0f, y),
end = Offset(gridWidth, y),
color = gridColor,
strokeWidth = gridLineWidth.toPx()
)
}
}
)
}

View File

@ -42,7 +42,7 @@ import java.util.Locale
@Composable
private fun ReferenceComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
Column {
Reference(
text = "Test reference text",
@ -70,7 +70,7 @@ private fun ReferenceComposablePreview() {
@Composable
private fun StyledBalanceComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
Column {
StyledBalance(
balanceString = "1,234.56789012",
@ -192,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,
@ -200,6 +201,7 @@ fun Small(
Text(
text = text,
color = color,
fontWeight = textFontWeight,
maxLines = maxLines,
overflow = overflow,
textAlign = textAlign,
@ -276,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
) {
@ -301,7 +304,7 @@ fun Reference(
style =
textStyle.merge(
TextStyle(
color = ZcashTheme.colors.reference,
color = color,
textAlign = textAlign,
textDecoration = TextDecoration.Underline,
fontWeight = fontWeight
@ -373,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(
@ -408,7 +411,7 @@ fun BodyWithFiatCurrencySymbol(
@Composable
private fun NavigationTabTextPreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
Column {
NavigationTabText(
text = "Account",
@ -440,7 +443,7 @@ fun NavigationTabText(
},
maxLines = 1,
overflow = TextOverflow.Visible,
color = ZcashTheme.colors.tabTextColor,
color = ZcashTheme.colors.textCommon,
modifier =
Modifier
.clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner))

View File

@ -50,8 +50,8 @@ fun FormTextField(
keyboardOptions: KeyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
colors: TextFieldColors =
TextFieldDefaults.colors(
focusedContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent,
focusedContainerColor = ZcashTheme.colors.backgroundColor,
unfocusedContainerColor = ZcashTheme.colors.backgroundColor,
disabledContainerColor = ZcashTheme.colors.textDisabled,
errorContainerColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent,
@ -120,7 +120,7 @@ fun FormTextField(
BodySmall(
text = error,
color = ZcashTheme.colors.textFieldError,
color = ZcashTheme.colors.textFieldWarning,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)

View File

@ -2,7 +2,6 @@
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
@ -16,8 +15,8 @@ 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,6 +33,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
@ -44,12 +44,13 @@ 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
private fun TopAppBarTextComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
SmallTopAppBar(titleText = "Screen A", backText = "Back")
}
}
@ -59,11 +60,11 @@ private fun TopAppBarTextComposablePreview() {
@Composable
private fun TopAppBarTextRestoringComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
SmallTopAppBar(
titleText = "Screen A",
backText = "Back",
restoringLabel = "[RESTORING YOUR WALLET…]"
subTitle = "[RESTORING YOUR WALLET…]"
)
}
}
@ -73,11 +74,11 @@ private fun TopAppBarTextRestoringComposablePreview() {
@Composable
private fun TopAppBarTextRestoringLongComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
SmallTopAppBar(
titleText = "Screen A",
backText = "Back",
restoringLabel = "[RESTORING YOUR WALLET LONG TEXT…]"
subTitle = "[RESTORING YOUR WALLET LONG TEXT…]"
)
}
}
@ -87,7 +88,7 @@ private fun TopAppBarTextRestoringLongComposablePreview() {
@Composable
private fun TopAppBarLogoComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
SmallTopAppBar(showTitleLogo = true, backText = "Back")
}
}
@ -97,11 +98,11 @@ private fun TopAppBarLogoComposablePreview() {
@Composable
private fun TopAppBarLogoRestoringComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
SmallTopAppBar(
showTitleLogo = true,
backText = "Back",
restoringLabel = "[RESTORING YOUR WALLET…]"
subTitle = "[RESTORING YOUR WALLET…]"
)
}
}
@ -111,7 +112,7 @@ private fun TopAppBarLogoRestoringComposablePreview() {
@Composable
private fun TopAppBarRegularMenuComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
SmallTopAppBar(
titleText = "Screen B",
regularActions = {
@ -129,7 +130,7 @@ private fun TopAppBarRegularMenuComposablePreview() {
@Composable
private fun TopAppBarOneVisibleActionMenuComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
SmallTopAppBar(
titleText = "Screen C",
backText = "Back",
@ -147,7 +148,7 @@ private fun TopAppBarOneVisibleActionMenuComposablePreview() {
@Composable
private fun TopAppBarHamburgerMenuComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
SmallTopAppBar(
titleText = "Screen D",
backText = "Back",
@ -165,7 +166,7 @@ private fun TopAppBarHamburgerMenuComposablePreview() {
@Composable
private fun TopAppBarHamburgerPlusActionComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
BlankSurface {
SmallTopAppBar(
titleText = "Screen E",
hamburgerMenuActions = {
@ -260,19 +261,56 @@ private fun TopBarOneVisibleActionMenuExample(
)
}
@Composable
@Suppress("LongParameterList")
fun GridBgSmallTopAppBar(
modifier: Modifier = Modifier,
backContentDescriptionText: String? = null,
backText: String? = null,
colors: TopAppBarColors = ZcashTheme.colors.topAppBarColors,
hamburgerMenuActions: (@Composable RowScope.() -> Unit)? = null,
onBack: (() -> Unit)? = null,
regularActions: (@Composable RowScope.() -> Unit)? = null,
subTitle: String? = null,
showTitleLogo: Boolean = false,
titleText: String? = null,
) {
SmallTopAppBar(
modifier =
modifier.then(
Modifier.gridBackground(
backgroundColor = ZcashTheme.colors.backgroundColor,
gridSize = ZcashTheme.dimens.gridCellSize,
gridColor = ZcashTheme.colors.gridColor,
gridLineWidth = ZcashTheme.dimens.gridLineWidth
)
),
backContentDescriptionText = backContentDescriptionText,
backText = backText,
colors = colors.copyColors(containerColor = Color.Transparent),
hamburgerMenuActions = hamburgerMenuActions,
onBack = onBack,
regularActions = regularActions,
subTitle = subTitle,
showTitleLogo = showTitleLogo,
titleText = titleText
)
}
@Composable
@Suppress("LongParameterList", "LongMethod")
@OptIn(ExperimentalMaterial3Api::class)
fun SmallTopAppBar(
modifier: Modifier = Modifier,
restoringLabel: String? = null,
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,
subTitle: String? = null,
showTitleLogo: Boolean = false,
titleText: String? = null,
) {
CenterAlignedTopAppBar(
title = {
@ -284,26 +322,28 @@ fun SmallTopAppBar(
if (titleText != null) {
Text(
text = titleText.uppercase(),
style = SecondaryTypography.headlineSmall
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) {
if (subTitle != null) {
Spacer(modifier = Modifier.height(restoringSpacerHeight))
@Suppress("MagicNumber")
Text(
text = restoringLabel.uppercase(),
text = subTitle.uppercase(),
style = ZcashTheme.extendedTypography.restoringTopAppBarStyle,
color = ZcashTheme.colors.restoringTopAppBarColor,
color = colors.subTitleColor,
modifier = Modifier.fillMaxWidth(0.75f),
textAlign = TextAlign.Center,
maxLines = 1,
@ -325,9 +365,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())
@ -339,6 +380,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

@ -11,6 +11,7 @@ import androidx.compose.ui.unit.dp
data class Dimens(
// Default spacings:
val spacingNone: Dp,
val spacingMini: Dp,
val spacingXtiny: Dp,
val spacingMin: Dp,
val spacingTiny: Dp,
@ -29,6 +30,9 @@ data class Dimens(
val buttonWidth: Dp,
val buttonHeight: Dp,
val buttonHeightSmall: Dp,
// Screen background grid
val gridCellSize: Dp,
val gridLineWidth: Dp,
// Chip
val chipShadowElevation: Dp,
val chipStroke: Dp,
@ -55,11 +59,13 @@ data class Dimens(
val inScreenZcashTextLogoHeight: Dp,
val screenHorizontalSpacingBig: Dp,
val screenHorizontalSpacingRegular: Dp,
val cameraTorchButton: Dp,
)
private val defaultDimens =
Dimens(
spacingNone = 0.dp,
spacingMini = 1.dp,
spacingXtiny = 2.dp,
spacingTiny = 4.dp,
spacingMin = 6.dp,
@ -76,6 +82,8 @@ private val defaultDimens =
buttonWidth = 244.dp,
buttonHeight = 56.dp,
buttonHeightSmall = 38.dp,
gridCellSize = 14.dp,
gridLineWidth = 1.dp,
chipShadowElevation = 4.dp,
chipStroke = 0.5.dp,
circularScreenProgressWidth = 48.dp,
@ -96,6 +104,7 @@ private val defaultDimens =
inScreenZcashTextLogoHeight = 30.dp,
screenHorizontalSpacingBig = 64.dp,
screenHorizontalSpacingRegular = 32.dp,
cameraTorchButton = 20.dp,
)
private val normalDimens = defaultDimens

View File

@ -1,61 +1,43 @@
package co.electriccoin.zcash.ui.design.theme
import androidx.compose.material3.MaterialTheme
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(
val surfaceEnd: Color,
val backgroundColor: Color,
val gridColor: Color,
val onBackgroundHeader: Color,
val tertiary: Color,
val onTertiary: Color,
val callout: Color,
val onCallout: Color,
val circularProgressBarSmall: Color,
val circularProgressBarSmallDark: Color,
val circularProgressBarScreen: Color,
val linearProgressBarTrack: Color,
val linearProgressBarBackground: Color,
val restoringTopAppBarColor: Color,
val chipIndex: Color,
val textCommon: Color,
val textMedium: Color,
val textDescription: Color,
val textDisabled: Color,
val textFieldHint: Color,
val textFieldError: Color,
val textFieldWarning: Color,
val textFieldFrame: Color,
val textDescription: Color,
val textPending: Color,
val textDescriptionDark: Color,
val layoutStroke: Color,
val overlay: Color,
val highlight: Color,
val reference: Color,
val disabledButtonColor: Color,
val disabledButtonTextColor: Color,
val buttonShadowColor: Color,
val screenTitleColor: Color,
val aboutTextColor: Color,
val welcomeAnimationColor: Color,
val complementaryColor: Color,
val dividerColor: Color,
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 historyRedColor: Color,
) {
@Composable
fun surfaceGradient() =
Brush.verticalGradient(
colors =
listOf(
MaterialTheme.colorScheme.surface,
ZcashTheme.colors.surfaceEnd
)
)
}
val historySyncingColor: Color,
val topAppBarColors: TopAppBarColors,
val transparentTopAppBarColors: TopAppBarColors
)

View File

@ -11,41 +11,33 @@ import co.electriccoin.zcash.ui.design.theme.ExtendedColors
// TODO [#998]: Check and enhance screen dark mode
// TODO [#998]: https://github.com/Electric-Coin-Company/zashi-android/issues/998
// TODO [#1091]: Clear unused color resources
// TODO [#1091]: https://github.com/Electric-Coin-Company/zashi-android/issues/1091
internal object Dark {
val backgroundStart = Color(0xFF000000)
val backgroundEnd = Color(0xFF000000)
val backgroundColor = Color(0xFF231F20)
val gridColor = Color(0xFF272727)
val textHeaderOnBackground = Color(0xFFFFFFFF)
val textBodyOnBackground = Color(0xFFFFFFFF)
val textPrimaryButton = Color(0xFF000000)
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 textProgress = Color(0xFF8B8A8A)
val textDescriptionDark = Color(0xFF4D4D4D)
val aboutTextColor = Color(0xFF4E4E4E)
val screenTitleColor = Color(0xFF040404)
val welcomeAnimationColor = Color(0xFF231F20)
val complementaryColor = Color(0xFFF4B728)
val dividerColor = Color(0xFFDDDDDD)
val darkDividerColor = Color(0xFF000000)
val tabTextColor = Color(0xFF040404)
val layoutStroke = Color(0xFFFFFFFF)
val panelBackgroundColor = Color(0xFFEAEAEA)
val panelBackgroundColor = Color(0xFFF6F6F6)
val cameraDisabledBackgroundColor = Color(0xFF5E5C5C)
val cameraDisabledFrameColor = Color(0xFFFFFFFF)
val primaryButton = Color(0xFFFFFFFF)
val secondaryButton = Color(0xFFFFFFFF)
val tertiaryButton = Color.Transparent
val radioButtonColor = Color(0xFF070707)
val radioButtonTextColor = Color(0xFF4E4E4E)
@ -55,57 +47,49 @@ internal object Dark {
val circularProgressBarScreen = Color(0xFFFFFFFF)
val linearProgressBarTrack = Color(0xFFD9D9D9)
val linearProgressBarBackground = complementaryColor
val restoringTopAppBarColor = Color(0xFF8A8888)
val callout = Color(0xFFFFFFFF)
val onCallout = Color(0xFFFFFFFF)
val overlay = Color(0x22000000)
val highlight = Color(0xFFFFD800)
val reference = Color(0xFFFFFFFF)
val disabledButtonColor = Color(0xFFB7B7B7)
val disabledButtonTextColor = Color(0xFFDDDDDD)
val buttonShadowColor = Color(0xFFFFFFFF)
val historyBackgroundColor = Color(0xFFF6F6F6)
val historyRedColor = Color(0xFFF40202)
val historyRedColor = textFieldWarning
val historySyncingColor = panelBackgroundColor
val topAppBarColors = DarkTopAppBarColors()
val transparentTopAppBarColors = TransparentTopAppBarColors()
}
internal object Light {
val backgroundStart = Color(0xFFFFFFFF)
val backgroundEnd = Color(0xFFFFFFFF)
val backgroundColor = Color(0xFFFFFFFF)
val gridColor = Color(0xFFFBFBFB)
val textHeaderOnBackground = Color(0xFF000000)
val textBodyOnBackground = Color(0xFF000000)
val textPrimaryButton = Color(0xFFFFFFFF)
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 textProgress = Color(0xFF8B8A8A)
val textDescriptionDark = Color(0xFF4D4D4D)
val screenTitleColor = Color(0xFF040404)
val aboutTextColor = Color(0xFF4E4E4E)
val welcomeAnimationColor = Color(0xFF231F20)
val complementaryColor = Color(0xFFF4B728)
val dividerColor = Color(0xFFDDDDDD)
val darkDividerColor = Color(0xFF000000)
val tabTextColor = Color(0xFF040404)
val layoutStroke = Color(0xFF000000)
val panelBackgroundColor = Color(0xFFEAEAEA)
val panelBackgroundColor = Color(0xFFEBEBEB)
val cameraDisabledBackgroundColor = Color(0xFF5E5C5C)
val cameraDisabledFrameColor = Color(0xFFFFFFFF)
val primaryButton = Color(0xFF000000)
val secondaryButton = Color(0xFFFFFFFF)
val tertiaryButton = Color.Transparent
val radioButtonColor = Color(0xFF070707)
val radioButtonTextColor = Color(0xFF4E4E4E)
@ -115,22 +99,20 @@ internal object Light {
val circularProgressBarSmallDark = textBodyOnBackground
val linearProgressBarTrack = Color(0xFFD9D9D9)
val linearProgressBarBackground = complementaryColor
val restoringTopAppBarColor = Color(0xFF8A8888)
val callout = Color(0xFFFFFFFF)
val onCallout = Color(0xFFFFFFFF)
val overlay = Color(0x22000000)
val highlight = Color(0xFFFFD800)
val reference = Color(0xFF000000)
val disabledButtonColor = Color(0xFFB7B7B7)
val disabledButtonTextColor = Color(0xFFDDDDDD)
val buttonShadowColor = Color(0xFF000000)
val historyBackgroundColor = Color(0xFFF6F6F6)
val historyRedColor = Color(0xFFF40202)
val historyRedColor = textFieldWarning
val historySyncingColor = panelBackgroundColor
val topAppBarColors = LightTopAppBarColors()
val transparentTopAppBarColors = TransparentTopAppBarColors()
}
internal val DarkColorPalette =
@ -139,9 +121,9 @@ internal val DarkColorPalette =
secondary = Dark.secondaryButton,
onPrimary = Dark.textPrimaryButton,
onSecondary = Dark.textSecondaryButton,
surface = Dark.backgroundStart,
surface = Dark.backgroundColor,
onSurface = Dark.textBodyOnBackground,
background = Dark.backgroundStart,
background = Dark.backgroundColor,
onBackground = Dark.textBodyOnBackground,
)
@ -151,143 +133,125 @@ internal val LightColorPalette =
secondary = Light.secondaryButton,
onPrimary = Light.textPrimaryButton,
onSecondary = Light.textSecondaryButton,
surface = Light.backgroundStart,
surface = Light.backgroundColor,
onSurface = Light.textBodyOnBackground,
background = Light.backgroundStart,
background = Light.backgroundColor,
onBackground = Light.textBodyOnBackground,
)
internal val DarkExtendedColorPalette =
ExtendedColors(
surfaceEnd = Dark.backgroundEnd,
backgroundColor = Dark.backgroundColor,
gridColor = Dark.gridColor,
onBackgroundHeader = Dark.textHeaderOnBackground,
tertiary = Dark.tertiaryButton,
onTertiary = Dark.textTertiaryButton,
callout = Dark.callout,
onCallout = Dark.onCallout,
circularProgressBarSmall = Dark.circularProgressBarSmall,
circularProgressBarSmallDark = Dark.circularProgressBarSmallDark,
circularProgressBarScreen = Dark.circularProgressBarScreen,
linearProgressBarTrack = Dark.linearProgressBarTrack,
linearProgressBarBackground = Dark.linearProgressBarBackground,
restoringTopAppBarColor = Dark.restoringTopAppBarColor,
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,
textPending = Dark.textProgress,
textDescriptionDark = Dark.textDescriptionDark,
layoutStroke = Dark.layoutStroke,
overlay = Dark.overlay,
highlight = Dark.highlight,
disabledButtonTextColor = Dark.disabledButtonTextColor,
disabledButtonColor = Dark.disabledButtonColor,
reference = Dark.reference,
buttonShadowColor = Dark.buttonShadowColor,
screenTitleColor = Dark.screenTitleColor,
aboutTextColor = Dark.aboutTextColor,
welcomeAnimationColor = Dark.welcomeAnimationColor,
complementaryColor = Dark.complementaryColor,
dividerColor = Dark.dividerColor,
darkDividerColor = Dark.darkDividerColor,
tabTextColor = Dark.tabTextColor,
panelBackgroundColor = Dark.panelBackgroundColor,
cameraDisabledBackgroundColor = Dark.cameraDisabledBackgroundColor,
cameraDisabledFrameColor = Dark.cameraDisabledFrameColor,
radioButtonColor = Dark.radioButtonColor,
radioButtonTextColor = Dark.radioButtonTextColor,
historyBackgroundColor = Dark.historyBackgroundColor,
historyRedColor = Dark.historyRedColor,
historySyncingColor = Dark.historySyncingColor,
topAppBarColors = Dark.topAppBarColors,
transparentTopAppBarColors = Dark.transparentTopAppBarColors
)
internal val LightExtendedColorPalette =
ExtendedColors(
surfaceEnd = Light.backgroundEnd,
backgroundColor = Light.backgroundColor,
gridColor = Light.gridColor,
onBackgroundHeader = Light.textHeaderOnBackground,
tertiary = Light.tertiaryButton,
onTertiary = Light.textTertiaryButton,
callout = Light.callout,
onCallout = Light.onCallout,
circularProgressBarScreen = Light.circularProgressBarScreen,
circularProgressBarSmall = Light.circularProgressBarSmall,
circularProgressBarSmallDark = Light.circularProgressBarSmallDark,
linearProgressBarTrack = Light.linearProgressBarTrack,
linearProgressBarBackground = Light.linearProgressBarBackground,
restoringTopAppBarColor = Light.restoringTopAppBarColor,
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,
textPending = Light.textProgress,
textDescriptionDark = Light.textDescriptionDark,
layoutStroke = Light.layoutStroke,
overlay = Light.overlay,
highlight = Light.highlight,
disabledButtonTextColor = Light.disabledButtonTextColor,
disabledButtonColor = Light.disabledButtonColor,
reference = Light.reference,
buttonShadowColor = Light.buttonShadowColor,
screenTitleColor = Light.screenTitleColor,
aboutTextColor = Light.aboutTextColor,
welcomeAnimationColor = Light.welcomeAnimationColor,
complementaryColor = Light.complementaryColor,
dividerColor = Light.dividerColor,
darkDividerColor = Light.darkDividerColor,
tabTextColor = Light.tabTextColor,
panelBackgroundColor = Light.panelBackgroundColor,
cameraDisabledBackgroundColor = Light.cameraDisabledBackgroundColor,
cameraDisabledFrameColor = Light.cameraDisabledFrameColor,
radioButtonColor = Light.radioButtonColor,
radioButtonTextColor = Light.radioButtonTextColor,
historyBackgroundColor = Light.historyBackgroundColor,
historyRedColor = Light.historyRedColor,
historySyncingColor = Light.historySyncingColor,
topAppBarColors = Light.topAppBarColors,
transparentTopAppBarColors = Light.transparentTopAppBarColors
)
@Suppress("CompositionLocalAllowlist")
internal val LocalExtendedColors =
staticCompositionLocalOf {
ExtendedColors(
surfaceEnd = Color.Unspecified,
backgroundColor = Color.Unspecified,
gridColor = Color.Unspecified,
onBackgroundHeader = Color.Unspecified,
tertiary = Color.Unspecified,
onTertiary = Color.Unspecified,
callout = Color.Unspecified,
onCallout = Color.Unspecified,
circularProgressBarScreen = Color.Unspecified,
circularProgressBarSmall = Color.Unspecified,
circularProgressBarSmallDark = Color.Unspecified,
linearProgressBarTrack = Color.Unspecified,
linearProgressBarBackground = Color.Unspecified,
restoringTopAppBarColor = 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,
textPending = Color.Unspecified,
textDescriptionDark = Color.Unspecified,
layoutStroke = Color.Unspecified,
overlay = Color.Unspecified,
highlight = Color.Unspecified,
disabledButtonTextColor = Color.Unspecified,
disabledButtonColor = Color.Unspecified,
reference = Color.Unspecified,
buttonShadowColor = Color.Unspecified,
screenTitleColor = Color.Unspecified,
aboutTextColor = Color.Unspecified,
welcomeAnimationColor = Color.Unspecified,
complementaryColor = Color.Unspecified,
dividerColor = Color.Unspecified,
darkDividerColor = Color.Unspecified,
tabTextColor = Color.Unspecified,
panelBackgroundColor = Color.Unspecified,
cameraDisabledBackgroundColor = Color.Unspecified,
cameraDisabledFrameColor = Color.Unspecified,
radioButtonColor = Color.Unspecified,
radioButtonTextColor = Color.Unspecified,
historyBackgroundColor = Color.Unspecified,
historyRedColor = Color.Unspecified,
historySyncingColor = Color.Unspecified,
topAppBarColors = DefaultTopAppBarColors(),
transparentTopAppBarColors = DefaultTopAppBarColors(),
)
}

View File

@ -0,0 +1,126 @@
@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
)
fun copyColors(
containerColor: Color = this.containerColor,
navigationColor: Color = this.navigationColor,
titleColor: Color = this.titleColor,
subTitleColor: Color = this.subTitleColor,
actionColor: Color = this.actionColor,
): TopAppBarColors
}
@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 {
override fun copyColors(
containerColor: Color,
navigationColor: Color,
titleColor: Color,
subTitleColor: Color,
actionColor: Color
) = this.copy(
containerColor = containerColor,
navigationColor = navigationColor,
titleColor = titleColor,
subTitleColor = subTitleColor,
actionColor = actionColor
)
}
@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 {
override fun copyColors(
containerColor: Color,
navigationColor: Color,
titleColor: Color,
subTitleColor: Color,
actionColor: Color
) = this.copy(
containerColor = containerColor,
navigationColor = navigationColor,
titleColor = titleColor,
subTitleColor = subTitleColor,
actionColor = actionColor
)
}
@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 {
override fun copyColors(
containerColor: Color,
navigationColor: Color,
titleColor: Color,
subTitleColor: Color,
actionColor: Color
) = this.copy(
containerColor = containerColor,
navigationColor = navigationColor,
titleColor = titleColor,
subTitleColor = subTitleColor,
actionColor = actionColor
)
}
@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 {
override fun copyColors(
containerColor: Color,
navigationColor: Color,
titleColor: Color,
subTitleColor: Color,
actionColor: Color
) = this.copy(
containerColor = containerColor,
navigationColor = navigationColor,
titleColor = titleColor,
subTitleColor = subTitleColor,
actionColor = actionColor
)
}

View File

@ -163,6 +163,7 @@ data class TransactionItemTextStyles(
val valueFirstPart: TextStyle,
val valueSecondPart: TextStyle,
val content: TextStyle,
val contentItalic: TextStyle,
val contentMedium: TextStyle,
val contentUnderline: TextStyle,
val contentLineThrough: TextStyle,
@ -182,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,
@ -192,6 +193,8 @@ data class ExtendedTypography(
// Grouping transaction item text styles to a wrapper class
val transactionItemStyles: TransactionItemTextStyles,
val restoringTopAppBarStyle: TextStyle,
val deleteWalletWarnStyle: TextStyle,
val updateTitleStyle: TextStyle,
)
@Suppress("CompositionLocalAllowlist")
@ -271,7 +274,7 @@ val LocalExtendedTypography =
fontSize = 16.sp,
fontWeight = FontWeight.Medium
),
securityWarningFootnote =
footnote =
PrimaryTypography.bodySmall.copy(
fontSize = 11.sp,
fontWeight = FontWeight.Medium
@ -335,6 +338,11 @@ val LocalExtendedTypography =
PrimaryTypography.bodySmall.copy(
fontSize = 13.sp
),
contentItalic =
PrimaryTypography.bodySmall.copy(
fontSize = 13.sp,
fontStyle = FontStyle.Italic
),
contentMedium =
PrimaryTypography.bodySmall.copy(
fontSize = 13.sp,
@ -366,6 +374,14 @@ val LocalExtendedTypography =
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.TopAppBarSubTitleState
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)
}
},
topAppBarSubTitleState = TopAppBarSubTitleState.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

@ -2,8 +2,8 @@ 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.TopAppBarSubTitleState
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
@ -28,8 +28,8 @@ class AboutViewTestSetup(
configInfo = configInfo,
onPrivacyPolicy = {},
snackbarHostState = SnackbarHostState(),
topAppBarSubTitleState = TopAppBarSubTitleState.None,
versionInfo = versionInfo,
walletRestoringState = WalletRestoringState.NONE
)
}
}

View File

@ -1,11 +1,14 @@
package co.electriccoin.zcash.ui.screen.account
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
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.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
@ -69,7 +72,13 @@ class AccountTestSetup(
onTransactionItemAction = {
onItemClickCount.incrementAndGet()
},
hideStatusDialog = {},
showStatusDialog = null,
onStatusClick = {},
snackbarHostState = SnackbarHostState(),
topAppBarSubTitleState = TopAppBarSubTitleState.None,
walletRestoringState = WalletRestoringState.NONE,
walletSnapshot = WalletSnapshotFixture.new(),
)
}

View File

@ -3,6 +3,7 @@ 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.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
@ -29,10 +30,12 @@ class HistoryTestSetup(
ZcashTheme {
HistoryContainer(
transactionState = initialHistoryUiState,
onStatusClick = {},
onTransactionItemAction = {
onItemIdClickCount.incrementAndGet()
},
walletRestoringState = WalletRestoringState.NONE
walletRestoringState = WalletRestoringState.NONE,
walletSnapshot = WalletSnapshotFixture.new()
)
}
}

View File

@ -3,6 +3,7 @@ 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 kotlinx.collections.immutable.ImmutableList
@ -11,9 +12,21 @@ 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

@ -1,7 +1,9 @@
package co.electriccoin.zcash.ui.screen.balances
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@ -35,13 +37,17 @@ class BalancesTestSetup(
onSettings = {
onSettingsCount.incrementAndGet()
},
isDetailedStatus = false,
hideStatusDialog = {},
showStatusDialog = null,
onStatusClick = {},
snackbarHostState = SnackbarHostState(),
isFiatConversionEnabled = isShowFiatConversion,
isUpdateAvailable = false,
isShowingErrorDialog = false,
setShowErrorDialog = {},
onShielding = {},
shieldState = ShieldState.Available,
topAppBarSubTitleState = TopAppBarSubTitleState.None,
walletSnapshot = walletSnapshot,
walletRestoringState = WalletRestoringState.NONE,
)

View File

@ -31,8 +31,7 @@ class WalletDisplayValuesTest {
WalletDisplayValues.getNextValues(
context = getAppContext(),
walletSnapshot = walletSnapshot,
isUpdateAvailable = false,
isDetailedStatus = false
isUpdateAvailable = false
)
assertNotNull(values)

View File

@ -3,7 +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.common.model.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
@ -44,7 +44,7 @@ class ExportPrivateDataViewTestSetup(private val composeTestRule: ComposeContent
onConfirm = {
onConfirmCount.incrementAndGet()
},
walletRestoringState = WalletRestoringState.NONE
topAppBarSubTitleState = TopAppBarSubTitleState.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

@ -12,8 +12,8 @@ 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.TopAppBarSubTitleState
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
@ -70,8 +70,8 @@ class ReceiveViewTestSetup(
onAddrCopyToClipboard = {},
onQrImageShare = {},
screenBrightnessState = ScreenBrightnessState.NORMAL,
topAppBarSubTitleState = TopAppBarSubTitleState.None,
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.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.scan.model.ScanState
import java.util.concurrent.atomic.AtomicInteger
@ -28,7 +30,7 @@ class ScanViewBasicTestSetup(
@Suppress("TestFunctionName")
fun DefaultContent() {
Scan(
snackbarHostState = SnackbarHostState(),
addressValidationResult = AddressType.Shielded,
onBack = {
onBackCount.incrementAndGet()
},
@ -36,7 +38,9 @@ class ScanViewBasicTestSetup(
onOpenSettings = {},
onScanStateChanged = {
scanState.set(it)
}
},
snackbarHostState = SnackbarHostState(),
topAppBarSubTitleState = TopAppBarSubTitleState.None,
)
}

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,7 +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.common.model.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
import kotlinx.coroutines.test.runTest
@ -16,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()
@ -49,8 +49,8 @@ class SeedRecoveryViewsSecuredScreenTest : UiTestPrerequisites() {
onBirthdayCopy = {},
onDone = {},
onSeedCopy = {},
topAppBarSubTitleState = TopAppBarSubTitleState.None,
versionInfo = VersionInfoFixture.new(),
walletRestoringState = WalletRestoringState.NONE
)
}
}

View File

@ -3,8 +3,8 @@ package co.electriccoin.zcash.ui.screen.seedrecovery.view
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.TopAppBarSubTitleState
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
@ -43,8 +43,8 @@ class SeedRecoveryTestSetup(
onBirthdayCopy = { onBirthdayCopyCount.incrementAndGet() },
onDone = { onCompleteCallbackCount.incrementAndGet() },
onSeedCopy = { /* Not tested - debug mode feature only */ },
topAppBarSubTitleState = TopAppBarSubTitleState.None,
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,7 @@ 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.common.model.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
@ -79,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) }
@ -130,10 +128,10 @@ class SendViewTestSetup(
// TODO [#1260]: https://github.com/Electric-Coin-Company/zashi-android/issues/1260
},
setAmountState = {},
amountState = AmountState.new(context, "", monetarySeparators),
amountState = AmountState.new(context, monetarySeparators, "", false),
setMemoState = {},
memoState = MemoState.new(""),
walletRestoringState = WalletRestoringState.NONE,
topAppBarSubTitleState = TopAppBarSubTitleState.None,
walletSnapshot =
WalletSnapshotFixture.new(
saplingBalance =

View File

@ -11,14 +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.common.model.TopAppBarSubTitleState
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
@ -51,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
@ -82,7 +79,7 @@ class SendViewIntegrationTest {
goSendConfirmation = {},
hasCameraFeature = true,
monetarySeparators = monetarySeparators,
walletRestoringState = WalletRestoringState.NONE,
topAppBarSubTitleState = TopAppBarSubTitleState.None,
)
}
@ -102,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,7 +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.common.model.TopAppBarSubTitleState
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
@ -89,7 +89,7 @@ class SettingsViewTestSetup(
onAnalyticsSettingsChanged = {
onAnalyticsChangedCount.incrementAndGet()
},
walletRestoringState = WalletRestoringState.NONE
topAppBarSubTitleState = TopAppBarSubTitleState.None,
)
}
}

View File

@ -3,7 +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.common.model.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicReference
@ -47,7 +47,7 @@ class SupportViewTestSetup(private val composeTestRule: ComposeContentTestRule)
onSendMessage.set(it)
},
snackbarHostState = SnackbarHostState(),
walletRestoringState = WalletRestoringState.NONE
topAppBarSubTitleState = TopAppBarSubTitleState.None,
)
}

View File

@ -3,6 +3,7 @@ package co.electriccoin.zcash.ui.screen.update.util
import android.content.Intent
import androidx.test.filters.SmallTest
import co.electriccoin.zcash.ui.test.getAppContext
import co.electriccoin.zcash.ui.util.PlayStoreUtil
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Test

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,24 +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.BlankSurface
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
@ -53,7 +63,7 @@ import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
class MainActivity : ComponentActivity() {
class MainActivity : AppCompatActivity() {
private val homeViewModel by viewModels<HomeViewModel>()
val walletViewModel by viewModels<WalletViewModel>()
@ -61,6 +71,10 @@ class MainActivity : ComponentActivity() {
@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)
@ -118,7 +132,7 @@ class MainActivity : ComponentActivity() {
setContent {
Override(configurationOverrideFlow) {
ZcashTheme {
GradientSurface(
BlankSurface(
Modifier
.fillMaxWidth()
.fillMaxHeight()
@ -130,6 +144,8 @@ class MainActivity : ComponentActivity() {
} else {
MainContent()
}
AuthenticationForAppAccess()
}
}
}
@ -141,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

View File

@ -1,13 +1,21 @@
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.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavBackStackEntry
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.Synchronizer
import cash.z.ecc.android.sdk.model.ZecSend
import co.electriccoin.zcash.spackle.Twig
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
@ -18,9 +26,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
@ -35,10 +43,13 @@ 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.disconnected.WrapDisconnected
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
@ -49,6 +60,9 @@ import co.electriccoin.zcash.ui.screen.sendconfirmation.model.SendConfirmationSt
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
@ -62,6 +76,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,
@ -71,42 +93,7 @@ internal fun MainActivity.Navigation() {
popExitTransition = { popExitTransition() }
) {
composable(HOME) { backStack ->
WrapHome(
goBack = { finish() },
goScan = { navController.navigateJustOnce(SCAN) },
goSendConfirmation = { zecSend ->
navController.currentBackStackEntry?.savedStateHandle?.let { handle ->
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 =
backStack.savedStateHandle.get<String>(SEND_SCAN_RECIPIENT_ADDRESS)?.let {
Json.decodeFromString<SerializableAddress>(it).toRecipient()
},
clearForm = backStack.savedStateHandle.get<Boolean>(MULTIPLE_SUBMISSION_CLEAR_FORM) ?: false
).also {
// Remove Send screen arguments passed from the Scan or MultipleSubmissionFailure screens if
// some exist after we use them
backStack.savedStateHandle.remove<String>(SEND_SCAN_RECIPIENT_ADDRESS)
backStack.savedStateHandle.remove<Boolean>(MULTIPLE_SUBMISSION_CLEAR_FORM)
},
)
if (ConfigurationEntries.IS_APP_UPDATE_CHECK_ENABLED.getValue(RemoteConfig.current)) {
WrapCheckForUpdate()
}
NavigationHome(navController, backStack)
}
composable(SETTINGS) {
WrapSettings(
@ -130,15 +117,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(
@ -150,20 +182,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) })
}
@ -183,8 +222,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) {
@ -197,6 +242,7 @@ internal fun MainActivity.Navigation() {
navController.popBackStackJustOnce(SEND_CONFIRMATION)
},
goHome = { navController.navigateJustOnce(HOME) },
goSupport = { navController.navigateJustOnce(SUPPORT) },
arguments = SendConfirmationArguments.fromSavedStateHandle(backStackEntry.savedStateHandle)
)
}
@ -204,6 +250,112 @@ internal fun MainActivity.Navigation() {
}
}
/**
* This is the Home screens sub-navigation. We could consider creating a separate sub-navigation graph.
*/
@Composable
private fun MainActivity.NavigationHome(
navController: NavHostController,
backStack: NavBackStackEntry
) {
WrapHome(
goBack = { finish() },
goScan = { navController.navigateJustOnce(SCAN) },
goSendConfirmation = { zecSend ->
navController.currentBackStackEntry?.savedStateHandle?.let { handle ->
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 =
backStack.savedStateHandle.get<String>(SEND_SCAN_RECIPIENT_ADDRESS)?.let {
Json.decodeFromString<SerializableAddress>(it).toRecipient()
},
clearForm = backStack.savedStateHandle.get<Boolean>(MULTIPLE_SUBMISSION_CLEAR_FORM) ?: false
).also {
// Remove Send screen arguments passed from the Scan or MultipleSubmissionFailure screens if
// some exist after we use them
backStack.savedStateHandle.remove<String>(SEND_SCAN_RECIPIENT_ADDRESS)
backStack.savedStateHandle.remove<Boolean>(MULTIPLE_SUBMISSION_CLEAR_FORM)
},
)
val sdkStatus = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value?.status
if (Synchronizer.Status.DISCONNECTED == sdkStatus) {
Twig.info { "Disconnected state received from Synchronizer" }
WrapDisconnected(
goChooseServer = {
navController.navigateJustOnce(CHOOSE_SERVER)
},
onIgnore = {
// Keep the current navigation location
}
)
} else if (ConfigurationEntries.IS_APP_UPDATE_CHECK_ENABLED.getValue(RemoteConfig.current)) {
WrapCheckForUpdate()
}
}
@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?,
@ -265,10 +417,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

@ -22,9 +22,9 @@ 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.design.R
import co.electriccoin.zcash.ui.design.component.BlankSurface
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
@ -33,7 +33,7 @@ import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@Composable
private fun BalanceWidgetPreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface(
BlankSurface(
modifier = Modifier.fillMaxWidth()
) {
@Suppress("MagicNumber")
@ -57,7 +57,7 @@ private fun BalanceWidgetPreview() {
@Composable
private fun BalanceWidgetNotAvailableYetPreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface(
BlankSurface(
modifier = Modifier.fillMaxWidth()
) {
@Suppress("MagicNumber")
@ -80,6 +80,7 @@ sealed class BalanceState(open val totalBalance: Zatoshi) {
}
@Composable
@Suppress("LongMethod")
fun BalanceWidget(
balanceState: BalanceState,
isReferenceToBalances: Boolean,
@ -104,11 +105,22 @@ fun BalanceWidget(
text = stringResource(id = co.electriccoin.zcash.ui.R.string.balance_widget_available),
onClick = onReferenceClick,
fontWeight = FontWeight.Normal,
modifier = Modifier.padding(all = ZcashTheme.dimens.spacingTiny)
modifier =
Modifier
.padding(
vertical = ZcashTheme.dimens.spacingSmall,
horizontal = ZcashTheme.dimens.spacingMini,
)
)
} else {
Body(
text = stringResource(id = co.electriccoin.zcash.ui.R.string.balance_widget_available),
modifier =
Modifier
.padding(
vertical = ZcashTheme.dimens.spacingSmall,
horizontal = ZcashTheme.dimens.spacingMini,
)
)
}

View File

@ -0,0 +1,122 @@
package co.electriccoin.zcash.ui.common.compose
import androidx.compose.foundation.clickable
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.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
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.AppAlertDialog
import co.electriccoin.zcash.ui.design.component.BlankSurface
import co.electriccoin.zcash.ui.design.component.BodySmall
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.StatusAction
import co.electriccoin.zcash.ui.screen.balances.model.WalletDisplayValues
@Preview(device = Devices.PIXEL_4_XL)
@Composable
private fun BalanceWidgetPreview() {
ZcashTheme(forceDarkMode = false) {
BlankSurface(
modifier = Modifier.fillMaxWidth()
) {
SynchronizationStatus(
isUpdateAvailable = false,
onStatusClick = {},
walletSnapshot = WalletSnapshotFixture.new(),
)
}
}
}
@Composable
fun SynchronizationStatus(
isUpdateAvailable: Boolean,
onStatusClick: (StatusAction) -> Unit,
walletSnapshot: WalletSnapshot,
modifier: Modifier = Modifier,
testTag: String? = null,
) {
val walletDisplayValues =
WalletDisplayValues.getNextValues(
context = LocalContext.current,
walletSnapshot = walletSnapshot,
isUpdateAvailable = isUpdateAvailable,
)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
) {
if (walletDisplayValues.statusText.isNotEmpty()) {
BodySmall(
text = walletDisplayValues.statusText,
textAlign = TextAlign.Center,
modifier =
Modifier
.clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner))
.clickable { onStatusClick(walletDisplayValues.statusAction) }
.padding(all = ZcashTheme.dimens.spacingSmall)
.then(testTag?.let { Modifier.testTag(testTag) } ?: Modifier),
)
}
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.spacingDefault
)
)
}
}
@Composable
fun StatusDialog(
statusAction: StatusAction.Detailed,
onDone: () -> Unit
) {
AppAlertDialog(
title = stringResource(id = R.string.balances_status_error_dialog_title),
text = {
Column(
Modifier.verticalScroll(rememberScrollState())
) {
Text(text = statusAction.details)
}
},
confirmButtonText = stringResource(id = R.string.balances_status_dialog_button),
onConfirmButtonClick = onDone
)
}

View File

@ -0,0 +1,9 @@
package co.electriccoin.zcash.ui.common.model
sealed class TopAppBarSubTitleState {
data object None : TopAppBarSubTitleState()
data object Disconnected : TopAppBarSubTitleState()
data object Restoring : TopAppBarSubTitleState()
}

View File

@ -34,6 +34,8 @@ data class WalletSnapshot(
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
@ -48,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,416 @@
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 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 user does not have any biometrics enrolled
BiometricPrompt.ERROR_NO_BIOMETRICS,
// 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
// These 2 errors can come for a different Android SDK versions, but they mean the same
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.StatusUnexpected
}
}
}
@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 StatusUnexpected : BiometricSupportResult()
}

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