feature/swipe-actions #44

Merged
fabian merged 6 commits from feature/swipe-actions into develop 2023-08-25 18:19:45 +02:00
Showing only changes of commit 8521247c58 - Show all commits

View File

@@ -10,9 +10,12 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
@@ -22,9 +25,9 @@ import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.DeleteForever
import androidx.compose.material.icons.outlined.RestartAlt
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Badge
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DismissDirection
import androidx.compose.material3.DismissValue
import androidx.compose.material3.ExperimentalMaterial3Api
@@ -45,6 +48,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Alignment.Companion.TopEnd
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Color
@@ -161,58 +165,49 @@ fun HistoryList(
) {
Row {
LazyColumn(state = lazyListState) {
item {
Text(
modifier = Modifier.padding(start = 10.dp, end = 10.dp),
text = stringResource(R.string.active),
style = MaterialTheme.typography.headlineSmall
)
}
items(games.filter { it.game.active }) {
HistoryListItem(it, Modifier.animateItemPlacement())
}
if (games.count() > 1) {
item {
Text(
modifier = Modifier.padding(start = 10.dp, end = 10.dp, top = 10.dp),
text = stringResource(R.string.inactive),
style = MaterialTheme.typography.headlineSmall
items(
items = games,
key = { it.hashCode() }) {
if (it.game.active) {
HistoryListItem(
it,
Modifier.animateItemPlacement()
)
}
items(items = games.filter { !it.game.active }, key = {
it.hashCode()
}) {
} else {
DismissibleHistoryListItem(
it, onOpenClicked, onDeleteClicked, Modifier.animateItemPlacement()
it,
Modifier.animateItemPlacement(),
onOpenClicked,
onDeleteClicked
)
}
}
item {
Button(enabled = games.count() > 1,
modifier = Modifier
.padding(start = 4.dp, end = 4.dp, top = 10.dp)
.align(CenterVertically)
.fillMaxWidth()
.animateItemPlacement(),
onClick = { onDeleteAllClicked() }) {
Icon(imageVector = Icons.Outlined.DeleteForever, contentDescription = null)
Text(text = stringResource(id = R.string.deleteAll))
}
item {
Button(enabled = games.count() > 1,
modifier = Modifier
.padding(start = 4.dp, end = 4.dp, top = 10.dp)
.align(CenterVertically)
.fillMaxWidth()
.animateItemPlacement(),
onClick = { onDeleteAllClicked() }) {
Icon(imageVector = Icons.Outlined.DeleteForever, contentDescription = null)
Text(text = stringResource(id = R.string.deleteAll))
}
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DismissibleHistoryListItem(
game: GameWithScores,
modifier: Modifier = Modifier,
onOpenClicked: (gameId: Long) -> Unit,
onDeleteClicked: (gameId: Long) -> Unit,
modifier: Modifier = Modifier,
) {
val density = LocalDensity.current
@@ -228,53 +223,65 @@ fun DismissibleHistoryListItem(
true
})
SwipeToDismiss(modifier = modifier, state = dismissState, background = {
val direction = dismissState.dismissDirection ?: return@SwipeToDismiss
val color by animateColorAsState(
when (dismissState.targetValue) {
DismissValue.DismissedToStart -> Color.Red
else -> MaterialTheme.colorScheme.background
val directions = if (game.game.active) {
setOf()
}, label = ""
)
val alignment = when (direction) {
DismissDirection.StartToEnd -> Alignment.CenterStart
DismissDirection.EndToStart -> Alignment.CenterEnd
}
val icon = when (direction) {
DismissDirection.StartToEnd -> Icons.Outlined.RestartAlt
DismissDirection.EndToStart -> Icons.Outlined.Delete
}
val text = when (direction) {
DismissDirection.StartToEnd -> stringResource(id = R.string.continue_play)
DismissDirection.EndToStart -> stringResource(id = R.string.delete)
}
val scale by animateFloatAsState(
if (dismissState.targetValue == DismissValue.Default) 0.75f else 1f, label = ""
)
} else {
setOf(DismissDirection.EndToStart, DismissDirection.StartToEnd)
}
Box(
Modifier
.fillMaxSize()
.background(color)
.padding(horizontal = 20.dp),
contentAlignment = alignment
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
icon, contentDescription = null, modifier = Modifier.scale(scale)
)
Text(text = text)
SwipeToDismiss(
modifier = modifier,
state = dismissState,
directions = directions,
background = {
val direction = dismissState.dismissDirection ?: return@SwipeToDismiss
val color by animateColorAsState(
when (dismissState.targetValue) {
DismissValue.DismissedToStart -> Color.Red
else -> MaterialTheme.colorScheme.background
}, label = ""
)
val alignment = when (direction) {
DismissDirection.StartToEnd -> Alignment.CenterStart
DismissDirection.EndToStart -> Alignment.CenterEnd
}
}
}, dismissContent = {
HistoryListItem(game = game)
})
val icon = when (direction) {
DismissDirection.StartToEnd -> Icons.Outlined.RestartAlt
DismissDirection.EndToStart -> Icons.Outlined.Delete
}
val text = when (direction) {
DismissDirection.StartToEnd -> stringResource(id = R.string.continue_play)
DismissDirection.EndToStart -> stringResource(id = R.string.delete)
}
val scale by animateFloatAsState(
if (dismissState.targetValue == DismissValue.Default) 0.75f else 1f, label = ""
)
Box(
Modifier
.fillMaxSize()
.background(color)
.padding(horizontal = 20.dp),
contentAlignment = alignment
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
icon, contentDescription = null, modifier = Modifier.scale(scale)
)
Text(text = text)
}
}
}, dismissContent = {
HistoryListItem(game = game)
})
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HistoryListItem(
game: GameWithScores, modifier: Modifier = Modifier
@@ -282,40 +289,45 @@ fun HistoryListItem(
val format =
DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, Locale.getDefault())
val cardColor = if (game.game.active) {
CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.secondaryContainer)
} else {
CardDefaults.cardColors()
}
val totalScores = game.getTotalPoints()
Card(
modifier = modifier
.fillMaxWidth()
.padding(all = 4.dp), colors = cardColor
.padding(all = 4.dp)
) {
Row(
Modifier.padding(all = 12.dp)
) {
Column(Modifier.weight(4f)) {
Text(
text = game.game.nameA + " vs " + game.game.nameB,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.headlineSmall
)
Text(
text = totalScores.first.toString() + " : " + totalScores.second.toString(),
style = MaterialTheme.typography.bodyLarge
)
Spacer(modifier = Modifier.padding(5.dp))
Text(
text = format.format(game.game.modified),
style = MaterialTheme.typography.labelSmall
)
Box( modifier = modifier.fillMaxSize()) {
Column {
Text(
text = game.game.nameA + " vs " + game.game.nameB,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.headlineSmall
)
Text(
text = totalScores.first.toString() + " : " + totalScores.second.toString(),
style = MaterialTheme.typography.bodyLarge
)
Spacer(modifier = Modifier.padding(5.dp))
Text(
text = format.format(game.game.modified),
style = MaterialTheme.typography.labelSmall
)
}
if (game.game.active) {
Badge(
modifier = Modifier.align(TopEnd),
contentColor = MaterialTheme.colorScheme.onPrimary,
containerColor = MaterialTheme.colorScheme.primary) {
Text(
text = stringResource(id = R.string.active),
style = MaterialTheme.typography.labelSmall
)
}
}
}
}
}
@@ -326,7 +338,7 @@ fun HistoryListItem(
private fun HistoryListPreview() {
val tempData = listOf(
GameWithScores(
Game(true, "abc", "def", Date(), Date()), listOf(Round(1, 550, 500))
Game(true, "abcsdf sdaf asdf sdf ", "defsadf asdf sadf ", Date(), Date()), listOf(Round(1, 550, 500))
), GameWithScores(
Game(false, "ADTH", "dogfg", Date(), Date()), listOf(Round(2, 20, 60))
), GameWithScores(