Add swipe to open and delete to history items.
All checks were successful
Build Android / build (push) Successful in 7m17s
All checks were successful
Build Android / build (push) Successful in 7m17s
This commit is contained in:
@@ -6,12 +6,30 @@ import androidx.activity.compose.setContent
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
import androidx.compose.material.icons.outlined.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material.icons.outlined.Calculate
|
||||
import androidx.compose.material.icons.outlined.Info
|
||||
import androidx.compose.material.icons.outlined.Keyboard
|
||||
import androidx.compose.material.icons.outlined.List
|
||||
import androidx.compose.material.icons.outlined.MoreVert
|
||||
import androidx.compose.material.icons.outlined.Redo
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material.icons.outlined.Undo
|
||||
import androidx.compose.material3.DrawerState
|
||||
import androidx.compose.material3.DrawerValue
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalNavigationDrawer
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.rememberDrawerState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.navigation.NavHostController
|
||||
@@ -22,12 +40,23 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import me.zobrist.tichucounter.domain.*
|
||||
import me.zobrist.tichucounter.domain.DrawerItem
|
||||
import me.zobrist.tichucounter.domain.ISettingsChangeListener
|
||||
import me.zobrist.tichucounter.domain.KeepScreenOn
|
||||
import me.zobrist.tichucounter.domain.Language
|
||||
import me.zobrist.tichucounter.domain.Route
|
||||
import me.zobrist.tichucounter.domain.SettingsAdapter
|
||||
import me.zobrist.tichucounter.domain.Theme
|
||||
import me.zobrist.tichucounter.domain.TopBarAction
|
||||
import me.zobrist.tichucounter.domain.TopBarState
|
||||
import me.zobrist.tichucounter.domain.composable
|
||||
import me.zobrist.tichucounter.domain.navigate
|
||||
import me.zobrist.tichucounter.ui.AppTheme
|
||||
import me.zobrist.tichucounter.ui.MainViewModel
|
||||
import me.zobrist.tichucounter.ui.about.AboutView
|
||||
import me.zobrist.tichucounter.ui.composables.DropDownMenu
|
||||
import me.zobrist.tichucounter.ui.counter.*
|
||||
import me.zobrist.tichucounter.ui.counter.Counter
|
||||
import me.zobrist.tichucounter.ui.counter.CounterViewModel
|
||||
import me.zobrist.tichucounter.ui.history.HistoryList
|
||||
import me.zobrist.tichucounter.ui.history.HistoryViewModel
|
||||
import me.zobrist.tichucounter.ui.layout.DrawerContent
|
||||
|
||||
@@ -1,17 +1,40 @@
|
||||
package me.zobrist.tichucounter.ui.counter
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.core.*
|
||||
import androidx.compose.animation.core.RepeatMode
|
||||
import androidx.compose.animation.core.animateFloat
|
||||
import androidx.compose.animation.core.infiniteRepeatable
|
||||
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.IntrinsicSize
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.wrapContentWidth
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Backspace
|
||||
import androidx.compose.material.icons.outlined.Check
|
||||
import androidx.compose.material.icons.outlined.KeyboardHide
|
||||
import androidx.compose.material.icons.outlined.SwapHoriz
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.ElevatedButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package me.zobrist.tichucounter.ui.counter
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
||||
@@ -1,34 +1,45 @@
|
||||
package me.zobrist.tichucounter.ui.history
|
||||
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.foundation.background
|
||||
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.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Delete
|
||||
import androidx.compose.material.icons.outlined.DeleteForever
|
||||
import androidx.compose.material.icons.outlined.MoreVert
|
||||
import androidx.compose.material.icons.outlined.RestartAlt
|
||||
import androidx.compose.material3.AlertDialog
|
||||
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
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.SwipeToDismiss
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.rememberDismissState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Alignment.Companion.CenterVertically
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
@@ -38,7 +49,6 @@ import me.zobrist.tichucounter.data.GameWithScores
|
||||
import me.zobrist.tichucounter.data.entity.Game
|
||||
import me.zobrist.tichucounter.data.entity.Round
|
||||
import me.zobrist.tichucounter.domain.getTotalPoints
|
||||
import me.zobrist.tichucounter.ui.composables.DropDownMenu
|
||||
import java.text.DateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
@@ -46,8 +56,7 @@ import java.util.Locale
|
||||
|
||||
@Composable
|
||||
fun HistoryList(
|
||||
viewModel: HistoryViewModel,
|
||||
navigateToCalculator: () -> Unit
|
||||
viewModel: HistoryViewModel, navigateToCalculator: () -> Unit
|
||||
) {
|
||||
|
||||
var showDeleteDialog by remember { mutableStateOf(false) }
|
||||
@@ -78,14 +87,12 @@ fun DeleteConfirmDialog(show: Boolean = true, onExecuted: (Boolean) -> Unit = {}
|
||||
AlertDialog(
|
||||
onDismissRequest = { onExecuted(false) },
|
||||
dismissButton = {
|
||||
TextButton({ onExecuted(false) })
|
||||
{
|
||||
TextButton({ onExecuted(false) }) {
|
||||
Text(stringResource(R.string.cancel))
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton({ onExecuted(true) })
|
||||
{
|
||||
TextButton({ onExecuted(true) }) {
|
||||
Text(stringResource(R.string.ok))
|
||||
}
|
||||
},
|
||||
@@ -98,8 +105,8 @@ fun DeleteConfirmDialog(show: Boolean = true, onExecuted: (Boolean) -> Unit = {}
|
||||
@Composable
|
||||
fun HistoryList(
|
||||
games: List<GameWithScores>,
|
||||
onOpenClicked: (GameId: Long) -> Unit,
|
||||
onDeleteClicked: (GameId: Long) -> Unit,
|
||||
onOpenClicked: (gameId: Long) -> Unit,
|
||||
onDeleteClicked: (gameId: Long) -> Unit,
|
||||
onDeleteAllClicked: () -> Unit
|
||||
|
||||
) {
|
||||
@@ -113,7 +120,7 @@ fun HistoryList(
|
||||
)
|
||||
}
|
||||
items(games.filter { it.game.active }) {
|
||||
HistoryListItem(it, onOpenClicked, onDeleteClicked)
|
||||
HistoryListItem(it)
|
||||
}
|
||||
|
||||
if (games.count() > 1) {
|
||||
@@ -125,13 +132,14 @@ fun HistoryList(
|
||||
)
|
||||
}
|
||||
|
||||
items(games.filter { !it.game.active }) {
|
||||
HistoryListItem(it, onOpenClicked, onDeleteClicked)
|
||||
items(items = games.filter { !it.game.active }, key = {
|
||||
it.hashCode()
|
||||
}) {
|
||||
DismissibleHistoryListItem(it, onOpenClicked, onDeleteClicked)
|
||||
}
|
||||
|
||||
item {
|
||||
Button(
|
||||
enabled = games.count() > 1,
|
||||
Button(enabled = games.count() > 1,
|
||||
modifier = Modifier
|
||||
.padding(start = 4.dp, end = 4.dp, top = 10.dp)
|
||||
.align(CenterVertically)
|
||||
@@ -146,11 +154,70 @@ fun HistoryList(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun DismissibleHistoryListItem(
|
||||
game: GameWithScores,
|
||||
onOpenClicked: (gameId: Long) -> Unit,
|
||||
onDeleteClicked: (gameId: Long) -> Unit
|
||||
) {
|
||||
val dismissState = rememberDismissState(confirmValueChange = {
|
||||
if (it == DismissValue.DismissedToStart) {
|
||||
onDeleteClicked(game.game.uid)
|
||||
}
|
||||
if (it == DismissValue.DismissedToEnd) {
|
||||
onOpenClicked(game.game.uid)
|
||||
}
|
||||
true
|
||||
})
|
||||
|
||||
SwipeToDismiss(state = dismissState, 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
|
||||
}
|
||||
val icon = when (direction) {
|
||||
DismissDirection.StartToEnd -> Icons.Outlined.RestartAlt
|
||||
DismissDirection.EndToStart -> Icons.Outlined.Delete
|
||||
}
|
||||
val text = when (direction) {
|
||||
DismissDirection.StartToEnd -> stringResource(id = R.string.activate)
|
||||
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
|
||||
) {
|
||||
Row {
|
||||
Icon(
|
||||
icon, contentDescription = null, modifier = Modifier.scale(scale)
|
||||
)
|
||||
Text(text = text)
|
||||
}
|
||||
}
|
||||
}, dismissContent = {
|
||||
HistoryListItem(game = game)
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun HistoryListItem(
|
||||
game: GameWithScores,
|
||||
onOpenClicked: (GameId: Long) -> Unit,
|
||||
onDeleteClicked: (GameId: Long) -> Unit
|
||||
game: GameWithScores
|
||||
) {
|
||||
val format =
|
||||
DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, Locale.getDefault())
|
||||
@@ -168,13 +235,10 @@ fun HistoryListItem(
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(all = 4.dp)
|
||||
.clickable { onOpenClicked(game.game.uid) },
|
||||
colors = cardColor
|
||||
.padding(all = 4.dp), colors = cardColor
|
||||
) {
|
||||
Row(
|
||||
Modifier
|
||||
.padding(all = 12.dp)
|
||||
Modifier.padding(all = 12.dp)
|
||||
) {
|
||||
Column(Modifier.weight(4f)) {
|
||||
Text(
|
||||
@@ -193,38 +257,6 @@ fun HistoryListItem(
|
||||
style = MaterialTheme.typography.labelSmall
|
||||
)
|
||||
}
|
||||
Column(
|
||||
Modifier
|
||||
.wrapContentSize()
|
||||
.width(40.dp)
|
||||
) {
|
||||
|
||||
if (!game.game.active) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.padding(start = 20.dp, bottom = 20.dp)
|
||||
.clickable { expanded = true },
|
||||
imageVector = Icons.Outlined.MoreVert,
|
||||
contentDescription = null
|
||||
)
|
||||
|
||||
|
||||
DropDownMenu(
|
||||
mapOf("delete" to R.string.delete),
|
||||
"",
|
||||
expanded,
|
||||
) {
|
||||
expanded = false
|
||||
it?.let {
|
||||
when (it) {
|
||||
"delete" -> onDeleteClicked(game.game.uid)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,24 +266,15 @@ fun HistoryListItem(
|
||||
private fun HistoryListPreview() {
|
||||
val tempData = listOf(
|
||||
GameWithScores(
|
||||
Game(true, "abc", "def", Date(), Date()),
|
||||
listOf(Round(1, 550, 500))
|
||||
),
|
||||
GameWithScores(
|
||||
Game(false, "ADTH", "dogfg", Date(), Date()),
|
||||
listOf(Round(2, 20, 60))
|
||||
),
|
||||
GameWithScores(
|
||||
Game(false, "TeamA3 langer Name", "TeamB3", Date(), Date()),
|
||||
listOf(Round(3, 30, 70))
|
||||
),
|
||||
GameWithScores(
|
||||
Game(false, "TeamA4", "TeamB4", Date(), Date()),
|
||||
listOf(Round(4, 40, 80))
|
||||
),
|
||||
GameWithScores(
|
||||
Game(false, "TeamA5", "TeamB5", Date(), Date()),
|
||||
listOf(Round(5, 50, 90))
|
||||
Game(true, "abc", "def", Date(), Date()), listOf(Round(1, 550, 500))
|
||||
), GameWithScores(
|
||||
Game(false, "ADTH", "dogfg", Date(), Date()), listOf(Round(2, 20, 60))
|
||||
), GameWithScores(
|
||||
Game(false, "TeamA3 langer Name", "TeamB3", Date(), Date()), listOf(Round(3, 30, 70))
|
||||
), GameWithScores(
|
||||
Game(false, "TeamA4", "TeamB4", Date(), Date()), listOf(Round(4, 40, 80))
|
||||
), GameWithScores(
|
||||
Game(false, "TeamA5", "TeamB5", Date(), Date()), listOf(Round(5, 50, 90))
|
||||
)
|
||||
)
|
||||
HistoryList(tempData, {}, {}) {}
|
||||
|
||||
@@ -1,20 +1,28 @@
|
||||
package me.zobrist.tichucounter.ui.layout
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
import androidx.compose.material.icons.outlined.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material.icons.outlined.Calculate
|
||||
import androidx.compose.material.icons.outlined.List
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalDrawerSheet
|
||||
import androidx.compose.material3.NavigationDrawerItem
|
||||
import androidx.compose.material3.NavigationDrawerItemDefaults
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import me.zobrist.tichucounter.R
|
||||
import me.zobrist.tichucounter.domain.*
|
||||
import me.zobrist.tichucounter.domain.DrawerItem
|
||||
import me.zobrist.tichucounter.domain.Route
|
||||
import me.zobrist.tichucounter.ui.AppTheme
|
||||
import me.zobrist.tichucounter.ui.counter.*
|
||||
|
||||
@Composable
|
||||
fun DrawerContent(
|
||||
|
||||
@@ -24,5 +24,6 @@
|
||||
<string name="menu_counter">Counter</string>
|
||||
<string name="menu_about">About</string>
|
||||
<string name="contact_us">Schreib uns</string>
|
||||
<string name="activate">Aktivieren</string>
|
||||
|
||||
</resources>
|
||||
@@ -28,4 +28,5 @@
|
||||
<string name="menu_about">About</string>
|
||||
<string name="contact_us">Contact us</string>
|
||||
<string name="play_store" translatable="false">Play Store</string>
|
||||
<string name="activate">Activate</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user