[#947] About screen UI/logic/tests
* [#947] About screen UI (partially implemented) * [#947] About screen UI * [#947] Fixed failing test case * [#947] Added Zashi text logo --------- Co-authored-by: Honza Rychnovský <rychnovsky.honza@gmail.com> * [#947] UI: About Screen * [#1005] Remove DebugMenu from Home screen - The new design does not require it on the Home screen - Partially moved to the Settings and About screens * [#392] Update About screen texts Closes #392 as not needed now * [#1006] Enhance VersionInfo with other fields * [#947] About screen UI + logic + tests * Adopt VersionInfo on different screens * VersionInfo test Update .gitignore --------- Co-authored-by: Venkat-corebts <143575548+Venkat-corebts@users.noreply.github.com>
This commit is contained in:
parent
e871c4eb45
commit
16bf1afa90
|
@ -23,3 +23,4 @@ local.properties
|
|||
/.idea/androidTestResultsUserPreferences.xml
|
||||
google-services.json
|
||||
/.idea/kotlinc.xml
|
||||
/.idea/other.xml
|
||||
|
|
|
@ -6,7 +6,6 @@ import co.electriccoin.zcash.configuration.test.fixture.BooleanDefaultEntryFixtu
|
|||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
@ -34,7 +33,6 @@ class MergingConfigurationProviderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
fun getFlow_ordering() = runTest {
|
||||
val configurationProvider = MergingConfigurationProvider(
|
||||
persistentListOf(
|
||||
|
@ -53,7 +51,6 @@ class MergingConfigurationProviderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
fun getFlow_empty() = runTest {
|
||||
val configurationProvider = MergingConfigurationProvider(
|
||||
emptyList<ConfigurationProvider>().toPersistentList()
|
||||
|
@ -65,7 +62,6 @@ class MergingConfigurationProviderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
fun getUpdatedAt_newest() = runTest {
|
||||
val older = "2023-01-15T08:38:45.415Z".toInstant()
|
||||
val newer = "2023-01-17T08:38:45.415Z".toInstant()
|
||||
|
|
|
@ -27,6 +27,7 @@ data class Dimens(
|
|||
val defaultButtonHeight: Dp,
|
||||
val zcashLogoHeight: Dp,
|
||||
val zcashLogoWidth: Dp,
|
||||
val zcashTextLogoHeight: Dp
|
||||
)
|
||||
|
||||
private val defaultDimens = Dimens(
|
||||
|
@ -45,6 +46,7 @@ private val defaultDimens = Dimens(
|
|||
defaultButtonHeight = 50.dp,
|
||||
zcashLogoHeight = 100.dp,
|
||||
zcashLogoWidth = 60.dp,
|
||||
zcashTextLogoHeight = 30.dp
|
||||
)
|
||||
|
||||
private val normalDimens = defaultDimens
|
||||
|
|
|
@ -31,6 +31,7 @@ data class ExtendedColors(
|
|||
val disabledButtonTextColor: Color,
|
||||
val buttonShadowColor: Color,
|
||||
val screenTitleColor: Color,
|
||||
val aboutTextColor: Color,
|
||||
val welcomeAnimationColor: Color,
|
||||
) {
|
||||
@Composable
|
||||
|
|
|
@ -60,6 +60,9 @@ internal object Dark {
|
|||
|
||||
val buttonShadowColor = Color(0xFFFFFFFF)
|
||||
|
||||
// to be added later
|
||||
val aboutTextColor = Color.Unspecified
|
||||
|
||||
val screenTitleColor = Color(0xFF040404)
|
||||
|
||||
val welcomeAnimationColor = Color(0xFF231F20)
|
||||
|
@ -122,6 +125,8 @@ internal object Light {
|
|||
|
||||
val screenTitleColor = Color(0xFF040404)
|
||||
|
||||
val aboutTextColor = Color(0xFF4E4E4E)
|
||||
|
||||
val welcomeAnimationColor = Color(0xFF231F20)
|
||||
}
|
||||
|
||||
|
@ -171,6 +176,7 @@ internal val DarkExtendedColorPalette = ExtendedColors(
|
|||
reference = Dark.reference,
|
||||
buttonShadowColor = Dark.buttonShadowColor,
|
||||
screenTitleColor = Dark.screenTitleColor,
|
||||
aboutTextColor = Dark.aboutTextColor,
|
||||
welcomeAnimationColor = Dark.welcomeAnimationColor
|
||||
)
|
||||
|
||||
|
@ -198,6 +204,7 @@ internal val LightExtendedColorPalette = ExtendedColors(
|
|||
reference = Light.reference,
|
||||
buttonShadowColor = Light.buttonShadowColor,
|
||||
screenTitleColor = Light.screenTitleColor,
|
||||
aboutTextColor = Light.aboutTextColor,
|
||||
welcomeAnimationColor = Light.welcomeAnimationColor
|
||||
)
|
||||
|
||||
|
@ -227,6 +234,7 @@ internal val LocalExtendedColors = staticCompositionLocalOf {
|
|||
reference = Color.Unspecified,
|
||||
buttonShadowColor = Color.Unspecified,
|
||||
screenTitleColor = Color.Unspecified,
|
||||
aboutTextColor = Color.Unspecified,
|
||||
welcomeAnimationColor = Color.Unspecified,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@ data class ExtendedTypography(
|
|||
val chipIndex: TextStyle,
|
||||
val listItem: TextStyle,
|
||||
val zecBalance: TextStyle,
|
||||
val aboutText: TextStyle,
|
||||
val buttonText: TextStyle,
|
||||
val checkboxText: TextStyle,
|
||||
val securityWarningText: TextStyle
|
||||
|
@ -141,6 +142,10 @@ val LocalExtendedTypography = staticCompositionLocalOf {
|
|||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 30.sp
|
||||
),
|
||||
aboutText = PrimaryTypography.bodyLarge.copy(
|
||||
fontSize = 14.sp,
|
||||
lineHeight = 20.sp
|
||||
),
|
||||
buttonText = PrimaryTypography.bodySmall.copy(
|
||||
fontSize = 14.sp
|
||||
),
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package co.electriccoin.zcash.ui.common.model
|
||||
|
||||
import androidx.test.filters.SmallTest
|
||||
import co.electriccoin.zcash.ui.test.getAppContext
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class VersionInfoTest {
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
fun sanity_check_version_info_in_testing() {
|
||||
val versionInfo = VersionInfo.new(getAppContext())
|
||||
|
||||
// We expect some VersionInfo object parameters to be empty during the testing
|
||||
// isDebuggable is not tested as it's not static during UI testing in CI or locally
|
||||
|
||||
assertEquals("null", versionInfo.versionName)
|
||||
assertEquals(0, versionInfo.versionCode)
|
||||
assertNotEquals(versionInfo.gitSha, "")
|
||||
assertTrue(versionInfo.gitCommitCount >= 1)
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
package co.electriccoin.zcash.ui.screen.about
|
||||
|
||||
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.test.filters.MediumTest
|
||||
import co.electriccoin.zcash.build.gitSha
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.fixture.ConfigInfoFixture
|
||||
import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
|
||||
import co.electriccoin.zcash.ui.screen.about.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.screen.about.view.About
|
||||
import co.electriccoin.zcash.ui.screen.support.model.ConfigInfo
|
||||
import co.electriccoin.zcash.ui.test.getStringResource
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class AboutViewTest {
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun setup() {
|
||||
newTestSetup()
|
||||
|
||||
composeTestRule.onNodeWithText(VersionInfoFixture.VERSION_NAME, substring = true).also {
|
||||
it.assertExists()
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithText(gitSha, substring = true).also {
|
||||
it.assertExists()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun back() {
|
||||
val testSetup = newTestSetup()
|
||||
|
||||
assertEquals(0, testSetup.getOnBackCount())
|
||||
|
||||
composeTestRule.onNodeWithContentDescription(getStringResource(R.string.about_back_content_description)).also {
|
||||
it.performClick()
|
||||
}
|
||||
|
||||
assertEquals(1, testSetup.getOnBackCount())
|
||||
}
|
||||
|
||||
private fun newTestSetup() = TestSetup(
|
||||
composeTestRule,
|
||||
VersionInfoFixture.new(),
|
||||
ConfigInfoFixture.new()
|
||||
)
|
||||
|
||||
private class TestSetup(
|
||||
private val composeTestRule: ComposeContentTestRule,
|
||||
versionInfo: VersionInfo,
|
||||
configInfo: ConfigInfo
|
||||
) {
|
||||
|
||||
private val onBackCount = AtomicInteger(0)
|
||||
|
||||
fun getOnBackCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onBackCount.get()
|
||||
}
|
||||
|
||||
init {
|
||||
composeTestRule.setContent {
|
||||
ZcashTheme {
|
||||
About(versionInfo = versionInfo, configInfo = configInfo) {
|
||||
onBackCount.incrementAndGet()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package co.electriccoin.zcash.ui.screen.about.view
|
||||
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.test.filters.MediumTest
|
||||
import androidx.test.filters.SmallTest
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.fixture.ConfigInfoFixture
|
||||
import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
|
||||
import co.electriccoin.zcash.ui.screen.about.AboutTag
|
||||
import co.electriccoin.zcash.ui.test.getStringResource
|
||||
import org.junit.Rule
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class AboutViewTest {
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun default_ui_state_test() {
|
||||
val testSetup = newTestSetup()
|
||||
|
||||
assertEquals(0, testSetup.getOnBackCount())
|
||||
|
||||
composeTestRule.onNodeWithText(getStringResource(R.string.about_back).uppercase()).also {
|
||||
it.assertExists()
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithContentDescription(
|
||||
label = getStringResource(R.string.about_app_logo_content_description)
|
||||
).also {
|
||||
it.assertExists()
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithText(getStringResource(R.string.about_description)).also {
|
||||
it.assertExists()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun version_setup_test() {
|
||||
newTestSetup()
|
||||
|
||||
composeTestRule.onNodeWithText(VersionInfoFixture.VERSION_NAME, substring = true).also {
|
||||
it.assertExists()
|
||||
}
|
||||
composeTestRule.onNodeWithText(VersionInfoFixture.VERSION_CODE.toString(), substring = true).also {
|
||||
it.assertExists()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@MediumTest
|
||||
fun back_test() {
|
||||
val testSetup = newTestSetup()
|
||||
|
||||
assertEquals(0, testSetup.getOnBackCount())
|
||||
|
||||
composeTestRule.onNodeWithContentDescription(getStringResource(R.string.about_back_content_description)).also {
|
||||
it.performClick()
|
||||
}
|
||||
|
||||
assertEquals(1, testSetup.getOnBackCount())
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
fun debug_menu_visible_test() {
|
||||
newTestSetup(isDebuggable = true)
|
||||
|
||||
composeTestRule.onNodeWithTag(AboutTag.DEBUG_MENU_TAG).also {
|
||||
it.assertExists()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
fun debug_menu_not_visible_test() {
|
||||
newTestSetup(isDebuggable = false)
|
||||
|
||||
composeTestRule.onNodeWithTag(AboutTag.DEBUG_MENU_TAG).also {
|
||||
it.assertDoesNotExist()
|
||||
}
|
||||
}
|
||||
|
||||
private fun newTestSetup(isDebuggable: Boolean = false) = AboutViewTestSetup(
|
||||
composeTestRule,
|
||||
VersionInfoFixture.new(isDebuggable = isDebuggable),
|
||||
ConfigInfoFixture.new()
|
||||
)
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package co.electriccoin.zcash.ui.screen.about.view
|
||||
|
||||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.screen.support.model.ConfigInfo
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class AboutViewTestSetup(
|
||||
private val composeTestRule: ComposeContentTestRule,
|
||||
versionInfo: VersionInfo,
|
||||
configInfo: ConfigInfo
|
||||
) {
|
||||
|
||||
private val onBackCount = AtomicInteger(0)
|
||||
|
||||
fun getOnBackCount(): Int {
|
||||
composeTestRule.waitForIdle()
|
||||
return onBackCount.get()
|
||||
}
|
||||
|
||||
init {
|
||||
composeTestRule.setContent {
|
||||
ZcashTheme {
|
||||
About(
|
||||
onBack = { onBackCount.incrementAndGet() },
|
||||
versionInfo = versionInfo,
|
||||
configInfo = configInfo
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -71,7 +71,6 @@ class HomeTestSetup(
|
|||
isKeepScreenOnDuringSync = false,
|
||||
isFiatConversionEnabled = isShowFiatConversion,
|
||||
isCircularProgressBarEnabled = isCircularProgressBar,
|
||||
isDebugMenuEnabled = false,
|
||||
goSettings = {
|
||||
onSettingsCount.incrementAndGet()
|
||||
},
|
||||
|
@ -93,7 +92,6 @@ class HomeTestSetup(
|
|||
goHistory = {
|
||||
onHistoryCount.incrementAndGet()
|
||||
},
|
||||
resetSdk = {},
|
||||
drawerState = drawerValues.drawerState,
|
||||
scope = drawerValues.scope
|
||||
)
|
||||
|
|
|
@ -3,10 +3,8 @@ package co.electriccoin.zcash.ui.screen.securitywarning.view
|
|||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||
import co.electriccoin.zcash.spackle.getPackageInfoCompat
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.screen.about.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.test.getAppContext
|
||||
import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
|
@ -50,9 +48,7 @@ class SecurityWarningViewTestSetup(private val composeTestRule: ComposeContentTe
|
|||
onConfirm = {
|
||||
onConfirmCount.incrementAndGet()
|
||||
},
|
||||
versionInfo = VersionInfo.new(
|
||||
getAppContext().packageManager.getPackageInfoCompat(getAppContext().packageName, 0L)
|
||||
)
|
||||
versionInfo = VersionInfoFixture.new()
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,9 @@ internal fun MainActivity.Navigation() {
|
|||
WrapSettings(
|
||||
goBack = {
|
||||
navController.popBackStackJustOnce(SETTINGS)
|
||||
},
|
||||
goAbout = {
|
||||
navController.navigateJustOnce(ABOUT)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package co.electriccoin.zcash.ui.common.model
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.ApplicationInfo
|
||||
import co.electriccoin.zcash.build.gitCommitCount
|
||||
import co.electriccoin.zcash.build.gitSha
|
||||
import co.electriccoin.zcash.spackle.EmulatorWtfUtil
|
||||
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
||||
import co.electriccoin.zcash.spackle.getPackageInfoCompat
|
||||
import co.electriccoin.zcash.spackle.versionCodeCompat
|
||||
|
||||
data class VersionInfo(
|
||||
val versionName: String,
|
||||
val versionCode: Long,
|
||||
val isDebuggable: Boolean,
|
||||
val gitSha: String,
|
||||
val gitCommitCount: Long
|
||||
) {
|
||||
companion object {
|
||||
fun new(context: Context): VersionInfo {
|
||||
val packageInfo = context.packageManager.getPackageInfoCompat(context.packageName, 0L)
|
||||
val applicationInfo = context.applicationInfo
|
||||
|
||||
return VersionInfo(
|
||||
versionName = packageInfo.versionName ?: "null", // Should only be null during tests
|
||||
versionCode = packageInfo.versionCodeCompat, // Should only be 0 during tests
|
||||
isDebuggable = (
|
||||
(0 != applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) &&
|
||||
!FirebaseTestLabUtil.isFirebaseTestLab(context.applicationContext) &&
|
||||
!EmulatorWtfUtil.isEmulatorWtf(context.applicationContext)
|
||||
),
|
||||
gitSha = gitSha,
|
||||
gitCommitCount = gitCommitCount.toLong()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +1,27 @@
|
|||
package co.electriccoin.zcash.ui.fixture
|
||||
|
||||
import co.electriccoin.zcash.ui.screen.about.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||
|
||||
// Magic Number doesn't matter here for hard-coded fixture values
|
||||
@Suppress("MagicNumber")
|
||||
object VersionInfoFixture {
|
||||
const val VERSION_NAME = "1.0.3"
|
||||
const val VERSION_CODE = 3L
|
||||
const val VERSION_NAME = "1.0.0"
|
||||
const val VERSION_CODE = 1L
|
||||
const val IS_DEBUGGABLE = false
|
||||
const val GIT_SHA = "635dac0eb9ddc2bc6da5177f0dd495d8b76af4dc"
|
||||
const val GIT_COMMIT_COUNT = 1L
|
||||
|
||||
fun new(
|
||||
versionName: String = VERSION_NAME,
|
||||
versionCode: Long = VERSION_CODE
|
||||
) = VersionInfo(versionName, versionCode)
|
||||
versionCode: Long = VERSION_CODE,
|
||||
isDebuggable: Boolean = IS_DEBUGGABLE,
|
||||
gitSha: String = GIT_SHA,
|
||||
gitCommitCount: Long = GIT_COMMIT_COUNT
|
||||
) = VersionInfo(
|
||||
versionName,
|
||||
versionCode,
|
||||
isDebuggable,
|
||||
gitSha,
|
||||
gitCommitCount
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package co.electriccoin.zcash.ui.screen.about
|
||||
|
||||
/**
|
||||
* These are only used for automated testing.
|
||||
*/
|
||||
object AboutTag {
|
||||
const val DEBUG_MENU_TAG = "debug_menu"
|
||||
}
|
|
@ -6,9 +6,8 @@ import androidx.activity.ComponentActivity
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import co.electriccoin.zcash.configuration.AndroidConfigurationFactory
|
||||
import co.electriccoin.zcash.spackle.getPackageInfoCompat
|
||||
import co.electriccoin.zcash.ui.MainActivity
|
||||
import co.electriccoin.zcash.ui.screen.about.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.screen.about.view.About
|
||||
import co.electriccoin.zcash.ui.screen.support.model.ConfigInfo
|
||||
|
||||
|
@ -24,13 +23,17 @@ internal fun WrapAbout(
|
|||
activity: ComponentActivity,
|
||||
goBack: () -> Unit
|
||||
) {
|
||||
val packageInfo = activity.packageManager.getPackageInfoCompat(activity.packageName, 0L)
|
||||
val configurationProvider = AndroidConfigurationFactory.getInstance(activity.applicationContext)
|
||||
|
||||
About(VersionInfo.new(packageInfo), ConfigInfo.new(configurationProvider), goBack)
|
||||
val configInfo = ConfigInfo.new(AndroidConfigurationFactory.getInstance(activity.applicationContext))
|
||||
val versionInfo = VersionInfo.new(activity.applicationContext)
|
||||
|
||||
// Allows an implicit way to force configuration refresh by simply visiting the About screen
|
||||
LaunchedEffect(key1 = true) {
|
||||
AndroidConfigurationFactory.getInstance(activity.applicationContext).hintToRefresh()
|
||||
}
|
||||
|
||||
About(
|
||||
onBack = goBack,
|
||||
versionInfo = versionInfo,
|
||||
configInfo = configInfo
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package co.electriccoin.zcash.ui.screen.about.model
|
||||
|
||||
import android.content.pm.PackageInfo
|
||||
import co.electriccoin.zcash.spackle.versionCodeCompat
|
||||
|
||||
data class VersionInfo(val versionName: String, val versionCode: Long) {
|
||||
companion object {
|
||||
fun new(packageInfo: PackageInfo) = VersionInfo(
|
||||
packageInfo.versionName ?: "null", // Should only be null during tests
|
||||
packageInfo.versionCodeCompat
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,34 +1,47 @@
|
|||
package co.electriccoin.zcash.ui.screen.about.view
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import co.electriccoin.zcash.build.gitSha
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.design.component.Body
|
||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.design.component.GradientSurface
|
||||
import co.electriccoin.zcash.ui.design.component.Header
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.fixture.ConfigInfoFixture
|
||||
import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
|
||||
import co.electriccoin.zcash.ui.screen.about.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.screen.about.AboutTag
|
||||
import co.electriccoin.zcash.ui.screen.support.model.ConfigInfo
|
||||
|
||||
@Preview("About")
|
||||
|
@ -37,9 +50,9 @@ private fun AboutPreview() {
|
|||
ZcashTheme(darkTheme = false) {
|
||||
GradientSurface {
|
||||
About(
|
||||
onBack = {},
|
||||
versionInfo = VersionInfoFixture.new(),
|
||||
configInfo = ConfigInfoFixture.new(),
|
||||
goBack = {}
|
||||
configInfo = ConfigInfoFixture.new()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -47,16 +60,19 @@ private fun AboutPreview() {
|
|||
|
||||
@Composable
|
||||
fun About(
|
||||
onBack: () -> Unit,
|
||||
versionInfo: VersionInfo,
|
||||
configInfo: ConfigInfo,
|
||||
goBack: () -> Unit
|
||||
configInfo: ConfigInfo
|
||||
) {
|
||||
Scaffold(topBar = {
|
||||
AboutTopAppBar(onBack = goBack)
|
||||
AboutTopAppBar(
|
||||
onBack = onBack,
|
||||
versionInfo = versionInfo,
|
||||
configInfo = configInfo
|
||||
)
|
||||
}) { paddingValues ->
|
||||
AboutMainContent(
|
||||
versionInfo,
|
||||
configInfo,
|
||||
versionInfo = versionInfo,
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
.verticalScroll(
|
||||
|
@ -65,8 +81,8 @@ fun About(
|
|||
.padding(
|
||||
top = paddingValues.calculateTopPadding() + ZcashTheme.dimens.spacingDefault,
|
||||
bottom = paddingValues.calculateBottomPadding() + ZcashTheme.dimens.spacingDefault,
|
||||
start = ZcashTheme.dimens.spacingDefault,
|
||||
end = ZcashTheme.dimens.spacingDefault
|
||||
start = ZcashTheme.dimens.spacingHuge,
|
||||
end = ZcashTheme.dimens.spacingHuge
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -74,52 +90,122 @@ fun About(
|
|||
|
||||
@Composable
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
private fun AboutTopAppBar(onBack: () -> Unit) {
|
||||
TopAppBar(
|
||||
title = { Text(text = stringResource(id = R.string.about_title)) },
|
||||
private fun AboutTopAppBar(
|
||||
onBack: () -> Unit,
|
||||
versionInfo: VersionInfo,
|
||||
configInfo: ConfigInfo
|
||||
) {
|
||||
CenterAlignedTopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.about_title).uppercase(),
|
||||
style = ZcashTheme.typography.primary.titleSmall,
|
||||
color = ZcashTheme.colors.screenTitleColor
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = onBack
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.ArrowBack,
|
||||
contentDescription = stringResource(R.string.about_back_content_description)
|
||||
IconButton(
|
||||
onClick = onBack
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.ArrowBack,
|
||||
contentDescription = stringResource(R.string.about_back_content_description)
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = stringResource(id = R.string.about_back).uppercase(),
|
||||
style = ZcashTheme.typography.primary.bodyMedium
|
||||
)
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
if (versionInfo.isDebuggable) {
|
||||
DebugMenu(versionInfo, configInfo)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DebugMenu(
|
||||
versionInfo: VersionInfo,
|
||||
configInfo: ConfigInfo
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.testTag(AboutTag.DEBUG_MENU_TAG)
|
||||
) {
|
||||
var expanded by rememberSaveable { mutableStateOf(false) }
|
||||
IconButton(onClick = { expanded = true }) {
|
||||
Icon(Icons.Default.MoreVert, contentDescription = null)
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false }
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Column {
|
||||
Text(stringResource(R.string.about_debug_menu_build, versionInfo.gitSha))
|
||||
Text(configInfo.toSupportString())
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AboutMainContent(
|
||||
versionInfo: VersionInfo,
|
||||
configInfo: ConfigInfo,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(modifier) {
|
||||
Icon(painterResource(id = R.drawable.zashi_logo), contentDescription = null)
|
||||
Text(stringResource(id = R.string.app_name))
|
||||
|
||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
|
||||
|
||||
Header(stringResource(id = R.string.about_version_header))
|
||||
Body(stringResource(R.string.about_version_format, versionInfo.versionName, versionInfo.versionCode))
|
||||
|
||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
|
||||
|
||||
Header(stringResource(id = R.string.about_build_header))
|
||||
Body(gitSha)
|
||||
|
||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
|
||||
|
||||
configInfo.configurationUpdatedAt?.let { updatedAt ->
|
||||
Header(stringResource(id = R.string.about_build_configuration))
|
||||
Body(updatedAt.toString())
|
||||
val logoContentDescription = stringResource(R.string.about_app_logo_content_description)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.semantics(mergeDescendants = true) {
|
||||
contentDescription = logoContentDescription
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.zashi_logo_without_text),
|
||||
contentDescription = null,
|
||||
Modifier
|
||||
.height(ZcashTheme.dimens.zcashLogoHeight)
|
||||
.width(ZcashTheme.dimens.zcashLogoWidth)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingDefault))
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.zashi_text_logo),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.height(ZcashTheme.dimens.zcashTextLogoHeight)
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
|
||||
|
||||
Header(stringResource(id = R.string.about_legal_header))
|
||||
Body(stringResource(id = R.string.about_legal_info))
|
||||
Text(
|
||||
text = stringResource(
|
||||
R.string.about_version_format,
|
||||
versionInfo.versionName,
|
||||
versionInfo.versionCode
|
||||
),
|
||||
style = ZcashTheme.typography.primary.titleSmall
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.about_description),
|
||||
color = ZcashTheme.colors.aboutTextColor,
|
||||
style = ZcashTheme.extendedTypography.aboutText
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,7 @@ import androidx.compose.material3.DrawerValue
|
|||
import androidx.compose.material3.rememberDrawerState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import co.electriccoin.zcash.spackle.EmulatorWtfUtil
|
||||
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
||||
import co.electriccoin.zcash.ui.BuildConfig
|
||||
import co.electriccoin.zcash.ui.MainActivity
|
||||
import co.electriccoin.zcash.ui.common.closeDrawerMenu
|
||||
import co.electriccoin.zcash.ui.configuration.ConfigurationEntries
|
||||
|
@ -86,23 +82,14 @@ internal fun WrapHome(
|
|||
if (null == walletSnapshot) {
|
||||
// Display loading indicator
|
||||
} else {
|
||||
val context = LocalContext.current
|
||||
|
||||
// We might eventually want to check the debuggable property of the manifest instead
|
||||
// of relying on BuildConfig.
|
||||
val isDebugMenuEnabled = BuildConfig.DEBUG &&
|
||||
!FirebaseTestLabUtil.isFirebaseTestLab(context) &&
|
||||
!EmulatorWtfUtil.isEmulatorWtf(context)
|
||||
|
||||
val drawerValues = drawerBackHandler()
|
||||
|
||||
Home(
|
||||
walletSnapshot,
|
||||
walletSnapshot = walletSnapshot,
|
||||
isUpdateAvailable = updateAvailable,
|
||||
isKeepScreenOnDuringSync = isKeepScreenOnWhileSyncing,
|
||||
isFiatConversionEnabled = isFiatConversionEnabled,
|
||||
isCircularProgressBarEnabled = isCircularProgressBarEnabled,
|
||||
isDebugMenuEnabled = isDebugMenuEnabled,
|
||||
goSeedPhrase = goSeedPhrase,
|
||||
goSettings = goSettings,
|
||||
goSupport = goSupport,
|
||||
|
@ -110,9 +97,6 @@ internal fun WrapHome(
|
|||
goReceive = goReceive,
|
||||
goSend = goSend,
|
||||
goHistory = goHistory,
|
||||
resetSdk = {
|
||||
walletViewModel.resetSdk()
|
||||
},
|
||||
drawerState = drawerValues.drawerState,
|
||||
scope = drawerValues.scope
|
||||
)
|
||||
|
|
|
@ -19,14 +19,11 @@ import androidx.compose.material.icons.Icons
|
|||
import androidx.compose.material.icons.filled.ContactSupport
|
||||
import androidx.compose.material.icons.filled.Info
|
||||
import androidx.compose.material.icons.filled.Menu
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material.icons.filled.Password
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.DrawerState
|
||||
import androidx.compose.material3.DrawerValue
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
|
@ -40,9 +37,7 @@ import androidx.compose.material3.TopAppBar
|
|||
import androidx.compose.material3.rememberDrawerState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
@ -56,7 +51,6 @@ import androidx.compose.ui.unit.dp
|
|||
import cash.z.ecc.android.sdk.Synchronizer
|
||||
import cash.z.ecc.android.sdk.model.FiatCurrencyConversionRateState
|
||||
import cash.z.ecc.android.sdk.model.PercentDecimal
|
||||
import co.electriccoin.zcash.crash.android.GlobalCrashReporter
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.common.DisableScreenTimeout
|
||||
import co.electriccoin.zcash.ui.common.closeDrawerMenu
|
||||
|
@ -83,7 +77,6 @@ private fun ComposablePreview() {
|
|||
walletSnapshot = WalletSnapshotFixture.new(),
|
||||
isUpdateAvailable = false,
|
||||
isKeepScreenOnDuringSync = false,
|
||||
isDebugMenuEnabled = false,
|
||||
isFiatConversionEnabled = false,
|
||||
isCircularProgressBarEnabled = false,
|
||||
goSeedPhrase = {},
|
||||
|
@ -93,7 +86,6 @@ private fun ComposablePreview() {
|
|||
goReceive = {},
|
||||
goSend = {},
|
||||
goHistory = {},
|
||||
resetSdk = {},
|
||||
drawerState = rememberDrawerState(DrawerValue.Closed),
|
||||
scope = rememberCoroutineScope()
|
||||
)
|
||||
|
@ -109,7 +101,6 @@ fun Home(
|
|||
isKeepScreenOnDuringSync: Boolean?,
|
||||
isFiatConversionEnabled: Boolean,
|
||||
isCircularProgressBarEnabled: Boolean,
|
||||
isDebugMenuEnabled: Boolean,
|
||||
goSeedPhrase: () -> Unit,
|
||||
goSettings: () -> Unit,
|
||||
goSupport: () -> Unit,
|
||||
|
@ -117,7 +108,6 @@ fun Home(
|
|||
goReceive: () -> Unit,
|
||||
goSend: () -> Unit,
|
||||
goHistory: () -> Unit,
|
||||
resetSdk: () -> Unit,
|
||||
drawerState: DrawerState,
|
||||
scope: CoroutineScope
|
||||
) {
|
||||
|
@ -135,9 +125,7 @@ fun Home(
|
|||
content = {
|
||||
Scaffold(topBar = {
|
||||
HomeTopAppBar(
|
||||
isDebugMenuEnabled = isDebugMenuEnabled,
|
||||
openDrawer = { drawerState.openDrawerMenu(scope) },
|
||||
resetSdk = resetSdk
|
||||
openDrawer = { drawerState.openDrawerMenu(scope) }
|
||||
)
|
||||
}) { paddingValues ->
|
||||
HomeMainContent(
|
||||
|
@ -164,9 +152,7 @@ fun Home(
|
|||
@Composable
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
private fun HomeTopAppBar(
|
||||
isDebugMenuEnabled: Boolean,
|
||||
openDrawer: () -> Unit,
|
||||
resetSdk: () -> Unit,
|
||||
openDrawer: () -> Unit
|
||||
) {
|
||||
TopAppBar(
|
||||
title = { Text(text = stringResource(id = R.string.app_name)) },
|
||||
|
@ -180,59 +166,10 @@ private fun HomeTopAppBar(
|
|||
contentDescription = stringResource(R.string.home_menu_content_description)
|
||||
)
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
if (isDebugMenuEnabled) {
|
||||
DebugMenu(resetSdk)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DebugMenu(
|
||||
resetSdk: () -> Unit
|
||||
) {
|
||||
Column {
|
||||
var expanded by rememberSaveable { mutableStateOf(false) }
|
||||
IconButton(onClick = { expanded = true }) {
|
||||
Icon(Icons.Default.MoreVert, contentDescription = null)
|
||||
}
|
||||
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false }
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = { Text("Throw Uncaught Exception") },
|
||||
onClick = {
|
||||
// Supposed to be generic, for manual debugging only
|
||||
@Suppress("TooGenericExceptionThrown")
|
||||
throw RuntimeException("Manually crashed from debug menu")
|
||||
}
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text("Report Caught Exception") },
|
||||
onClick = {
|
||||
// Eventually this shouldn't rely on the Android implementation, but rather an expect/actual
|
||||
// should be used at the crash API level.
|
||||
GlobalCrashReporter.reportCaughtException(
|
||||
RuntimeException("Manually caught exception from debug menu")
|
||||
)
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text("Reset SDK") },
|
||||
onClick = {
|
||||
resetSdk()
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HomeDrawer(
|
||||
onCloseDrawer: () -> Unit,
|
||||
|
|
|
@ -6,7 +6,6 @@ import android.content.Context
|
|||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.viewModels
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import cash.z.ecc.android.sdk.WalletInitMode
|
||||
import cash.z.ecc.android.sdk.fixture.WalletFixture
|
||||
|
@ -17,10 +16,9 @@ import cash.z.ecc.android.sdk.model.ZcashNetwork
|
|||
import cash.z.ecc.android.sdk.model.defaultForNetwork
|
||||
import cash.z.ecc.sdk.type.fromResources
|
||||
import co.electriccoin.lightwallet.client.model.LightWalletEndpoint
|
||||
import co.electriccoin.zcash.spackle.EmulatorWtfUtil
|
||||
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
||||
import co.electriccoin.zcash.ui.BuildConfig
|
||||
import co.electriccoin.zcash.ui.MainActivity
|
||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.configuration.ConfigurationEntries
|
||||
import co.electriccoin.zcash.ui.configuration.RemoteConfig
|
||||
import co.electriccoin.zcash.ui.screen.home.model.OnboardingState
|
||||
|
@ -43,13 +41,7 @@ internal fun WrapOnboarding(
|
|||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||
val onboardingViewModel by activity.viewModels<OnboardingViewModel>()
|
||||
|
||||
val applicationContext = LocalContext.current.applicationContext
|
||||
|
||||
// We might eventually want to check the debuggable property of the manifest instead
|
||||
// of relying on BuildConfig.
|
||||
val isDebugMenuEnabled = BuildConfig.DEBUG &&
|
||||
!FirebaseTestLabUtil.isFirebaseTestLab(applicationContext) &&
|
||||
!EmulatorWtfUtil.isEmulatorWtf(applicationContext)
|
||||
val versionInfo = VersionInfo.new(activity.applicationContext)
|
||||
|
||||
// TODO [#383]: https://github.com/zcash/secant-android-wallet/issues/383
|
||||
// TODO [#383]: Refactoring of UI state retention into rememberSaveable fields
|
||||
|
@ -63,12 +55,12 @@ internal fun WrapOnboarding(
|
|||
// Firebase Test Lab or Google Play pre-launch report, we want to skip creating
|
||||
// a new or restoring an existing wallet screens by persisting an existing wallet
|
||||
// with a mock seed.
|
||||
if (FirebaseTestLabUtil.isFirebaseTestLab(applicationContext)) {
|
||||
if (FirebaseTestLabUtil.isFirebaseTestLab(activity.applicationContext)) {
|
||||
persistExistingWalletWithSeedPhrase(
|
||||
applicationContext,
|
||||
activity.applicationContext,
|
||||
walletViewModel,
|
||||
SeedPhrase.new(WalletFixture.Alice.seedPhrase),
|
||||
birthday = WalletFixture.Alice.getBirthday(ZcashNetwork.fromResources(applicationContext))
|
||||
birthday = WalletFixture.Alice.getBirthday(ZcashNetwork.fromResources(activity.applicationContext))
|
||||
)
|
||||
} else {
|
||||
onboardingViewModel.setIsImporting(true)
|
||||
|
@ -79,10 +71,10 @@ internal fun WrapOnboarding(
|
|||
|
||||
val onFixtureWallet = {
|
||||
persistExistingWalletWithSeedPhrase(
|
||||
applicationContext,
|
||||
activity.applicationContext,
|
||||
walletViewModel,
|
||||
SeedPhrase.new(WalletFixture.Alice.seedPhrase),
|
||||
birthday = WalletFixture.Alice.getBirthday(ZcashNetwork.fromResources(applicationContext))
|
||||
birthday = WalletFixture.Alice.getBirthday(ZcashNetwork.fromResources(activity.applicationContext))
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -100,7 +92,7 @@ internal fun WrapOnboarding(
|
|||
} else {
|
||||
LongOnboarding(
|
||||
onboardingState = onboardingViewModel.onboardingState,
|
||||
isDebugMenuEnabled = isDebugMenuEnabled,
|
||||
isDebugMenuEnabled = versionInfo.isDebuggable,
|
||||
onImportWallet = onImportWallet,
|
||||
onCreateWallet = onCreateWallet,
|
||||
onFixtureWallet = onFixtureWallet
|
||||
|
|
|
@ -8,10 +8,9 @@ import androidx.compose.runtime.LaunchedEffect
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import co.electriccoin.zcash.configuration.AndroidConfigurationFactory
|
||||
import co.electriccoin.zcash.spackle.getPackageInfoCompat
|
||||
import co.electriccoin.zcash.ui.MainActivity
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.screen.about.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.screen.securitywarning.util.WebBrowserUtil
|
||||
import co.electriccoin.zcash.ui.screen.securitywarning.view.SecurityWarning
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
@ -35,14 +34,12 @@ internal fun WrapSecurityWarning(
|
|||
onBack: () -> Unit,
|
||||
onConfirm: () -> Unit
|
||||
) {
|
||||
val packageInfo = activity.packageManager.getPackageInfoCompat(activity.packageName, 0L)
|
||||
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
SecurityWarning(
|
||||
snackbarHostState = snackbarHostState,
|
||||
versionInfo = VersionInfo.new(packageInfo),
|
||||
versionInfo = VersionInfo.new(activity.applicationContext),
|
||||
onBack = onBack,
|
||||
onAcknowledged = {
|
||||
// Needed for UI testing only
|
||||
|
|
|
@ -36,13 +36,13 @@ import androidx.compose.ui.text.style.TextDecoration
|
|||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT
|
||||
import co.electriccoin.zcash.ui.design.component.CheckBox
|
||||
import co.electriccoin.zcash.ui.design.component.GradientSurface
|
||||
import co.electriccoin.zcash.ui.design.component.PrimaryButton
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
|
||||
import co.electriccoin.zcash.ui.screen.about.model.VersionInfo
|
||||
|
||||
@Preview("Security Warning")
|
||||
@Composable
|
||||
|
|
|
@ -6,8 +6,8 @@ import androidx.activity.ComponentActivity
|
|||
import androidx.activity.viewModels
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import co.electriccoin.zcash.ui.BuildConfig
|
||||
import co.electriccoin.zcash.ui.MainActivity
|
||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||
import co.electriccoin.zcash.ui.configuration.ConfigurationEntries
|
||||
import co.electriccoin.zcash.ui.configuration.RemoteConfig
|
||||
import co.electriccoin.zcash.ui.screen.home.viewmodel.WalletViewModel
|
||||
|
@ -17,11 +17,13 @@ import co.electriccoin.zcash.ui.screen.settings.viewmodel.SettingsViewModel
|
|||
|
||||
@Composable
|
||||
internal fun MainActivity.WrapSettings(
|
||||
goBack: () -> Unit
|
||||
goBack: () -> Unit,
|
||||
goAbout: () -> Unit,
|
||||
) {
|
||||
WrapSettings(
|
||||
activity = this,
|
||||
goBack = goBack,
|
||||
goAbout = goAbout
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -29,10 +31,13 @@ internal fun MainActivity.WrapSettings(
|
|||
private fun WrapSettings(
|
||||
activity: ComponentActivity,
|
||||
goBack: () -> Unit,
|
||||
goAbout: () -> Unit,
|
||||
) {
|
||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||
val settingsViewModel by activity.viewModels<SettingsViewModel>()
|
||||
|
||||
val versionInfo = VersionInfo.new(activity.applicationContext)
|
||||
|
||||
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
|
||||
val isBackgroundSyncEnabled = settingsViewModel.isBackgroundSync.collectAsStateWithLifecycle().value
|
||||
val isKeepScreenOnWhileSyncing = settingsViewModel.isKeepScreenOnWhileSyncing.collectAsStateWithLifecycle().value
|
||||
|
@ -48,7 +53,7 @@ private fun WrapSettings(
|
|||
} else {
|
||||
Settings(
|
||||
TroubleshootingParameters(
|
||||
isEnabled = BuildConfig.DEBUG,
|
||||
isEnabled = versionInfo.isDebuggable,
|
||||
isBackgroundSyncEnabled = isBackgroundSyncEnabled,
|
||||
isKeepScreenOnDuringSyncEnabled = isKeepScreenOnWhileSyncing,
|
||||
isAnalyticsEnabled = isAnalyticsEnabled,
|
||||
|
@ -59,7 +64,7 @@ private fun WrapSettings(
|
|||
onDocumentation = {},
|
||||
onPrivacyPolicy = {},
|
||||
onFeedback = {},
|
||||
onAbout = {},
|
||||
onAbout = goAbout,
|
||||
onRescanWallet = {
|
||||
walletViewModel.rescanBlockchain()
|
||||
},
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="about_title">About</string>
|
||||
<string name="about_back">Back</string>
|
||||
<string name="about_back_content_description">Back</string>
|
||||
<string name="about_icon_content_description">Zcash icon</string>
|
||||
<string name="about_version_header">Version</string>
|
||||
<string name="about_version_format" formatted="true"><xliff:g id="version_name" example="1.0">%1$s</xliff:g> (<xliff:g id="version_code" example="1.0">%2$d</xliff:g>)</string>
|
||||
<string name="about_build_header">Build</string>
|
||||
<string name="about_build_configuration">Configuration</string>
|
||||
<string name="about_legal_header">Legal</string>
|
||||
<!-- TODO [#392] Update with real legal info. -->
|
||||
<!-- TODO [#392] https://github.com/zcash/secant-android-wallet/issues/392 -->
|
||||
<string name="about_legal_info">GitHub Issue #392</string>
|
||||
<string name="about_app_logo_content_description">Zcash logo</string>
|
||||
<string name="about_version_format" formatted="true">Version <xliff:g example="1.0" id="version_name">%1$s
|
||||
</xliff:g> (<xliff:g example="1.0" id="version_code">%2$d</xliff:g>)</string>
|
||||
<string name="about_debug_menu_build">Build: <xliff:g example="635dac0eb9ddc2bc6da5177f0dd495d8b76af4dc"
|
||||
id="git_commit_hash">%1$s</xliff:g></string>
|
||||
<string name="about_description">Send and receive ZEC on Zashi! Zashi is a minimal-design, self-custody, ZEC-only
|
||||
shielded wallet that keeps your transaction history and wallet balance private. Built by Zcashers, for
|
||||
Zcashers. Developed and maintained by Electric Coin Co., the inventor of Zcash, Zashi features a built-in
|
||||
user-feedback mechanism to enable more features, more quickly.</string>
|
||||
</resources>
|
||||
|
|
|
@ -680,7 +680,9 @@ private fun supportScreenshots(resContext: Context, tag: String, composeTestRule
|
|||
}
|
||||
|
||||
private fun aboutScreenshots(resContext: Context, tag: String, composeTestRule: ComposeTestRule) {
|
||||
composeTestRule.onNode(hasText(resContext.getString(R.string.about_title))).also {
|
||||
composeTestRule.onNode(
|
||||
hasText(resContext.getString(R.string.about_title).uppercase())
|
||||
).also {
|
||||
it.assertExists()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue