mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-30 22:00:55 +02:00
Clear history UX/UI improved
- Show clear history button only when history view is fully expanded - History view placeholder - AlertDialog closes after clearing history - List item height callback is called only once
This commit is contained in:
parent
4668a5cea3
commit
95a401581d
@ -1028,6 +1028,7 @@
|
||||
<string name="calculator_clear_history_label">Clear</string>
|
||||
<string name="calculator_clear_history_title">Clear history</string>
|
||||
<string name="calculator_clear_history_support">All expressions from history will be deleted forever. This action can\'t be undone!</string>
|
||||
<string name="calculator_no_history">No history</string>
|
||||
|
||||
<!--Precision-->
|
||||
<string name="precision_setting_support">Number of decimal places</string>
|
||||
|
@ -18,7 +18,10 @@
|
||||
|
||||
package com.sadellie.unitto.feature.calculator
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.gestures.draggable
|
||||
@ -101,6 +104,7 @@ private fun CalculatorScreen(
|
||||
evaluate: () -> Unit,
|
||||
clearHistory: () -> Unit
|
||||
) {
|
||||
var showClearHistoryButton by rememberSaveable { mutableStateOf(false) }
|
||||
var showClearHistoryDialog by rememberSaveable { mutableStateOf(false) }
|
||||
var draggedAmount by remember { mutableStateOf(0f) }
|
||||
val dragAmountAnimated by animateFloatAsState(draggedAmount)
|
||||
@ -113,6 +117,11 @@ private fun CalculatorScreen(
|
||||
navigateUpAction = navigateUpAction,
|
||||
colors = TopAppBarDefaults.topAppBarColors(MaterialTheme.colorScheme.surfaceVariant),
|
||||
actions = {
|
||||
AnimatedVisibility(
|
||||
visible = showClearHistoryButton,
|
||||
enter = fadeIn(),
|
||||
exit = fadeOut()
|
||||
) {
|
||||
IconButton(
|
||||
onClick = { showClearHistoryDialog = true },
|
||||
content = {
|
||||
@ -123,6 +132,7 @@ private fun CalculatorScreen(
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
) { paddingValues ->
|
||||
DragDownView(
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
@ -153,10 +163,14 @@ private fun CalculatorScreen(
|
||||
state = rememberDraggableState { delta ->
|
||||
draggedAmount = (draggedAmount + delta).coerceAtLeast(0f)
|
||||
},
|
||||
onDragStopped = {
|
||||
onDragStopped = { _ ->
|
||||
// Snap to closest anchor (0, one history item, all history items)
|
||||
draggedAmount = listOf(0, historyItemHeight, maxDragAmount)
|
||||
.minBy { abs(draggedAmount.roundToInt() - it) }
|
||||
.also {
|
||||
// Show button only when fully history view is fully expanded
|
||||
showClearHistoryButton = it == maxDragAmount
|
||||
}
|
||||
.toFloat()
|
||||
}
|
||||
),
|
||||
@ -218,12 +232,21 @@ private fun CalculatorScreen(
|
||||
Text(stringResource(R.string.calculator_clear_history_support))
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = clearHistory) { Text(stringResource(R.string.calculator_clear_history_label)) }
|
||||
TextButton(
|
||||
onClick = {
|
||||
clearHistory()
|
||||
showClearHistoryDialog = false
|
||||
}
|
||||
) {
|
||||
Text(stringResource(R.string.calculator_clear_history_label))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = {
|
||||
showClearHistoryDialog = false
|
||||
}) { Text(stringResource(R.string.cancel_label)) }
|
||||
TextButton(
|
||||
onClick = { showClearHistoryDialog = false }
|
||||
) {
|
||||
Text(stringResource(R.string.cancel_label))
|
||||
}
|
||||
},
|
||||
onDismissRequest = { showClearHistoryDialog = false }
|
||||
)
|
||||
@ -247,7 +270,7 @@ private fun PreviewCalculatorScreen() {
|
||||
).map {
|
||||
HistoryItem(
|
||||
date = dtf.parse(it)!!,
|
||||
expression = "12345123451234512345123451234512345123451234512345123451234512345",
|
||||
expression = "12345".repeat(10),
|
||||
result = "67890"
|
||||
)
|
||||
}
|
||||
|
@ -18,21 +18,35 @@
|
||||
|
||||
package com.sadellie.unitto.feature.calculator.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.History
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.onPlaced
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.sadellie.unitto.core.ui.theme.NumbersTextStyleDisplayMedium
|
||||
import com.sadellie.unitto.data.model.HistoryItem
|
||||
import com.sadellie.unitto.feature.calculator.R
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
@ -42,14 +56,56 @@ internal fun HistoryList(
|
||||
historyItems: List<HistoryItem>,
|
||||
historyItemHeightCallback: (Int) -> Unit
|
||||
) {
|
||||
val verticalArrangement by remember(historyItems) {
|
||||
derivedStateOf {
|
||||
if (historyItems.isEmpty()) {
|
||||
Arrangement.Center
|
||||
} else {
|
||||
Arrangement.spacedBy(16.dp, Alignment.Bottom)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
modifier = modifier,
|
||||
reverseLayout = true
|
||||
reverseLayout = true,
|
||||
verticalArrangement = verticalArrangement
|
||||
) {
|
||||
items(historyItems) { historyItem ->
|
||||
if (historyItems.isEmpty()) {
|
||||
item {
|
||||
Column(
|
||||
Modifier.onPlaced { historyItemHeightCallback(it.size.height) }
|
||||
modifier = Modifier
|
||||
.onPlaced { historyItemHeightCallback(it.size.height) }
|
||||
.fillParentMaxWidth()
|
||||
.padding(vertical = 32.dp),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Icon(Icons.Default.History, null)
|
||||
Text(stringResource(R.string.calculator_no_history))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We do this so that callback for items height is called only once
|
||||
item {
|
||||
HistoryListItem(
|
||||
modifier = Modifier.onPlaced { historyItemHeightCallback(it.size.height) },
|
||||
historyItem = historyItems.first()
|
||||
)
|
||||
}
|
||||
items(historyItems.drop(1)) { historyItem ->
|
||||
HistoryListItem(historyItem = historyItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HistoryListItem(
|
||||
modifier: Modifier = Modifier,
|
||||
historyItem: HistoryItem
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
Text(
|
||||
text = historyItem.expression,
|
||||
maxLines = 1,
|
||||
@ -71,8 +127,6 @@ internal fun HistoryList(
|
||||
textAlign = TextAlign.End
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@ -98,7 +152,9 @@ private fun PreviewHistoryList() {
|
||||
}
|
||||
|
||||
HistoryList(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f))
|
||||
.fillMaxSize(),
|
||||
historyItems = historyItems,
|
||||
historyItemHeightCallback = {}
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user