Skip to content

Commit

Permalink
Feature/address book (#1614)
Browse files Browse the repository at this point in the history
* [#1564] Send screen redesign (#1601)

* [#1564] Send screen redesign

Closes #1564
Closes #1580

* [#1564] Test hotfix

Closes #1564
Closes #1580

* [#1564] Test hotfix

* [#1564] Bugfixes and code cleanup

* [#1564] Focus handling

* Address Book UI (#1606)

* Address Book UI

* Design hotfix

* Code cleanup

* Test hotfix

* Confirmation screen redesign (#1602)

* Confirmation screen redesign

* Documentation update

* Design hotfixes

* History item redesign (#1603)

* History item redesign

* Empty Memo message removed

* Hidden fee for a receiving transaction

* Address Book, Add Contact & Update Contact logic (#1610)

* Address Book Screen logic

* Add New Contact screen logic

* Update Contact screen logic

* Code cleanup

* Code cleanup
  • Loading branch information
Milan-Cerovsky authored Oct 3, 2024
1 parent 519b48b commit 1fedce1
Show file tree
Hide file tree
Showing 74 changed files with 2,580 additions and 644 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ and this application adheres to [Semantic Versioning](https://semver.org/spec/v2

### Changed
- The Receive screen UI has been redesigned
- Send screen redesigned
- Confirmation screen redesigned
- History item redesigned

## [1.2 (739)] - 2024-09-27

Expand Down
3 changes: 3 additions & 0 deletions docs/whatsNew/WHATS_NEW_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ directly impact users rather than highlighting other key architectural updates.*

### Changed
- The Receive screen UI has been redesigned
- Send screen redesigned
- Confirmation screen redesigned
- History item redesigned

## [1.2 (739)] - 2024-09-27

Expand Down
13 changes: 13 additions & 0 deletions tools/detekt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ style:
excludes: [ '**/*.kts' ]
ignoreAnnotated:
- 'Preview'
- 'PreviewScreens'

complexity:
LongMethod:
active: true
ignoreAnnotated:
- 'Preview'
- 'PreviewScreens'
LongParameterList:
active: true
ignoreAnnotated:
- 'Preview'
- 'PreviewScreens'

Compose:
ModifierMissing:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ fun TextWithIcon(
textAlign: TextAlign = TextAlign.Start,
style: TextStyle = LocalTextStyle.current,
color: Color = ZcashTheme.colors.textPrimary,
fontWeight: FontWeight? = null,
) {
Row(
modifier =
Expand Down Expand Up @@ -248,6 +249,7 @@ fun TextWithIcon(
overflow = overflow,
textAlign = textAlign,
style = style,
fontWeight = fontWeight
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,6 @@ data class TextFieldState(
val error: StringResource? = null,
val isEnabled: Boolean = true,
val onValueChange: (String) -> Unit,
)
) {
val isError = error != null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package co.electriccoin.zcash.ui.design.component

import androidx.compose.foundation.interaction.InteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.text.selection.TextSelectionColors
import androidx.compose.material3.TextFieldColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.graphics.Color

@Composable
internal fun TextFieldColors.textColor(
enabled: Boolean,
isError: Boolean,
interactionSource: InteractionSource
): State<Color> {
val focused by interactionSource.collectIsFocusedAsState()

val targetValue =
when {
!enabled -> disabledTextColor
isError -> errorTextColor
focused -> focusedTextColor
else -> unfocusedTextColor
}
return rememberUpdatedState(targetValue)
}

internal val TextFieldColors.selectionColors: TextSelectionColors
@Composable get() = textSelectionColors

@Composable
internal fun TextFieldColors.cursorColor(isError: Boolean): State<Color> {
return rememberUpdatedState(if (isError) errorCursorColor else cursorColor)
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ fun ZashiBottomBar(
}
}

@Suppress("UnusedPrivateMember")
@PreviewScreens
@Composable
private fun BottomBarPreview() =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
Expand All @@ -26,100 +30,192 @@ import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography
import co.electriccoin.zcash.ui.design.util.StringResource
import co.electriccoin.zcash.ui.design.util.getValue
import co.electriccoin.zcash.ui.design.util.orDark
import co.electriccoin.zcash.ui.design.util.stringRes

@Composable
fun ZashiSettingsListItem(
state: ButtonState,
text: String,
@DrawableRes icon: Int,
trailing: @Composable () -> Unit = {
Image(
painter = painterResource(R.drawable.ic_chevron_right orDark R.drawable.ic_chevron_right_dark),
contentDescription = state.text.getValue(),
)
}
subtitle: String? = null,
isEnabled: Boolean = true,
onClick: () -> Unit
) {
ZashiSettingsListItem(
text = state.text.getValue(),
state =
ZashiSettingsListItemState(
text = stringRes(text),
subtitle = subtitle?.let { stringRes(it) },
isEnabled = isEnabled,
onClick = onClick
),
icon = icon,
trailing = trailing,
onClick = state.onClick
)
}

@Composable
fun ZashiSettingsListItem(
text: String,
@DrawableRes icon: Int,
trailing: @Composable () -> Unit = {
Image(
painter = painterResource(R.drawable.ic_chevron_right orDark R.drawable.ic_chevron_right_dark),
contentDescription = text,
)
},
onClick: () -> Unit
state: ZashiSettingsListItemState,
@DrawableRes icon: Int
) {
ZashiSettingsListItem(
leading = {
Image(
modifier = Modifier.size(40.dp),
painter = painterResource(icon),
contentDescription = text
leading = { modifier ->
ZashiSettingsListLeadingItem(
modifier = modifier,
icon = icon,
contentDescription = state.text.getValue()
)
},
content = {
Text(
text = text,
style = ZashiTypography.textMd,
fontWeight = FontWeight.SemiBold,
color = ZashiColors.Text.textPrimary
content = { modifier ->
ZashiSettingsListContentItem(
modifier = modifier,
text = state.text.getValue(),
subtitle = state.subtitle?.getValue()
)
},
trailing = trailing,
onClick = onClick
trailing = { modifier ->
ZashiSettingsListTrailingItem(
modifier = modifier,
isEnabled = state.isEnabled,
contentDescription = state.text.getValue()
)
},
onClick = state.onClick.takeIf { state.isEnabled }
)
}

@Composable
fun ZashiSettingsListLeadingItem(
icon: Int,
contentDescription: String,
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier,
contentAlignment = Alignment.Center
) {
Image(
modifier = Modifier.size(40.dp),
painter = painterResource(icon),
contentDescription = contentDescription,
)
}
}

@Composable
fun ZashiSettingsListTrailingItem(
isEnabled: Boolean,
contentDescription: String,
modifier: Modifier = Modifier
) {
if (isEnabled) {
Box(
modifier = modifier,
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(R.drawable.ic_chevron_right orDark R.drawable.ic_chevron_right_dark),
contentDescription = contentDescription,
)
}
}
}

@Composable
fun ZashiSettingsListContentItem(
text: String,
subtitle: String?,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier
) {
Text(
text = text,
style = ZashiTypography.textMd,
fontWeight = FontWeight.SemiBold,
color = ZashiColors.Text.textPrimary
)
subtitle?.let {
Spacer(modifier = Modifier.height(2.dp))
Text(
text = it,
style = ZashiTypography.textXs,
color = ZashiColors.Text.textTertiary
)
}
}
}

@Composable
fun ZashiSettingsListItem(
leading: @Composable () -> Unit,
content: @Composable () -> Unit,
trailing: @Composable () -> Unit,
onClick: () -> Unit
leading: @Composable (Modifier) -> Unit,
content: @Composable (Modifier) -> Unit,
trailing: @Composable (Modifier) -> Unit,
contentPadding: PaddingValues = PaddingValues(vertical = 12.dp),
onClick: (() -> Unit)?
) {
Row(
modifier =
Modifier
.clip(RoundedCornerShape(12.dp))
.clickable(
indication = rememberRipple(),
interactionSource = remember { MutableInteractionSource() },
onClick = onClick,
role = Role.Button,
)
.padding(vertical = 12.dp),
.clip(RoundedCornerShape(12.dp)) then
if (onClick != null) {
Modifier.clickable(
indication = rememberRipple(),
interactionSource = remember { MutableInteractionSource() },
onClick = onClick,
role = Role.Button,
)
} else {
Modifier
} then Modifier.padding(contentPadding),
verticalAlignment = Alignment.CenterVertically
) {
Spacer(modifier = Modifier.width(20.dp))
leading()
leading(Modifier)
Spacer(modifier = Modifier.width(16.dp))
content(Modifier.weight(1f))
Spacer(modifier = Modifier.width(16.dp))
content()
Spacer(modifier = Modifier.weight(1f))
trailing()
trailing(Modifier)
Spacer(modifier = Modifier.width(20.dp))
}
}

data class ZashiSettingsListItemState(
val text: StringResource,
val subtitle: StringResource? = null,
val isEnabled: Boolean = true,
val onClick: () -> Unit = {},
)

@Suppress("UnusedPrivateMember")
@PreviewScreens
@Composable
private fun EnabledPreview() =
ZcashTheme {
BlankSurface {
ZashiSettingsListItem(
text = "Test",
subtitle = "Subtitle",
icon = R.drawable.ic_radio_button_checked,
onClick = {}
)
}
}

@Suppress("UnusedPrivateMember")
@PreviewScreens
@Composable
private fun ZashiSettingsListItemPreview() =
private fun DisabledPreview() =
ZcashTheme {
BlankSurface {
ZashiSettingsListItem(
text = "Test",
subtitle = "Subtitle",
icon = R.drawable.ic_radio_button_checked,
isEnabled = false,
onClick = {}
)
}
Expand Down
Loading

0 comments on commit 1fedce1

Please sign in to comment.