[#24] Add long press to delete functionality.
Some checks are pending
continuous-integration/drone/push Build is running
Some checks are pending
continuous-integration/drone/push Build is running
Reformat code. closes #24
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package me.zobrist.tichucounter.data
|
||||
|
||||
import androidx.room.*
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Update
|
||||
|
||||
@Dao
|
||||
interface DaoBase<T> {
|
||||
|
||||
@@ -5,7 +5,6 @@ import androidx.room.Entity
|
||||
import androidx.room.Relation
|
||||
import me.zobrist.tichucounter.data.entity.Game
|
||||
import me.zobrist.tichucounter.data.entity.Round
|
||||
import java.util.*
|
||||
|
||||
@Entity
|
||||
data class GameWithScores(
|
||||
@@ -14,5 +13,5 @@ data class GameWithScores(
|
||||
parentColumn = "uid",
|
||||
entityColumn = "gameId"
|
||||
)
|
||||
val rounds: List<Round> = emptyList()
|
||||
val rounds: List<Round> = emptyList()
|
||||
)
|
||||
@@ -5,7 +5,7 @@ import androidx.navigation.*
|
||||
import androidx.navigation.compose.composable
|
||||
|
||||
fun NavController.navigate(route: Route) {
|
||||
this.navigate(route.name){
|
||||
this.navigate(route.name) {
|
||||
// Pop up to the start destination of the graph to
|
||||
// avoid building up a large stack of destinations
|
||||
// on the back stack as users select items
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
package me.zobrist.tichucounter.repository
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import me.zobrist.tichucounter.data.GameDao
|
||||
import me.zobrist.tichucounter.data.GameWithScores
|
||||
import me.zobrist.tichucounter.data.RoundDao
|
||||
@@ -41,7 +47,7 @@ class GameRepository @Inject constructor(
|
||||
val newA = nameA ?: activeGame.nameA
|
||||
val newB = nameB ?: activeGame.nameB
|
||||
|
||||
if(newA == activeGame.nameA && newB == activeGame.nameB) {
|
||||
if (newA == activeGame.nameA && newB == activeGame.nameB) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -137,9 +137,6 @@ internal class PreviewViewModel : ICounterViewModel {
|
||||
override fun addSub100Clicked(toAdd: Int) {
|
||||
}
|
||||
|
||||
override fun deleteClicked() {
|
||||
}
|
||||
|
||||
override fun updateNameA(value: String) {
|
||||
}
|
||||
|
||||
@@ -161,4 +158,7 @@ internal class PreviewViewModel : ICounterViewModel {
|
||||
override fun showKeyboard() {
|
||||
}
|
||||
|
||||
override fun deleteState(pressed: Boolean) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import me.zobrist.tichucounter.data.entity.Round
|
||||
import me.zobrist.tichucounter.domain.Tichu
|
||||
@@ -38,12 +40,12 @@ interface IKeyBoardViewModel {
|
||||
fun digitClicked(digit: String)
|
||||
fun negateClicked()
|
||||
fun addSub100Clicked(toAdd: Int)
|
||||
fun deleteClicked()
|
||||
fun updateFocusStateA(state: Boolean)
|
||||
fun updateFocusStateB(state: Boolean)
|
||||
fun swapInputScores()
|
||||
fun hideKeyboard()
|
||||
fun showKeyboard()
|
||||
fun deleteState(pressed: Boolean)
|
||||
|
||||
}
|
||||
|
||||
@@ -138,6 +140,10 @@ class CounterViewModel @Inject constructor(
|
||||
|
||||
private var lastFocused = Focused.TEAM_A
|
||||
|
||||
private var deletePressed = false
|
||||
|
||||
private var deleteJob: Job? = null
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
gameRepository.getActiveGameFlow().collect {
|
||||
@@ -204,8 +210,7 @@ class CounterViewModel @Inject constructor(
|
||||
focusLastInput()
|
||||
|
||||
|
||||
if(activeValue.digitCount() >= 5)
|
||||
{
|
||||
if (activeValue.digitCount() >= 5) {
|
||||
// 5 digits is enough
|
||||
return
|
||||
}
|
||||
@@ -214,8 +219,7 @@ class CounterViewModel @Inject constructor(
|
||||
|
||||
try {
|
||||
activeValue = newValue.toInt().toString()
|
||||
} catch (_: NumberFormatException)
|
||||
{
|
||||
} catch (_: NumberFormatException) {
|
||||
}
|
||||
|
||||
updateOtherScore()
|
||||
@@ -250,14 +254,6 @@ class CounterViewModel @Inject constructor(
|
||||
updateSubmitButton()
|
||||
}
|
||||
|
||||
override fun deleteClicked() {
|
||||
if (activeValue != "") {
|
||||
activeValue = activeValue.dropLast(1)
|
||||
}
|
||||
updateOtherScore()
|
||||
updateSubmitButton()
|
||||
}
|
||||
|
||||
override fun updateNameA(value: String) {
|
||||
viewModelScope.launch {
|
||||
gameRepository.updateActiveTeamName(nameA = value)
|
||||
@@ -297,4 +293,35 @@ class CounterViewModel @Inject constructor(
|
||||
override fun showKeyboard() {
|
||||
keyboardHidden = false
|
||||
}
|
||||
|
||||
override fun deleteState(pressed: Boolean) {
|
||||
deletePressed = pressed
|
||||
|
||||
if (deletePressed) {
|
||||
if (deleteJob?.isActive != true) {
|
||||
deleteJob = deleteRepeatedlyUntilRelease()
|
||||
}
|
||||
} else {
|
||||
deleteJob?.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
private fun deleteLastDigitActive() {
|
||||
if (activeValue != "") {
|
||||
activeValue = activeValue.dropLast(1)
|
||||
}
|
||||
updateOtherScore()
|
||||
updateSubmitButton()
|
||||
}
|
||||
|
||||
private fun deleteRepeatedlyUntilRelease(): Job {
|
||||
return viewModelScope.launch {
|
||||
deleteLastDigitActive()
|
||||
delay(500)
|
||||
while (deletePressed) {
|
||||
deleteLastDigitActive()
|
||||
delay(100)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package me.zobrist.tichucounter.ui.counter
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.core.*
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Backspace
|
||||
@@ -37,11 +39,11 @@ fun KeyBoardView(viewModel: IKeyBoardViewModel) {
|
||||
{ viewModel.updateFocusStateB(it) },
|
||||
{ viewModel.digitClicked(it) },
|
||||
{ viewModel.addSub100Clicked(it) },
|
||||
{ viewModel.deleteClicked() },
|
||||
{ viewModel.negateClicked() },
|
||||
{ viewModel.submitClicked() },
|
||||
{ viewModel.hideKeyboard() },
|
||||
{ viewModel.swapInputScores() }
|
||||
{ viewModel.swapInputScores() },
|
||||
{ viewModel.deleteState(it) }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -58,11 +60,11 @@ fun KeyboardView(
|
||||
updateFocusStateB: (Boolean) -> Unit,
|
||||
digitClicked: (String) -> Unit,
|
||||
addSub100Clicked: (Int) -> Unit,
|
||||
deleteClicked: () -> Unit,
|
||||
negateClicked: () -> Unit,
|
||||
submitClicked: () -> Unit,
|
||||
hideKeyboardClicked: () -> Unit,
|
||||
onSwapClicked: () -> Unit
|
||||
onSwapClicked: () -> Unit,
|
||||
deleteButtonPressedState: (Boolean) -> Unit
|
||||
) {
|
||||
Column {
|
||||
Row(Modifier.height(IntrinsicSize.Max)) {
|
||||
@@ -164,9 +166,16 @@ fun KeyboardView(
|
||||
}
|
||||
}
|
||||
Column(Modifier.weight(1f)) {
|
||||
KeyboardIconButton(Icons.Outlined.Backspace) {
|
||||
deleteClicked()
|
||||
}
|
||||
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
val deletePressed by interactionSource.collectIsPressedAsState()
|
||||
|
||||
deleteButtonPressedState(deletePressed)
|
||||
|
||||
KeyboardIconButton(
|
||||
icon = Icons.Outlined.Backspace,
|
||||
interactionSource = interactionSource
|
||||
) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +228,12 @@ fun KeyboardTextButton(text: String, onClicked: () -> Unit) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun KeyboardIconButton(icon: ImageVector, enabled: Boolean = true, onClicked: () -> Unit) {
|
||||
fun KeyboardIconButton(
|
||||
icon: ImageVector,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
onClicked: () -> Unit
|
||||
) {
|
||||
|
||||
ElevatedButton(
|
||||
onClick = { onClicked() },
|
||||
@@ -228,6 +242,7 @@ fun KeyboardIconButton(icon: ImageVector, enabled: Boolean = true, onClicked: ()
|
||||
.height(50.dp)
|
||||
.padding(2.dp),
|
||||
enabled = enabled,
|
||||
interactionSource = interactionSource
|
||||
) {
|
||||
Icon(
|
||||
icon,
|
||||
@@ -319,11 +334,11 @@ fun KeyboardViewPreview() {
|
||||
updateFocusStateB = {},
|
||||
digitClicked = {},
|
||||
addSub100Clicked = {},
|
||||
deleteClicked = {},
|
||||
negateClicked = {},
|
||||
submitClicked = {},
|
||||
hideKeyboardClicked = {},
|
||||
onSwapClicked = {})
|
||||
onSwapClicked = {},
|
||||
deleteButtonPressedState = {})
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user