Compare commits

...

7 Commits

Author SHA1 Message Date
Emerson 0625c06247
Merge d8566d11ae into e0439f0ca9 2024-04-24 17:11:40 +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
Emerson Hall d8566d11ae Add zec.rocks to the server list 2024-04-20 23:05:39 -05:00
15 changed files with 63 additions and 50 deletions

View File

@ -9,8 +9,11 @@ directly impact users rather than highlighting other key architectural updates.*
## [Unreleased]
## [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

View File

@ -62,7 +62,7 @@ NDK_DEBUG_SYMBOL_LEVEL=symbol_table
# VERSION_CODE is effectively ignored. VERSION_NAME is suffixed with the version code.
# If not using automated Google Play deployment, then these serve as the actual version numbers.
ZCASH_VERSION_CODE=1
ZCASH_VERSION_NAME=0.2.0
ZCASH_VERSION_NAME=1.0
# Set these fields, as you need them (e.g. with values "Zcash X" and "co.electriccoin.zcash.x")
# to distinguish a different release build that can be installed alongside the official version
@ -198,7 +198,7 @@ ZXING_VERSION=3.5.3
ZCASH_BIP39_VERSION=1.0.8
# WARNING: Ensure a non-snapshot version is used before releasing to production
ZCASH_SDK_VERSION=2.1.1-SNAPSHOT
ZCASH_SDK_VERSION=2.1.1
# Toolchain is the Java version used to build the application, which is separate from the
# Java version used to run the application.

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

@ -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

@ -18,7 +18,6 @@ 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
@ -100,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

@ -47,6 +47,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
import cash.z.ecc.android.sdk.model.FiatCurrencyConversionRateState
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.model.toZecString
@ -318,6 +319,8 @@ private fun BalancesMainContent(
}
}
const val DEFAULT_LESS_THAN_FEE = 100_000L
@Composable
fun TransparentBalancePanel(
onShielding: () -> Unit,
@ -366,8 +369,7 @@ fun TransparentBalancePanel(
id = R.string.balances_transparent_balance_fee,
// TODO [#1047]: Representing Zatoshi amount
// TODO [#1047]: https://github.com/Electric-Coin-Company/zashi-android/issues/1047
@Suppress("MagicNumber")
Zatoshi(100_000L).toZecString()
Zatoshi(DEFAULT_LESS_THAN_FEE).convertZatoshiToZecString(maxDecimals = 3)
),
textFontWeight = FontWeight.SemiBold
)

View File

