secant-android-wallet/ui-lib/src/main/java/cash/z/ecc/ui/screen/profile/view/ProfileView.kt

155 lines
5.5 KiB
Kotlin
Raw Normal View History

2022-01-13 09:49:08 -08:00
package cash.z.ecc.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
2022-02-21 06:33:40 -08:00
import androidx.compose.material3.Divider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SmallTopAppBar
import androidx.compose.material3.Text
2022-01-13 09:49:08 -08:00
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.sdk.fixture.WalletAddressFixture
import cash.z.ecc.sdk.model.WalletAddress
import cash.z.ecc.ui.R
import cash.z.ecc.ui.design.component.Body
import cash.z.ecc.ui.design.component.GradientSurface
import cash.z.ecc.ui.design.component.PrimaryButton
import cash.z.ecc.ui.design.component.TertiaryButton
2022-01-13 09:49:08 -08:00
import cash.z.ecc.ui.screen.profile.util.AndroidQrCodeImageGenerator
import cash.z.ecc.ui.screen.profile.util.JvmQrCodeGenerator
import cash.z.ecc.ui.theme.ZcashTheme
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 = {}
)
}
}
}
@Composable
@Suppress("LongParameterList")
fun Profile(
walletAddress: WalletAddress,
onBack: () -> Unit,
onAddressDetails: () -> Unit,
onAddressBook: () -> Unit,
onSettings: () -> Unit,
onCoinholderVote: () -> Unit,
onSupport: () -> Unit
) {
Column {
ProfileTopAppBar(onBack)
ProfileContents(
walletAddress = walletAddress,
onAddressDetails = onAddressDetails,
onAddressBook = onAddressBook,
onSettings = onSettings,
onCoinholderVote = onCoinholderVote,
onSupport = onSupport
)
}
}
@Composable
private fun ProfileTopAppBar(onBack: () -> Unit) {
2022-02-21 06:33:40 -08:00
SmallTopAppBar(
2022-01-13 09:49:08 -08:00
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),
2022-02-21 06:33:40 -08:00
tint = MaterialTheme.colorScheme.secondary
2022-01-13 09:49:08 -08:00
)
}
}
)
}
private val DEFAULT_QR_CODE_SIZE = 320.dp
@Composable
@Suppress("LongParameterList")
private fun ProfileContents(
walletAddress: WalletAddress,
onAddressDetails: () -> Unit,
onAddressBook: () -> Unit,
onSettings: () -> Unit,
onCoinholderVote: () -> Unit,
2022-03-08 10:46:43 -08:00
onSupport: () -> Unit,
isAddressBookEnabled: Boolean = false
2022-01-13 09:49:08 -08:00
) {
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
Text(
text = walletAddress.address,
2022-02-21 06:33:40 -08:00
style = MaterialTheme.typography.headlineLarge,
color = MaterialTheme.colorScheme.onBackground,
2022-01-13 09:49:08 -08:00
modifier = Modifier.align(Alignment.CenterHorizontally),
overflow = TextOverflow.Ellipsis
)
PrimaryButton(onClick = onAddressDetails, text = stringResource(id = R.string.profile_see_address_details))
2022-03-08 10:46:43 -08:00
if (isAddressBookEnabled) {
TertiaryButton(onClick = onAddressBook, text = stringResource(id = R.string.profile_address_book))
}
2022-01-13 09:49:08 -08:00
TertiaryButton(onClick = onSettings, text = stringResource(id = R.string.profile_settings))
Divider()
TertiaryButton(onClick = onCoinholderVote, text = stringResource(id = R.string.profile_coinholder_vote))
TertiaryButton(onClick = onSupport, text = stringResource(id = R.string.profile_support))
}
}
@Composable
private fun QrCode(data: String, size: Dp, modifier: Modifier) {
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
)
}