Skip to content

Commit

Permalink
PortfolioScreen refactoring, fix search text field height
Browse files Browse the repository at this point in the history
  • Loading branch information
mdrlzy committed Jun 8, 2024
1 parent 84fe8f4 commit 5ae9e83
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 188 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ import dev.arkbuilders.rate.R
import dev.arkbuilders.rate.data.CurrUtils
import dev.arkbuilders.rate.domain.model.CurrencyCode
import dev.arkbuilders.rate.di.DIManager
import dev.arkbuilders.rate.domain.model.AmountStr
import dev.arkbuilders.rate.presentation.destinations.SearchCurrencyScreenDestination
import dev.arkbuilders.rate.presentation.pairalert.DropDownWithIcon
import dev.arkbuilders.rate.presentation.shared.AppSharedFlow
import dev.arkbuilders.rate.presentation.shared.AppSharedFlowKey
import dev.arkbuilders.rate.presentation.theme.ArkColor
import dev.arkbuilders.rate.presentation.ui.AppTopBarBack
import dev.arkbuilders.rate.presentation.ui.BasicTextFieldPlaceholder
import dev.arkbuilders.rate.presentation.ui.GroupCreateDialog
import dev.arkbuilders.rate.presentation.ui.GroupSelectPopup
import dev.arkbuilders.rate.presentation.ui.NotifyAddedSnackbarVisuals
Expand Down Expand Up @@ -215,7 +217,7 @@ private fun Currencies(
@Composable
fun InputCurrency(
pos: Int,
codeToValue: Pair<CurrencyCode, String>,
amount: AmountStr,
onAssetValueChanged: (Int, String) -> Unit,
onAssetRemove: (Int) -> Unit,
onCodeChange: (Int) -> Unit
Expand All @@ -242,7 +244,7 @@ fun InputCurrency(
) {
Text(
modifier = Modifier.padding(start = 14.dp),
text = codeToValue.first,
text = amount.code,
fontSize = 16.sp,
color = ArkColor.TextSecondary
)
Expand All @@ -253,29 +255,28 @@ fun InputCurrency(
tint = ArkColor.FGQuinary
)
}
BasicTextField(
BasicTextFieldPlaceholder(
modifier = Modifier.padding(start = 12.dp),
value = codeToValue.second,
value = amount.value,
onValueChange = { onAssetValueChanged(pos, it) },
textStyle = TextStyle.Default.copy(
color = ArkColor.TextPrimary,
fontSize = 16.sp
),
placeholder = "Input value",
keyboardOptions = KeyboardOptions.Default
.copy(keyboardType = KeyboardType.Number)
)
}

IconButton(modifier = Modifier
.padding(start = 16.dp)
.size(44.dp)
.border(
1.dp,
ArkColor.Border,
RoundedCornerShape(8.dp)
)
.clip(RoundedCornerShape(8.dp)),
onClick = { onAssetRemove(pos) }
Box(
modifier = Modifier
.padding(start = 16.dp)
.size(44.dp)
.border(
1.dp,
ArkColor.Border,
RoundedCornerShape(8.dp)
)
.clip(RoundedCornerShape(8.dp))
.clickable { onAssetRemove(pos) },
contentAlignment = Alignment.Center
) {
Icon(
painter = painterResource(id = R.drawable.ic_delete),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import dev.arkbuilders.rate.data.CurrUtils
import dev.arkbuilders.rate.domain.model.Asset
import dev.arkbuilders.rate.domain.model.CurrencyCode
import dev.arkbuilders.rate.data.toDoubleSafe
import dev.arkbuilders.rate.domain.model.AmountStr
import dev.arkbuilders.rate.domain.repo.CodeUseStatRepo
import dev.arkbuilders.rate.domain.repo.CurrencyRepo
import dev.arkbuilders.rate.domain.repo.PortfolioRepo
Expand All @@ -23,10 +24,8 @@ import org.orbitmvi.orbit.viewmodel.container
import javax.inject.Inject
import javax.inject.Singleton

private val stubCurrency = "USD" to ""

data class AddAssetState(
val currencies: List<Pair<CurrencyCode, String>> = listOf(stubCurrency),
val currencies: List<AmountStr> = listOf(AmountStr("USD", "")),
val group: String? = null,
val availableGroups: List<String> = emptyList()
)
Expand All @@ -53,15 +52,15 @@ class AddAssetViewModel(
reduce {
val newCurrencies = state.currencies.toMutableList()
newCurrencies[pos] =
newCurrencies[pos].copy(first = selectedCode)
newCurrencies[pos].copy(code = selectedCode)
state.copy(currencies = newCurrencies)
}
}
}.launchIn(viewModelScope)

AppSharedFlow.AddAsset.flow.onEach { code ->
intent {
reduce { state.copy(currencies = state.currencies + (code to "")) }
reduce { state.copy(currencies = state.currencies + AmountStr(code, "")) }
}
}.launchIn(viewModelScope)

Expand Down Expand Up @@ -91,15 +90,15 @@ class AddAssetViewModel(
reduce {
val newCurrencies = state.currencies.toMutableList()
val old = newCurrencies[pos]
val validatedAmount = CurrUtils.validateInput(old.second, input)
newCurrencies[pos] = newCurrencies[pos].copy(second = validatedAmount)
val validatedAmount = CurrUtils.validateInput(old.value, input)
newCurrencies[pos] = newCurrencies[pos].copy(value = validatedAmount)
state.copy(currencies = newCurrencies)
}
}

fun onAddAsset() = intent {
val currencies = state.currencies.map {
Asset(code = it.first, value = it.second.toDoubleSafe(), group = state.group)
Asset(code = it.code, value = it.value.toDoubleSafe(), group = state.group)
}
assetsRepo.setAssetsList(currencies)
codeUseStatRepo.codesUsed(*currencies.map { it.code }.toTypedArray())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ import dev.arkbuilders.rate.presentation.ui.AppSwipeToDismiss
import dev.arkbuilders.rate.presentation.ui.CurrIcon
import dev.arkbuilders.rate.presentation.ui.GroupViewPager
import dev.arkbuilders.rate.presentation.ui.LoadingScreen
import dev.arkbuilders.rate.presentation.ui.SearchTextFieldWithSort
import dev.arkbuilders.rate.presentation.ui.NoResult
import dev.arkbuilders.rate.presentation.ui.SearchTextField
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.orbitmvi.orbit.compose.collectAsState
Expand Down Expand Up @@ -119,6 +120,7 @@ fun PortfolioScreen(navigator: DestinationsNavigator) {
onClick = { display ->
navigator.navigate(EditAssetScreenDestination(display.asset.id))
},
onFilterChange = viewModel::onFilterChange,
onDelete = viewModel::onAssetRemove
)
}
Expand All @@ -134,8 +136,14 @@ private val previewPortfolioAmount = PortfolioDisplayAsset(

private val previewState = PortfolioScreenState(
pages = listOf(
PortfolioScreenPage("Group1", listOf(previewPortfolioAmount, previewPortfolioAmount)),
PortfolioScreenPage("Group2", listOf(previewPortfolioAmount, previewPortfolioAmount))
PortfolioScreenPage(
"Group1",
listOf(previewPortfolioAmount, previewPortfolioAmount)
),
PortfolioScreenPage(
"Group2",
listOf(previewPortfolioAmount, previewPortfolioAmount)
)
)
)

Expand All @@ -144,13 +152,24 @@ private val previewState = PortfolioScreenState(
private fun Content(
state: PortfolioScreenState = previewState,
onClick: (PortfolioDisplayAsset) -> Unit = {},
onFilterChange: (String) -> Unit = {},
onDelete: (Asset) -> Unit = {}
) {
val groups = state.pages.map { it.group }
Column {
SearchTextFieldWithSort(modifier = Modifier.padding(top = 16.dp))
SearchTextField(
modifier = Modifier.padding(
top = 16.dp,
start = 16.dp,
end = 16.dp,
bottom = 16.dp
),
text = state.filter,
onValueChange = onFilterChange
)
if (state.pages.size == 1) {
GroupPage(
filter = state.filter,
baseCode = state.baseCode,
amounts = state.pages.first().assets,
onClick = onClick,
Expand All @@ -162,6 +181,7 @@ private fun Content(
groups = groups
) { index ->
GroupPage(
filter = state.filter,
baseCode = state.baseCode,
amounts = state.pages[index].assets,
onClick = onClick,
Expand All @@ -174,6 +194,7 @@ private fun Content(

@Composable
private fun GroupPage(
filter: String,
baseCode: CurrencyCode,
amounts: List<PortfolioDisplayAsset>,
onClick: (PortfolioDisplayAsset) -> Unit = {},
Expand All @@ -182,33 +203,41 @@ private fun GroupPage(
val total = amounts.fold(0.0) { acc, amount ->
acc + amount.baseAmount.value
}
LazyColumn(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
item {
Text(
modifier = Modifier.padding(top = 32.dp),
text = "Total Assets",
color = ArkColor.TextTertiary,
fontWeight = FontWeight.Medium
)
Text(
modifier = Modifier.padding(top = 8.dp),
text = "${CurrUtils.prepareToDisplay(total)} $baseCode",
color = ArkColor.TextPrimary,
fontWeight = FontWeight.SemiBold,
fontSize = 36.sp
)
AppHorDiv16(Modifier.padding(top = 32.dp))
}
items(amounts, key = { it.asset.id }) {
AppSwipeToDismiss(
content = { CurrencyItem(it, onClick = onClick) },
onDelete = { onDelete(it.asset) }
)
AppHorDiv16()
val filtered =
amounts.filter { it.asset.code.contains(filter, ignoreCase = true) }
if (filtered.isNotEmpty()) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
if (filter.isEmpty()) {
item {
Text(
modifier = Modifier.padding(top = 32.dp),
text = "Total Assets",
color = ArkColor.TextTertiary,
fontWeight = FontWeight.Medium
)
Text(
modifier = Modifier.padding(top = 8.dp),
text = "${CurrUtils.prepareToDisplay(total)} $baseCode",
color = ArkColor.TextPrimary,
fontWeight = FontWeight.SemiBold,
fontSize = 36.sp
)
AppHorDiv16(Modifier.padding(top = 32.dp))
}
}
items(filtered, key = { it.asset.id }) {
AppSwipeToDismiss(
content = { CurrencyItem(it, onClick = onClick) },
onDelete = { onDelete(it.asset) }
)
AppHorDiv16()
}
}
} else {
NoResult()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ import dev.arkbuilders.rate.domain.usecase.ConvertWithRateUseCase
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.orbitmvi.orbit.Container
import org.orbitmvi.orbit.ContainerHost
import org.orbitmvi.orbit.syntax.simple.blockingIntent
import org.orbitmvi.orbit.syntax.simple.intent
import org.orbitmvi.orbit.syntax.simple.reduce
import org.orbitmvi.orbit.viewmodel.container
import javax.inject.Inject
import javax.inject.Singleton

data class PortfolioScreenState(
val filter: String = "",
val baseCode: CurrencyCode = "USD",
val pages: List<PortfolioScreenPage> = emptyList(),
val initialized: Boolean = false
Expand Down Expand Up @@ -73,10 +74,14 @@ class PortfolioViewModel(
assetsRepo.removeAsset(amount.id)
}

fun onFilterChange(filter: String) = blockingIntent {
reduce { state.copy(filter = filter) }
}

private fun init() = intent {
val baseCode = prefs.get(PreferenceKey.BaseCurrencyCode)
val list = assetsRepo.allAssets()
val groups = list.groupBy(keySelector = { it.group })
val assets = assetsRepo.allAssets().reversed()
val groups = assets.groupBy(keySelector = { it.group })
val pages = groups.map { (group, assets) ->
val displayAssets = assetToPortfolioDisplayAmount(
baseCode,
Expand All @@ -85,7 +90,7 @@ class PortfolioViewModel(
PortfolioScreenPage(group, displayAssets)
}
reduce {
state.copy(baseCode, pages, initialized = true)
state.copy(baseCode = baseCode, pages = pages, initialized = true)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import dev.arkbuilders.rate.presentation.shared.AppSharedFlowKey
import dev.arkbuilders.rate.presentation.theme.ArkColor
import dev.arkbuilders.rate.presentation.ui.AppHorDiv16
import dev.arkbuilders.rate.presentation.ui.AppTopBarBack
import dev.arkbuilders.rate.presentation.ui.BasicTextFieldPlaceholder
import dev.arkbuilders.rate.presentation.ui.GroupCreateDialog
import dev.arkbuilders.rate.presentation.ui.GroupSelectPopup
import dev.arkbuilders.rate.presentation.ui.NotifyAddedSnackbarVisuals
Expand Down Expand Up @@ -307,43 +308,14 @@ private fun FromInput(
tint = ArkColor.FGQuinary
)
}
val interactionSource = remember { MutableInteractionSource() }
BasicTextField(
BasicTextFieldPlaceholder(
modifier = Modifier.padding(start = 12.dp),
value = amount,
onValueChange = { onAmountChanged(it) },
textStyle = TextStyle.Default.copy(
color = ArkColor.TextPrimary,
fontSize = 16.sp
),
placeholder = "Input value",
keyboardOptions = KeyboardOptions.Default
.copy(keyboardType = KeyboardType.Number),
interactionSource = interactionSource,
singleLine = true
) { innerTextField ->
TextFieldDefaults.DecorationBox(
value = amount,
innerTextField = innerTextField,
placeholder = {
Text(
text = "Input the value",
color = ArkColor.TextPlaceHolder,
fontSize = 16.sp
)
},
contentPadding = PaddingValues(0.dp),
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent
),
enabled = true,
singleLine = true,
visualTransformation = VisualTransformation.None,
interactionSource = interactionSource
)
}
.copy(keyboardType = KeyboardType.Number)
)
}
}
}
Expand Down
Loading

0 comments on commit 5ae9e83

Please sign in to comment.