Refactor HistoryList composable

This commit is contained in:
Sad Ellie 2023-05-17 10:28:05 +03:00
parent 533a281af9
commit 777ff6ca67
4 changed files with 71 additions and 42 deletions

View File

@ -59,6 +59,7 @@ class CalculatorHistoryRepository @Inject constructor(
private fun List<CalculatorHistoryEntity>.toHistoryItemList(): List<HistoryItem> { private fun List<CalculatorHistoryEntity>.toHistoryItemList(): List<HistoryItem> {
return this.map { return this.map {
HistoryItem( HistoryItem(
id = it.entityId,
date = Date(it.timestamp), date = Date(it.timestamp),
expression = it.expression, expression = it.expression,
result = it.result result = it.result

View File

@ -18,9 +18,10 @@
package com.sadellie.unitto.data.model package com.sadellie.unitto.data.model
import java.util.* import java.util.Date
data class HistoryItem( data class HistoryItem(
val id: Int,
val date: Date, val date: Date,
val expression: String, val expression: String,
val result: String val result: String

View File

@ -339,6 +339,7 @@ private fun PreviewCalculatorScreen() {
"14.07.2005 23:59:19", "14.07.2005 23:59:19",
).map { ).map {
HistoryItem( HistoryItem(
id = it.hashCode(),
date = dtf.parse(it)!!, date = dtf.parse(it)!!,
expression = "12345".repeat(10), expression = "12345".repeat(10),
result = "1234" result = "1234"

View File

@ -27,6 +27,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
@ -39,7 +40,6 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -75,53 +75,78 @@ internal fun HistoryList(
formatterSymbols: FormatterSymbols, formatterSymbols: FormatterSymbols,
addTokens: (String) -> Unit, addTokens: (String) -> Unit,
) { ) {
val verticalArrangement by remember(historyItems) { if (historyItems.isEmpty()) {
derivedStateOf { HistoryListPlaceholder(
if (historyItems.isEmpty()) { modifier = modifier,
Arrangement.Center historyItemHeightCallback = historyItemHeightCallback
} else { )
Arrangement.spacedBy(16.dp, Alignment.Bottom) } else {
} HistoryListContent(
modifier = modifier,
historyItems = historyItems,
addTokens = addTokens,
formatterSymbols = formatterSymbols,
historyItemHeightCallback = historyItemHeightCallback
)
}
}
@Composable
private fun HistoryListPlaceholder(
modifier: Modifier,
historyItemHeightCallback: (Int) -> Unit
) {
Column(
modifier = modifier.wrapContentHeight(unbounded = true),
verticalArrangement = Arrangement.Center
) {
Column(
modifier = Modifier
.onPlaced { historyItemHeightCallback(it.size.height) }
.fillMaxWidth()
.padding(vertical = 32.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(Icons.Default.History, null)
Text(stringResource(R.string.calculator_no_history))
} }
} }
}
@Composable
private fun HistoryListContent(
modifier: Modifier,
historyItems: List<HistoryItem>,
addTokens: (String) -> Unit,
formatterSymbols: FormatterSymbols,
historyItemHeightCallback: (Int) -> Unit
) {
val firstItem by remember { mutableStateOf(historyItems.first()) }
val restOfTheItems by remember { mutableStateOf(historyItems.drop(1)) }
LazyColumn( LazyColumn(
modifier = modifier, modifier = modifier,
reverseLayout = true, reverseLayout = true,
verticalArrangement = verticalArrangement verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.Bottom)
) { ) {
if (historyItems.isEmpty()) { // We do this so that callback for items height is called only once
item { item(firstItem.id) {
Column( HistoryListItem(
modifier = Modifier modifier = Modifier.onPlaced { historyItemHeightCallback(it.size.height) },
.onPlaced { historyItemHeightCallback(it.size.height) } historyItem = historyItems.first(),
.fillParentMaxWidth() formatterSymbols = formatterSymbols,
.padding(vertical = 32.dp), addTokens = addTokens,
verticalArrangement = Arrangement.Center, )
horizontalAlignment = Alignment.CenterHorizontally }
) {
Icon(Icons.Default.History, null) items(restOfTheItems, { it.id }) { historyItem ->
Text(stringResource(R.string.calculator_no_history)) HistoryListItem(
} modifier = Modifier,
} historyItem = historyItem,
} else { formatterSymbols = formatterSymbols,
// We do this so that callback for items height is called only once addTokens = addTokens,
item { )
HistoryListItem(
modifier = Modifier.onPlaced { historyItemHeightCallback(it.size.height) },
historyItem = historyItems.first(),
formatterSymbols = formatterSymbols,
addTokens = addTokens,
)
}
items(historyItems.drop(1)) { historyItem ->
HistoryListItem(
modifier = Modifier,
historyItem = historyItem,
formatterSymbols = formatterSymbols,
addTokens = addTokens,
)
}
} }
} }
} }
@ -226,6 +251,7 @@ private fun PreviewHistoryList() {
"14.07.2005 23:59:19", "14.07.2005 23:59:19",
).map { ).map {
HistoryItem( HistoryItem(
id = it.hashCode(),
date = dtf.parse(it)!!, date = dtf.parse(it)!!,
expression = "12345".repeat(10), expression = "12345".repeat(10),
result = "67890" result = "67890"