@ -22,6 +22,10 @@ object AvailableServerProvider {
private const val HOST_SA = "sa.lightwalletd.com" // NON-NLS
private const val HOST_EU = "eu.lightwalletd.com" // NON-NLS
private const val HOST_AI = "ai.lightwalletd.com" // NON-NLS
private const val HOST_ZR_GLOBAL = "zec.rocks" // NON-NLS
private const val HOST_ZR_SA = "sa.zec.rocks" // NON-NLS
private const val HOST_ZR_EU = "eu.zec.rocks" // NON-NLS
private const val HOST_ZR_AP = "ap.zec.rocks" // NON-NLS
private const val PORT = 443
fun toList(network: ZcashNetwork) =
@ -32,6 +36,10 @@ object AvailableServerProvider {
add(LightWalletEndpoint(HOST_SA, PORT, true))
add(LightWalletEndpoint(HOST_EU, PORT, true))
add(LightWalletEndpoint(HOST_AI, PORT, true))
add(LightWalletEndpoint(HOST_ZR_GLOBAL, PORT, true))
add(LightWalletEndpoint(HOST_ZR_SA, PORT, true))
add(LightWalletEndpoint(HOST_ZR_EU, PORT, true))
add(LightWalletEndpoint(HOST_ZR_AP, PORT, true))
} else {
add(LightWalletEndpoint.Testnet)
}

View File

@ -4,6 +4,7 @@ package co.electriccoin.zcash.ui.screen.send.view
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@ -24,11 +25,16 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.testTag
@ -40,12 +46,12 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
import cash.z.ecc.android.sdk.model.Memo
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.model.ZecSendExt
import cash.z.ecc.android.sdk.model.toZecString
import cash.z.ecc.android.sdk.type.AddressType
import cash.z.ecc.sdk.fixture.ZatoshiFixture
import cash.z.ecc.sdk.type.ZcashCurrency
@ -75,6 +81,7 @@ import co.electriccoin.zcash.ui.screen.send.model.AmountState
import co.electriccoin.zcash.ui.screen.send.model.MemoState
import co.electriccoin.zcash.ui.screen.send.model.RecipientAddressState
import co.electriccoin.zcash.ui.screen.send.model.SendStage
import kotlinx.coroutines.launch
import java.util.Locale
@Composable
@ -270,6 +277,8 @@ private fun SendForm(
val scrollState = rememberScrollState()
val (scrollToFeePixels, setScrollToFeePixels) = rememberSaveable { mutableIntStateOf(0) }
Column(
modifier =
Modifier
@ -330,6 +339,8 @@ private fun SendForm(
recipientAddressState.type !is AddressType.Transparent
)
),
scrollState = scrollState,
scrollTo = scrollToFeePixels
)
Spacer(
@ -341,7 +352,15 @@ private fun SendForm(
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
SendButton(amountState, memoState, monetarySeparators, onCreateZecSend, recipientAddressState, walletSnapshot)
SendButton(
amountState = amountState,
memoState = memoState,
monetarySeparators = monetarySeparators,
onCreateZecSend = onCreateZecSend,
recipientAddressState = recipientAddressState,
walletSnapshot = walletSnapshot,
setScrollToFeePixels = setScrollToFeePixels
)
}
}
@ -353,6 +372,7 @@ fun SendButton(
monetarySeparators: MonetarySeparators,
onCreateZecSend: (ZecSend) -> Unit,
recipientAddressState: RecipientAddressState,
setScrollToFeePixels: (Int) -> Unit,
walletSnapshot: WalletSnapshot,
) {
val context = LocalContext.current
@ -414,9 +434,13 @@ fun SendButton(
id = R.string.send_fee,
// TODO [#1047]: Representing Zatoshi amount
// TODO [#1047]: https://github.com/Electric-Coin-Company/zashi-android/issues/1047
Zatoshi(DEFAULT_LESS_THAN_FEE).toZecString()
Zatoshi(DEFAULT_LESS_THAN_FEE).convertZatoshiToZecString(maxDecimals = 3)
),
textFontWeight = FontWeight.SemiBold
textFontWeight = FontWeight.SemiBold,
modifier =
Modifier.onGloballyPositioned {
setScrollToFeePixels(it.positionInRoot().y.toInt())
}
)
}
}
@ -584,12 +608,11 @@ fun SendFormAmountTextField(
),
keyboardActions =
KeyboardActions(
onDone = {
focusManager.clearFocus(true)
},
onNext = {
if (imeAction == ImeAction.Done) {
focusManager.clearFocus(true)
} else {
focusManager.moveFocus(FocusDirection.Down)
}
focusManager.moveFocus(FocusDirection.Down)
}
),
bringIntoViewRequester = bringIntoViewRequester,
@ -600,14 +623,18 @@ fun SendFormAmountTextField(
// TODO [#1259]: Send.Form screen Memo field stroke bubble style
// TODO [#1259]: https://github.com/Electric-Coin-Company/zashi-android/issues/1259
@OptIn(ExperimentalFoundationApi::class)
@Suppress("LongMethod")
@Suppress("LongMethod", "LongParameterList")
@Composable
fun SendFormMemoTextField(
focusManager: FocusManager,
isMemoFieldAvailable: Boolean,
memoState: MemoState,
setMemoState: (MemoState) -> Unit,
scrollState: ScrollState,
scrollTo: Int
) {
val scope = rememberCoroutineScope()
val bringIntoViewRequester = remember { BringIntoViewRequester() }
Column(
@ -664,8 +691,14 @@ fun SendFormMemoTextField(
),
keyboardActions =
KeyboardActions(
onNext = {
onDone = {
focusManager.clearFocus(true)
// Scroll down to make sure the Send button is visible on small screens
if (scrollTo > 0) {
scope.launch {
scrollState.animateScrollTo(scrollTo)
}
}
}
),
placeholder = {

View File

@ -54,7 +54,7 @@ fun NotEnoughSpaceView(
) {
Image(
painter = painterResource(id = R.drawable.not_enough_space),
contentDescription = stringResource(id = R.string.not_enough_space_logo_content_description),
contentDescription = null,
modifier = Modifier.fillMaxWidth()
)

View File

@ -2,7 +2,6 @@
<string name="fiat_currency_conversion_rate_unavailable">Unavailable</string>
<string name="empty_char">-</string>
<string name="zcash_logo_content_description">Zcash logo</string>
<string name="not_implemented_yet">Not implemented yet.</string>
<string name="settings_menu_content_description">Open Settings</string>
<string name="balance_widget_available">Available Balance:</string>
<!-- This is replaced by a resource overlay via app/build.gradle.kts -->

View File

@ -2,7 +2,7 @@
<string name="app_name">zcash-ui</string>
<string name="onboarding_header">A no-frills wallet for sending and receiving Zcash (ZEC)</string>
<string name="onboarding_information">We need to create a new wallet or restore an existing one. Select your path:</string>
<string name="onboarding_create_new_wallet">Create New Wallet</string>
<string name="onboarding_import_existing_wallet">Restore Existing Wallet</string>

View File

@ -1,7 +1,5 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="send_stage_send_title">Send</string>
<string name="send_back">Back</string>
<string name="send_back_content_description">Back</string>
<string name="send_scan_content_description">Scan</string>
<string name="send_address_label">To:</string>
<string name="send_address_hint">Zcash Address</string>

View File

@ -1,11 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="not_enough_space_title">Not enough space!</string>
<string name="not_enough_space_logo_content_description"></string>
<string name="not_enough_space_description">You need approximately <xliff:g example="1" id="required_gigabytes">
%1$d</xliff:g> Gbyte of space while synchronizing the Zcash blockchain, but only 300 Mbyte once done. Syncing
will stay paused until more space is available.</string>
<string name="space_required_to_continue"><xliff:g example="300" id="required_megabytes">~%1$d</xliff:g> Mbyte
required to continue </string>
<string name="unknown">Unknown</string>
</resources>