169 lines
6.4 KiB
Kotlin
169 lines
6.4 KiB
Kotlin
package co.electriccoin.zcash.ui.screen.profile.view
|
|
|
|
import androidx.compose.foundation.Image
|
|
import androidx.compose.foundation.layout.Column
|
|
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.material3.Divider
|
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
import androidx.compose.material3.Icon
|
|
import androidx.compose.material3.IconButton
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.material3.TopAppBar
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.platform.LocalDensity
|
|
import androidx.compose.ui.res.stringResource
|
|
import androidx.compose.ui.text.style.TextOverflow
|
|
import androidx.compose.ui.tooling.preview.Preview
|
|
import androidx.compose.ui.unit.Dp
|
|
import androidx.compose.ui.unit.dp
|
|
import cash.z.ecc.android.sdk.fixture.WalletAddressFixture
|
|
import cash.z.ecc.android.sdk.model.WalletAddress
|
|
import co.electriccoin.zcash.ui.R
|
|
import co.electriccoin.zcash.ui.common.BrightenScreen
|
|
import co.electriccoin.zcash.ui.common.DisableScreenTimeout
|
|
import co.electriccoin.zcash.ui.design.component.Body
|
|
import co.electriccoin.zcash.ui.design.component.GradientSurface
|
|
import co.electriccoin.zcash.ui.design.component.PrimaryButton
|
|
import co.electriccoin.zcash.ui.design.component.TertiaryButton
|
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
|
import co.electriccoin.zcash.ui.screen.profile.util.AndroidQrCodeImageGenerator
|
|
import co.electriccoin.zcash.ui.screen.profile.util.JvmQrCodeGenerator
|
|
import co.electriccoin.zcash.ui.screen.profile.util.ProfileConfiguration
|
|
import kotlinx.coroutines.runBlocking
|
|
import kotlin.math.roundToInt
|
|
|
|
@Preview
|
|
@Composable
|
|
fun ComposablePreview() {
|
|
ZcashTheme(darkTheme = true) {
|
|
GradientSurface {
|
|
Profile(
|
|
walletAddress = runBlocking { WalletAddressFixture.unified() },
|
|
onBack = {},
|
|
onAddressDetails = {},
|
|
onAddressBook = {},
|
|
onSettings = {},
|
|
onCoinholderVote = {},
|
|
onSupport = {},
|
|
onAbout = {}
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
@Suppress("LongParameterList")
|
|
fun Profile(
|
|
walletAddress: WalletAddress,
|
|
onBack: () -> Unit,
|
|
onAddressDetails: () -> Unit,
|
|
onAddressBook: () -> Unit,
|
|
onSettings: () -> Unit,
|
|
onCoinholderVote: () -> Unit,
|
|
onSupport: () -> Unit,
|
|
onAbout: () -> Unit
|
|
) {
|
|
Column {
|
|
ProfileTopAppBar(onBack = onBack)
|
|
ProfileContents(
|
|
walletAddress = walletAddress,
|
|
onAddressDetails = onAddressDetails,
|
|
onAddressBook = onAddressBook,
|
|
onSettings = onSettings,
|
|
onCoinholderVote = onCoinholderVote,
|
|
onSupport = onSupport,
|
|
onAbout = onAbout,
|
|
isAddressBookEnabled = ProfileConfiguration.IS_ADDRESS_BOOK_ENABLED,
|
|
isCoinholderVoteEnabled = ProfileConfiguration.IS_COINHOLDER_VOTE_ENABLED
|
|
)
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
@OptIn(ExperimentalMaterial3Api::class)
|
|
private fun ProfileTopAppBar(onBack: () -> Unit) {
|
|
TopAppBar(
|
|
title = { Text(text = stringResource(id = R.string.profile_title)) },
|
|
navigationIcon = {
|
|
IconButton(
|
|
onClick = onBack
|
|
) {
|
|
Icon(
|
|
imageVector = Icons.Filled.ArrowBack,
|
|
contentDescription = stringResource(R.string.profile_back_content_description)
|
|
)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
private val DEFAULT_QR_CODE_SIZE = 320.dp
|
|
|
|
@Composable
|
|
@Suppress("LongParameterList")
|
|
private fun ProfileContents(
|
|
walletAddress: WalletAddress,
|
|
onAddressDetails: () -> Unit,
|
|
onAddressBook: () -> Unit,
|
|
onSettings: () -> Unit,
|
|
onCoinholderVote: () -> Unit,
|
|
onSupport: () -> Unit,
|
|
onAbout: () -> Unit,
|
|
isAddressBookEnabled: Boolean,
|
|
isCoinholderVoteEnabled: Boolean
|
|
) {
|
|
Column(Modifier.verticalScroll(rememberScrollState())) {
|
|
QrCode(data = walletAddress.address, DEFAULT_QR_CODE_SIZE, Modifier.align(Alignment.CenterHorizontally))
|
|
Body(text = stringResource(id = R.string.wallet_address_unified), Modifier.align(Alignment.CenterHorizontally))
|
|
// TODO [#163]: Ellipsize center of the string
|
|
// TODO [#163]: https://github.com/zcash/secant-android-wallet/issues/163
|
|
Text(
|
|
text = walletAddress.address,
|
|
style = MaterialTheme.typography.headlineLarge,
|
|
color = MaterialTheme.colorScheme.onBackground,
|
|
modifier = Modifier.align(Alignment.CenterHorizontally),
|
|
overflow = TextOverflow.Ellipsis,
|
|
maxLines = 1
|
|
)
|
|
PrimaryButton(onClick = onAddressDetails, text = stringResource(id = R.string.profile_see_address_details))
|
|
if (isAddressBookEnabled) {
|
|
TertiaryButton(onClick = onAddressBook, text = stringResource(id = R.string.profile_address_book))
|
|
}
|
|
TertiaryButton(onClick = onSettings, text = stringResource(id = R.string.profile_settings))
|
|
Divider()
|
|
if (isCoinholderVoteEnabled) {
|
|
TertiaryButton(onClick = onCoinholderVote, text = stringResource(id = R.string.profile_coinholder_vote))
|
|
}
|
|
TertiaryButton(onClick = onSupport, text = stringResource(id = R.string.profile_support))
|
|
TertiaryButton(onClick = onAbout, text = stringResource(id = R.string.profile_about))
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
private fun QrCode(data: String, size: Dp, modifier: Modifier) {
|
|
BrightenScreen()
|
|
DisableScreenTimeout()
|
|
val sizePixels = with(LocalDensity.current) { size.toPx() }.roundToInt()
|
|
|
|
// In the future, use actual/expect to switch QR code generator implementations for multiplatform
|
|
|
|
// Note that our implementation has an extra array copy to BooleanArray, which is a cross-platform
|
|
// representation. This should have minimal performance impact since the QR code is relatively
|
|
// small and we only generate QR codes infrequently.
|
|
|
|
val qrCodePixelArray = JvmQrCodeGenerator.generate(data, sizePixels)
|
|
val qrCodeImage = AndroidQrCodeImageGenerator.generate(qrCodePixelArray, sizePixels)
|
|
|
|
Image(
|
|
bitmap = qrCodeImage,
|
|
contentDescription = stringResource(R.string.profile_qr_code_content_description),
|
|
modifier = modifier
|
|
)
|
|
}
|