Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Dense account design #3428

Merged
merged 11 commits into from
Aug 26, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ data class AccountsState(
val totalBalanceWithExcludedText: String,
val totalBalanceWithoutExcluded: String,
val totalBalanceWithoutExcludedText: String,
val reorderVisible: Boolean
val reorderVisible: Boolean,
val compactAccountsModeEnabled: Boolean
)
136 changes: 119 additions & 17 deletions screen/accounts/src/main/java/com/ivy/accounts/AccountsTab.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.ivy.base.legacy.Theme
import com.ivy.data.model.Account
import com.ivy.data.model.AccountId
import com.ivy.data.model.primitive.AssetCode
import com.ivy.data.model.primitive.ColorInt
Expand Down Expand Up @@ -151,6 +152,7 @@ private fun BoxWithConstraintsScope.UI(
AccountCard(
baseCurrency = state.baseCurrency,
accountData = it,
compactModeEnabled = state.compactAccountsModeEnabled,
onBalanceClick = {
nav.navigateTo(
TransactionsScreen(
Expand Down Expand Up @@ -202,6 +204,7 @@ private fun BoxWithConstraintsScope.UI(
private fun AccountCard(
baseCurrency: String,
accountData: AccountData,
compactModeEnabled: Boolean,
onBalanceClick: () -> Unit,
onClick: () -> Unit
) {
Expand All @@ -227,17 +230,19 @@ private fun AccountCard(
onBalanceClick = onBalanceClick
)

Spacer(Modifier.height(12.dp))
if (!compactModeEnabled) {
Spacer(Modifier.height(12.dp))

IncomeExpensesRow(
currency = currency,
incomeLabel = stringResource(R.string.month_income),
income = accountData.monthlyIncome,
expensesLabel = stringResource(R.string.month_expenses),
expenses = accountData.monthlyExpenses
)
IncomeExpensesRow(
currency = currency,
incomeLabel = stringResource(R.string.month_income),
income = accountData.monthlyIncome,
expensesLabel = stringResource(R.string.month_expenses),
expenses = accountData.monthlyExpenses
)

Spacer(Modifier.height(12.dp))
Spacer(Modifier.height(12.dp))
}
}
}

Expand Down Expand Up @@ -330,9 +335,9 @@ private fun AccountHeader(

@Preview
@Composable
private fun PreviewAccountsTab(theme: Theme = Theme.LIGHT) {
private fun PreviewAccountsTabCompactModeDisabled(theme: Theme = Theme.LIGHT) {
IvyWalletPreview(theme = theme) {
val acc1 = com.ivy.data.model.Account(
val acc1 = Account(
id = AccountId(UUID.randomUUID()),
name = NotBlankTrimmedString.unsafe("Phyre"),
color = ColorInt(Green.toArgb()),
Expand All @@ -342,7 +347,7 @@ private fun PreviewAccountsTab(theme: Theme = Theme.LIGHT) {
orderNum = 0.0,
)

val acc2 = com.ivy.data.model.Account(
val acc2 = Account(
id = AccountId(UUID.randomUUID()),
name = NotBlankTrimmedString.unsafe("DSK"),
color = ColorInt(GreenLight.toArgb()),
Expand All @@ -352,7 +357,7 @@ private fun PreviewAccountsTab(theme: Theme = Theme.LIGHT) {
orderNum = 0.0,
)

val acc3 = com.ivy.data.model.Account(
val acc3 = Account(
id = AccountId(UUID.randomUUID()),
name = NotBlankTrimmedString.unsafe("Revolut"),
color = ColorInt(Green.toArgb()),
Expand All @@ -362,7 +367,7 @@ private fun PreviewAccountsTab(theme: Theme = Theme.LIGHT) {
orderNum = 0.0,
)

val acc4 = com.ivy.data.model.Account(
val acc4 = Account(
id = AccountId(UUID.randomUUID()),
name = NotBlankTrimmedString.unsafe("Cash"),
color = ColorInt(Green.toArgb()),
Expand Down Expand Up @@ -407,18 +412,115 @@ private fun PreviewAccountsTab(theme: Theme = Theme.LIGHT) {
totalBalanceWithExcludedText = "BGN 25.54",
totalBalanceWithoutExcluded = "25.54",
totalBalanceWithoutExcludedText = "BGN 25.54",
reorderVisible = false
reorderVisible = false,
compactAccountsModeEnabled = false
)
UI(state = state)
}
}

@Preview
@Composable
private fun PreviewAccountsTabCompactModeEnabled(theme: Theme = Theme.LIGHT) {
IvyWalletPreview(theme = theme) {
val acc1 = Account(
id = AccountId(UUID.randomUUID()),
name = NotBlankTrimmedString.unsafe("Phyre"),
color = ColorInt(Green.toArgb()),
asset = AssetCode.unsafe("USD"),
icon = null,
includeInBalance = true,
orderNum = 0.0,
)

val acc2 = Account(
id = AccountId(UUID.randomUUID()),
name = NotBlankTrimmedString.unsafe("DSK"),
color = ColorInt(GreenLight.toArgb()),
asset = AssetCode.unsafe("USD"),
icon = null,
includeInBalance = true,
orderNum = 0.0,
)

val acc3 = Account(
id = AccountId(UUID.randomUUID()),
name = NotBlankTrimmedString.unsafe("Revolut"),
color = ColorInt(Green.toArgb()),
asset = AssetCode.unsafe("USD"),
icon = IconAsset.unsafe("revolut"),
includeInBalance = true,
orderNum = 0.0,
)

val acc4 = Account(
id = AccountId(UUID.randomUUID()),
name = NotBlankTrimmedString.unsafe("Cash"),
color = ColorInt(Green.toArgb()),
asset = AssetCode.unsafe("USD"),
icon = IconAsset.unsafe("cash"),
includeInBalance = true,
orderNum = 0.0,
)
val state = AccountsState(
baseCurrency = "BGN",
accountsData = persistentListOf(
AccountData(
account = acc1,
balance = 2125.0,
balanceBaseCurrency = null,
monthlyExpenses = 920.0,
monthlyIncome = 3045.0
),
AccountData(
account = acc2,
balance = 12125.21,
balanceBaseCurrency = null,
monthlyExpenses = 1350.50,
monthlyIncome = 8000.48
),
AccountData(
account = acc3,
balance = 1200.0,
balanceBaseCurrency = 1979.64,
monthlyExpenses = 750.0,
monthlyIncome = 1000.30
),
AccountData(
account = acc4,
balance = 820.0,
balanceBaseCurrency = null,
monthlyExpenses = 340.0,
monthlyIncome = 400.0
),
),
totalBalanceWithExcluded = "25.54",
totalBalanceWithExcludedText = "BGN 25.54",
totalBalanceWithoutExcluded = "25.54",
totalBalanceWithoutExcludedText = "BGN 25.54",
reorderVisible = false,
compactAccountsModeEnabled = true
)
UI(state = state)
}
}

/** For screen shot testing **/
@Composable
fun AccountsTabNonCompactUITest(dark: Boolean) {
val theme = when (dark) {
true -> Theme.DARK
false -> Theme.LIGHT
}
PreviewAccountsTabCompactModeDisabled(theme)
}

/** For screen shot testing **/
@Composable
fun AccountsTabUITest(dark: Boolean) {
fun AccountsTabCompactUITest(dark: Boolean) {
val theme = when (dark) {
true -> Theme.DARK
false -> Theme.LIGHT
}
PreviewAccountsTab(theme)
PreviewAccountsTabCompactModeEnabled(theme)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.ivy.base.legacy.SharedPrefs
import com.ivy.data.DataObserver
import com.ivy.data.DataWriteEvent
import com.ivy.data.repository.AccountRepository
import com.ivy.domain.features.Features
import com.ivy.legacy.IvyWalletCtx
import com.ivy.legacy.data.model.AccountData
import com.ivy.legacy.data.model.toCloseTimeRange
Expand Down Expand Up @@ -43,6 +44,7 @@ class AccountsViewModel @Inject constructor(
private val accountDataAct: AccountDataAct,
private val accountRepository: AccountRepository,
private val dataObserver: DataObserver,
private val features: Features,
) : ComposeViewModel<AccountsState, AccountsEvent>() {
private val baseCurrency = mutableStateOf("")
private val accountsData = mutableStateOf(listOf<AccountData>())
Expand Down Expand Up @@ -81,7 +83,8 @@ class AccountsViewModel @Inject constructor(
totalBalanceWithExcludedText = getTotalBalanceWithExcludedText(),
totalBalanceWithoutExcluded = getTotalBalanceWithoutExcluded(),
totalBalanceWithoutExcludedText = getTotalBalanceWithoutExcludedText(),
reorderVisible = getReorderVisible()
reorderVisible = getReorderVisible(),
compactAccountsModeEnabled = getCompactAccountsMode()
)
}

Expand Down Expand Up @@ -120,6 +123,11 @@ class AccountsViewModel @Inject constructor(
return reorderVisible.value
}

@Composable
private fun getCompactAccountsMode(): Boolean {
return features.compactAccountsMode.asEnabledState()
}

override fun onEvent(event: AccountsEvent) {
viewModelScope.launch(Dispatchers.Default) {
when (event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,16 @@ class AccountsTabPaparazziTest(
private val theme: PaparazziTheme,
) : PaparazziScreenshotTest() {
@Test
fun `snapshot accountTab composable`() {
fun `snapshot accountTab nonCompact composable`() {
ILIYANGERMANOV marked this conversation as resolved.
Show resolved Hide resolved
snapshot(theme) {
AccountsTabUITest(theme == PaparazziTheme.Dark)
AccountsTabNonCompactUITest(theme == PaparazziTheme.Dark)
}
}

@Test
fun `snapshot accountTab compact composable`() {
snapshot(theme) {
AccountsTabCompactUITest(theme == PaparazziTheme.Dark)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.ivy.domain.features

interface Features {
val sortCategoriesAlphabetically: BoolFeature
val compactAccountsMode: BoolFeature

val allFeatures: List<BoolFeature>
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@ class IvyFeatures @Inject constructor() : Features {
key = "sort_categories_alphabetically",
name = "Sort Categories Alphabetically",
description = "Sort income and expenses" +
" categories alphabetically"
" categories alphabetically"
)
override val compactAccountsMode = BoolFeature(
key = "compact_account_ui",
name = "Compact account UI",
description = "Enables more compact and dense UI for the \"Accounts\" tab"
)

override val allFeatures: List<BoolFeature>
get() = listOf(
sortCategoriesAlphabetically
sortCategoriesAlphabetically,
compactAccountsMode
)
}
Loading