Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cf5c408464 | |||
| fdf8c5c7df | |||
| 7ed3a29c5b | |||
| 9434d1f1b9 | |||
| 9abff51cb8 | |||
| 93f51b9220 | |||
| 8bb2b9bf20 | |||
| 80039a5f94 | |||
| 4c01fe13a8 |
@@ -30,15 +30,11 @@ jobs:
|
|||||||
- name: Build abb
|
- name: Build abb
|
||||||
run: ./gradlew bundleRelease
|
run: ./gradlew bundleRelease
|
||||||
|
|
||||||
- name: Deploy latest to Nextcloud
|
- uses: actions/upload-artifact@v3
|
||||||
run: |
|
with:
|
||||||
curl -k -u "${{ secrets.NEXTCLOUD_USERNAME }}:${{ secrets.NEXTCLOUD_PASSWORD }}" -T "app/build/outputs/apk/release/app-release.apk" "${{ secrets.NEXTCLOUD_BASE_URL }}/TichuCounter/latest/app-release.apk"
|
name: app-release
|
||||||
curl -k -u "${{ secrets.NEXTCLOUD_USERNAME }}:${{ secrets.NEXTCLOUD_PASSWORD }}" -T "app/build/outputs/bundle/release/app-release.aab" "${{ secrets.NEXTCLOUD_BASE_URL }}/TichuCounter/latest/app-release.aab"
|
retention-days: 10
|
||||||
|
path: app/build/outputs/**/release/app-release.*
|
||||||
- name: Deploy tagged build to Nextcloud
|
|
||||||
run: |
|
|
||||||
curl -k -u "${{ secrets.NEXTCLOUD_USERNAME }}:${{ secrets.NEXTCLOUD_PASSWORD }}" -T "app/build/outputs/apk/release/app-release.apk" "${{ secrets.NEXTCLOUD_BASE_URL }}/TichuCounter/tagged/app-release-${GITHUB_REF_NAME##*/}.apk"
|
|
||||||
curl -k -u "${{ secrets.NEXTCLOUD_USERNAME }}:${{ secrets.NEXTCLOUD_PASSWORD }}" -T "app/build/outputs/bundle/release/app-release.aab" "${{ secrets.NEXTCLOUD_BASE_URL }}/TichuCounter/tagged/app-release-${GITHUB_REF_NAME##*/}.aab"
|
|
||||||
|
|
||||||
- uses: https://github.com/ravsamhq/notify-slack-action@v2
|
- uses: https://github.com/ravsamhq/notify-slack-action@v2
|
||||||
if: always()
|
if: always()
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -15,3 +15,4 @@
|
|||||||
.idea
|
.idea
|
||||||
keystore.properties
|
keystore.properties
|
||||||
version.properties
|
version.properties
|
||||||
|
.vscode/
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ plugins {
|
|||||||
id 'kotlin-android'
|
id 'kotlin-android'
|
||||||
id 'com.google.dagger.hilt.android'
|
id 'com.google.dagger.hilt.android'
|
||||||
id 'kotlin-kapt'
|
id 'kotlin-kapt'
|
||||||
|
id 'com.google.devtools.ksp'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a variable called keystorePropertiesFile, and initialize it to your
|
// Create a variable called keystorePropertiesFile, and initialize it to your
|
||||||
@@ -67,7 +68,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
composeOptions {
|
composeOptions {
|
||||||
kotlinCompilerExtensionVersion = "1.4.8"
|
kotlinCompilerExtensionVersion = "1.5.14"
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
@@ -88,44 +89,44 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||||
implementation 'androidx.core:core-ktx:1.10.1'
|
implementation 'androidx.core:core-ktx:1.13.1'
|
||||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
implementation 'androidx.appcompat:appcompat:1.7.0'
|
||||||
implementation "androidx.compose.material3:material3:1.1.1"
|
implementation "androidx.compose.material3:material3:1.2.1"
|
||||||
implementation 'com.google.android.play:core-ktx:1.8.1'
|
implementation 'com.google.android.play:review:2.0.1'
|
||||||
implementation 'com.google.android.play:core-ktx:1.8.1'
|
implementation 'com.google.android.play:review-ktx:2.0.1'
|
||||||
implementation 'com.google.code.gson:gson:2.9.0'
|
implementation 'com.google.code.gson:gson:2.10.1'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.1'
|
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7'
|
||||||
implementation 'androidx.navigation:navigation-ui-ktx:2.7.1'
|
implementation 'androidx.navigation:navigation-ui-ktx:2.7.7'
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'
|
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.4'
|
||||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
|
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4'
|
||||||
implementation 'androidx.fragment:fragment-ktx:1.6.1'
|
implementation 'androidx.fragment:fragment-ktx:1.8.2'
|
||||||
implementation 'androidx.preference:preference-ktx:1.2.1'
|
implementation 'androidx.preference:preference-ktx:1.2.1'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.3.1'
|
implementation 'androidx.recyclerview:recyclerview:1.3.2'
|
||||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
|
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.4'
|
||||||
implementation 'androidx.compose.material:material-icons-extended:1.5.0'
|
implementation 'androidx.compose.material:material-icons-extended:1.6.8'
|
||||||
implementation "com.google.accompanist:accompanist-systemuicontroller:0.27.0"
|
implementation "com.google.accompanist:accompanist-systemuicontroller:0.27.0"
|
||||||
implementation 'androidx.activity:activity-compose:1.7.2'
|
implementation 'androidx.activity:activity-compose:1.9.1'
|
||||||
implementation "androidx.compose.ui:ui:1.5.0"
|
implementation "androidx.compose.ui:ui:1.6.8"
|
||||||
implementation "androidx.compose.ui:ui-tooling-preview:1.5.0"
|
implementation "androidx.compose.ui:ui-tooling-preview:1.6.8"
|
||||||
implementation "androidx.compose.runtime:runtime-livedata:1.5.0"
|
implementation "androidx.compose.runtime:runtime-livedata:1.6.8"
|
||||||
implementation "androidx.navigation:navigation-compose:2.7.1"
|
implementation "androidx.navigation:navigation-compose:2.7.7"
|
||||||
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1"
|
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4"
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
|
||||||
implementation "com.google.dagger:hilt-android:2.44"
|
implementation "com.google.dagger:hilt-android:2.51.1"
|
||||||
androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.5.0"
|
androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.6.8"
|
||||||
debugImplementation "androidx.compose.ui:ui-tooling:1.5.0"
|
debugImplementation "androidx.compose.ui:ui-tooling:1.6.8"
|
||||||
debugImplementation "androidx.compose.ui:ui-test-manifest:1.5.0"
|
debugImplementation "androidx.compose.ui:ui-test-manifest:1.6.8"
|
||||||
kapt "com.google.dagger:hilt-compiler:2.44"
|
kapt "com.google.dagger:hilt-compiler:2.51.1"
|
||||||
implementation "androidx.room:room-runtime:2.5.2"
|
annotationProcessor "androidx.room:room-compiler:2.6.1"
|
||||||
annotationProcessor "androidx.room:room-compiler:2.5.2"
|
implementation "androidx.room:room-runtime:2.6.1"
|
||||||
kapt "androidx.room:room-compiler:2.5.2"
|
ksp "androidx.room:room-compiler:2.6.1"
|
||||||
implementation "androidx.room:room-ktx:2.5.2"
|
implementation "androidx.room:room-ktx:2.6.1"
|
||||||
implementation "androidx.multidex:multidex:2.0.1"
|
implementation "androidx.multidex:multidex:2.0.1"
|
||||||
api "androidx.navigation:navigation-fragment-ktx:2.7.1"
|
api "androidx.navigation:navigation-fragment-ktx:2.7.7"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow references to generated code
|
// Allow references to generated code
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.outlined.List
|
||||||
|
import androidx.compose.material.icons.automirrored.outlined.Redo
|
||||||
|
import androidx.compose.material.icons.automirrored.outlined.Undo
|
||||||
import androidx.compose.material.icons.outlined.Calculate
|
import androidx.compose.material.icons.outlined.Calculate
|
||||||
import androidx.compose.material.icons.outlined.Info
|
import androidx.compose.material.icons.outlined.Info
|
||||||
import androidx.compose.material.icons.outlined.Keyboard
|
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.MoreVert
|
||||||
import androidx.compose.material.icons.outlined.Redo
|
|
||||||
import androidx.compose.material.icons.outlined.Settings
|
import androidx.compose.material.icons.outlined.Settings
|
||||||
import androidx.compose.material.icons.outlined.Undo
|
|
||||||
import androidx.compose.material3.DrawerState
|
import androidx.compose.material3.DrawerState
|
||||||
import androidx.compose.material3.DrawerValue
|
import androidx.compose.material3.DrawerValue
|
||||||
import androidx.compose.material3.FloatingActionButton
|
import androidx.compose.material3.FloatingActionButton
|
||||||
@@ -166,7 +166,11 @@ class MainActivity : AppCompatActivity() {
|
|||||||
Icons.Outlined.Calculate,
|
Icons.Outlined.Calculate,
|
||||||
stringResource(R.string.menu_counter)
|
stringResource(R.string.menu_counter)
|
||||||
),
|
),
|
||||||
DrawerItem(Route.HISTORY, Icons.Outlined.List, stringResource(R.string.menu_history)),
|
DrawerItem(
|
||||||
|
Route.HISTORY,
|
||||||
|
Icons.AutoMirrored.Outlined.List,
|
||||||
|
stringResource(R.string.menu_history)
|
||||||
|
),
|
||||||
DrawerItem(
|
DrawerItem(
|
||||||
Route.SETTINGS,
|
Route.SETTINGS,
|
||||||
Icons.Outlined.Settings,
|
Icons.Outlined.Settings,
|
||||||
@@ -217,7 +221,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
var topBarState by remember { mutableStateOf(TopBarState()) }
|
var topBarState by remember { mutableStateOf(TopBarState()) }
|
||||||
var snackbarHostState by remember { mutableStateOf(SnackbarHostState()) }
|
val snackbarHostState by remember { mutableStateOf(SnackbarHostState()) }
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
snackbarHost = { SnackbarHost(snackbarHostState) },
|
snackbarHost = { SnackbarHost(snackbarHostState) },
|
||||||
@@ -236,7 +240,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
startDestination = Route.COUNTER.name,
|
startDestination = Route.COUNTER.name,
|
||||||
modifier = Modifier.padding(paddings)
|
modifier = Modifier.padding(paddings)
|
||||||
) {
|
) {
|
||||||
this.composable(Route.COUNTER.name.toString()) {
|
this.composable(Route.COUNTER.name) {
|
||||||
|
|
||||||
var expanded by remember { mutableStateOf(false) }
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
@@ -244,11 +248,11 @@ class MainActivity : AppCompatActivity() {
|
|||||||
title = stringResource(R.string.app_name),
|
title = stringResource(R.string.app_name),
|
||||||
actions = (listOf(
|
actions = (listOf(
|
||||||
TopBarAction(
|
TopBarAction(
|
||||||
Icons.Outlined.Undo,
|
Icons.AutoMirrored.Outlined.Undo,
|
||||||
mainViewModel.isUndoActionActive,
|
mainViewModel.isUndoActionActive,
|
||||||
{ mainViewModel.undoLastRound() }),
|
{ mainViewModel.undoLastRound() }),
|
||||||
TopBarAction(
|
TopBarAction(
|
||||||
Icons.Outlined.Redo,
|
Icons.AutoMirrored.Outlined.Redo,
|
||||||
mainViewModel.isRedoActionActive,
|
mainViewModel.isRedoActionActive,
|
||||||
{ mainViewModel.redoLastRound() }),
|
{ mainViewModel.redoLastRound() }),
|
||||||
TopBarAction(
|
TopBarAction(
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package me.zobrist.tichucounter.data
|
package me.zobrist.tichucounter.data
|
||||||
|
|
||||||
import androidx.room.*
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Query
|
||||||
|
import androidx.room.Transaction
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import me.zobrist.tichucounter.data.entity.Game
|
import me.zobrist.tichucounter.data.entity.Game
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package me.zobrist.tichucounter.data
|
package me.zobrist.tichucounter.data
|
||||||
|
|
||||||
import androidx.room.*
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Query
|
||||||
import me.zobrist.tichucounter.data.entity.Round
|
import me.zobrist.tichucounter.data.entity.Round
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ class ReviewService @Inject constructor(@ActivityContext private val appContext:
|
|||||||
val reviewInfo = task.result
|
val reviewInfo = task.result
|
||||||
manager.launchReviewFlow(appContext as Activity, reviewInfo)
|
manager.launchReviewFlow(appContext as Activity, reviewInfo)
|
||||||
|
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,7 @@ class GameRepository @Inject constructor(
|
|||||||
private val roundDao: RoundDao
|
private val roundDao: RoundDao
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var activeGame: Game = Game(true, "TeamA", "TeamB", Date(), Date())
|
private var activeGame: Game = Game(true, "TeamA", "TeamB", Date(), Date())
|
||||||
private set
|
|
||||||
|
|
||||||
private val newGameFlow = MutableStateFlow(Game())
|
private val newGameFlow = MutableStateFlow(Game())
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ import androidx.compose.material3.TextField
|
|||||||
import androidx.compose.material3.TextFieldColors
|
import androidx.compose.material3.TextFieldColors
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.input.key.Key
|
import androidx.compose.ui.input.key.Key
|
||||||
@@ -26,7 +26,7 @@ import androidx.compose.ui.platform.LocalFocusManager
|
|||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun TypeaheadTextField(
|
fun TypeaheadTextField(
|
||||||
value: String,
|
value: String,
|
||||||
@@ -46,7 +46,7 @@ fun TypeaheadTextField(
|
|||||||
onExpandedChange = {}
|
onExpandedChange = {}
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var dropDownWidth by remember { mutableStateOf(0) }
|
var dropDownWidth by remember { mutableIntStateOf(0) }
|
||||||
|
|
||||||
TextField(
|
TextField(
|
||||||
value = value,
|
value = value,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@@ -28,7 +28,7 @@ import me.zobrist.tichucounter.ui.AppTheme
|
|||||||
@Composable
|
@Composable
|
||||||
fun Counter(viewModel: ICounterViewModel = PreviewViewModel()) {
|
fun Counter(viewModel: ICounterViewModel = PreviewViewModel()) {
|
||||||
|
|
||||||
var orientation by remember { mutableStateOf(Configuration.ORIENTATION_PORTRAIT) }
|
var orientation by remember { mutableIntStateOf(Configuration.ORIENTATION_PORTRAIT) }
|
||||||
orientation = LocalConfiguration.current.orientation
|
orientation = LocalConfiguration.current.orientation
|
||||||
|
|
||||||
if (viewModel.showVictoryDialog) {
|
if (viewModel.showVictoryDialog) {
|
||||||
@@ -122,7 +122,7 @@ fun CounterViewPreview() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview()
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun GameVictoryDialog(
|
fun GameVictoryDialog(
|
||||||
pointsA: Int = 2000,
|
pointsA: Int = 2000,
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.wrapContentWidth
|
import androidx.compose.foundation.layout.wrapContentWidth
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.Backspace
|
import androidx.compose.material.icons.automirrored.outlined.Backspace
|
||||||
import androidx.compose.material.icons.outlined.Check
|
import androidx.compose.material.icons.outlined.Check
|
||||||
import androidx.compose.material.icons.outlined.KeyboardHide
|
import androidx.compose.material.icons.outlined.KeyboardHide
|
||||||
import androidx.compose.material.icons.outlined.SwapHoriz
|
import androidx.compose.material.icons.outlined.SwapHoriz
|
||||||
import androidx.compose.material3.Divider
|
|
||||||
import androidx.compose.material3.ElevatedButton
|
import androidx.compose.material3.ElevatedButton
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
@@ -198,7 +198,7 @@ fun KeyboardView(
|
|||||||
deleteButtonPressedState(deletePressed)
|
deleteButtonPressedState(deletePressed)
|
||||||
|
|
||||||
KeyboardIconButton(
|
KeyboardIconButton(
|
||||||
icon = Icons.Outlined.Backspace,
|
icon = Icons.AutoMirrored.Outlined.Backspace,
|
||||||
interactionSource = interactionSource
|
interactionSource = interactionSource
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
@@ -330,7 +330,7 @@ fun CenteredTextField(
|
|||||||
Row {
|
Row {
|
||||||
|
|
||||||
Text(text = value, color = cursorColor.copy(alpha = 0f))
|
Text(text = value, color = cursorColor.copy(alpha = 0f))
|
||||||
Divider(
|
HorizontalDivider(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(start = 3.dp, top = 15.dp, bottom = 15.dp)
|
.padding(start = 3.dp, top = 15.dp, bottom = 15.dp)
|
||||||
.width(1.dp)
|
.width(1.dp)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.Row
|
|||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
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.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
@@ -25,18 +26,17 @@ import androidx.compose.material3.AlertDialog
|
|||||||
import androidx.compose.material3.Badge
|
import androidx.compose.material3.Badge
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.DismissDirection
|
|
||||||
import androidx.compose.material3.DismissValue
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.SnackbarDuration
|
import androidx.compose.material3.SnackbarDuration
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.material3.SnackbarResult
|
import androidx.compose.material3.SnackbarResult
|
||||||
import androidx.compose.material3.SwipeToDismiss
|
import androidx.compose.material3.SwipeToDismissBox
|
||||||
|
import androidx.compose.material3.SwipeToDismissBoxValue
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.material3.rememberDismissState
|
import androidx.compose.material3.rememberSwipeToDismissBoxState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -213,89 +213,113 @@ fun DismissibleHistoryListItem(
|
|||||||
|
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
val dismissState =
|
val dismissState =
|
||||||
rememberDismissState(positionalThreshold = { with(density) { 100.dp.toPx() } },
|
rememberSwipeToDismissBoxState(positionalThreshold = { with(density) { 100.dp.toPx() } },
|
||||||
|
|
||||||
confirmValueChange = {
|
confirmValueChange = {
|
||||||
if (it == DismissValue.DismissedToStart) {
|
if (it == SwipeToDismissBoxValue.EndToStart) {
|
||||||
onDeleteClicked(game.game.uid)
|
onDeleteClicked(game.game.uid)
|
||||||
}
|
}
|
||||||
if (it == DismissValue.DismissedToEnd) {
|
if (it == SwipeToDismissBoxValue.StartToEnd) {
|
||||||
onOpenClicked(game.game.uid)
|
onOpenClicked(game.game.uid)
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
})
|
})
|
||||||
|
|
||||||
val directions = if (game.game.active) {
|
SwipeToDismissBox(
|
||||||
setOf()
|
|
||||||
|
|
||||||
} else {
|
|
||||||
setOf(DismissDirection.EndToStart, DismissDirection.StartToEnd)
|
|
||||||
}
|
|
||||||
|
|
||||||
SwipeToDismiss(
|
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
state = dismissState,
|
state = dismissState,
|
||||||
directions = directions,
|
enableDismissFromEndToStart = true,
|
||||||
background = {
|
enableDismissFromStartToEnd = true,
|
||||||
val direction = dismissState.dismissDirection ?: return@SwipeToDismiss
|
backgroundContent = {
|
||||||
val color by animateColorAsState(
|
ItemBackground(dismissState.targetValue)
|
||||||
when (dismissState.targetValue) {
|
}, content = {
|
||||||
DismissValue.DismissedToStart -> MaterialTheme.colorScheme.error
|
|
||||||
DismissValue.DismissedToEnd -> MaterialTheme.colorScheme.primary
|
|
||||||
else -> MaterialTheme.colorScheme.background
|
|
||||||
|
|
||||||
}, label = ""
|
|
||||||
)
|
|
||||||
val textColor by animateColorAsState(
|
|
||||||
when (dismissState.targetValue) {
|
|
||||||
DismissValue.DismissedToStart -> MaterialTheme.colorScheme.onError
|
|
||||||
DismissValue.DismissedToEnd -> MaterialTheme.colorScheme.onPrimary
|
|
||||||
else -> MaterialTheme.colorScheme.onBackground
|
|
||||||
|
|
||||||
}, 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 = ""
|
|
||||||
)
|
|
||||||
|
|
||||||
Box(
|
|
||||||
Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(top = 2.dp, bottom = 2.dp)
|
|
||||||
.background(color)
|
|
||||||
.padding(horizontal = 10.dp),
|
|
||||||
contentAlignment = alignment
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
icon,
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier.scale(scale),
|
|
||||||
tint = textColor
|
|
||||||
)
|
|
||||||
Text(text = text, color = textColor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, dismissContent = {
|
|
||||||
HistoryListItem(game = game, modifier = Modifier.padding(2.dp))
|
HistoryListItem(game = game, modifier = Modifier.padding(2.dp))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun ItemBackground(
|
||||||
|
dismissBoxValue: SwipeToDismissBoxValue
|
||||||
|
) {
|
||||||
|
val backgroundColor by animateColorAsState(
|
||||||
|
when (dismissBoxValue) {
|
||||||
|
SwipeToDismissBoxValue.EndToStart -> MaterialTheme.colorScheme.error
|
||||||
|
SwipeToDismissBoxValue.StartToEnd -> MaterialTheme.colorScheme.primary
|
||||||
|
else -> MaterialTheme.colorScheme.background
|
||||||
|
|
||||||
|
}, label = ""
|
||||||
|
)
|
||||||
|
val textColor by animateColorAsState(
|
||||||
|
when (dismissBoxValue) {
|
||||||
|
SwipeToDismissBoxValue.EndToStart -> MaterialTheme.colorScheme.onError
|
||||||
|
SwipeToDismissBoxValue.StartToEnd -> MaterialTheme.colorScheme.onPrimary
|
||||||
|
else -> MaterialTheme.colorScheme.onBackground
|
||||||
|
|
||||||
|
}, label = ""
|
||||||
|
)
|
||||||
|
val scale by animateFloatAsState(
|
||||||
|
if (dismissBoxValue == SwipeToDismissBoxValue.Settled) 0.75f else 1f, label = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
Box(
|
||||||
|
Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(top = 2.dp, bottom = 2.dp)
|
||||||
|
.background(backgroundColor)
|
||||||
|
.padding(horizontal = 10.dp),
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier.align(Alignment.CenterStart)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Outlined.RestartAlt,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = textColor,
|
||||||
|
modifier = Modifier.scale(scale),
|
||||||
|
)
|
||||||
|
Text(text = stringResource(id = R.string.continue_play), color = textColor)
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier.align(Alignment.CenterEnd)
|
||||||
|
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Outlined.Delete,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = textColor,
|
||||||
|
modifier = Modifier.scale(scale),
|
||||||
|
)
|
||||||
|
Text(text = stringResource(id = R.string.delete), color = textColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun BackgroundPreview() {
|
||||||
|
Column {
|
||||||
|
Box(modifier = Modifier.height(60.dp))
|
||||||
|
{
|
||||||
|
ItemBackground(SwipeToDismissBoxValue.Settled)
|
||||||
|
}
|
||||||
|
Box(modifier = Modifier.height(60.dp))
|
||||||
|
{
|
||||||
|
ItemBackground(SwipeToDismissBoxValue.EndToStart)
|
||||||
|
}
|
||||||
|
Box(modifier = Modifier.height(60.dp))
|
||||||
|
{
|
||||||
|
ItemBackground(SwipeToDismissBoxValue.StartToEnd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HistoryListItem(
|
fun HistoryListItem(
|
||||||
game: GameWithScores, modifier: Modifier = Modifier
|
game: GameWithScores, modifier: Modifier = Modifier
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ package me.zobrist.tichucounter.ui.layout
|
|||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.outlined.List
|
||||||
import androidx.compose.material.icons.outlined.Calculate
|
import androidx.compose.material.icons.outlined.Calculate
|
||||||
import androidx.compose.material.icons.outlined.List
|
|
||||||
import androidx.compose.material.icons.outlined.Settings
|
import androidx.compose.material.icons.outlined.Settings
|
||||||
import androidx.compose.material3.Divider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.ModalDrawerSheet
|
import androidx.compose.material3.ModalDrawerSheet
|
||||||
@@ -38,7 +38,7 @@ fun DrawerContent(
|
|||||||
text = stringResource(R.string.app_name),
|
text = stringResource(R.string.app_name),
|
||||||
style = MaterialTheme.typography.headlineSmall
|
style = MaterialTheme.typography.headlineSmall
|
||||||
)
|
)
|
||||||
Divider(modifier = Modifier.padding(10.dp))
|
HorizontalDivider(modifier = Modifier.padding(10.dp))
|
||||||
|
|
||||||
drawerItems.forEach { screen ->
|
drawerItems.forEach { screen ->
|
||||||
NavigationDrawerItem(
|
NavigationDrawerItem(
|
||||||
@@ -58,7 +58,7 @@ fun DrawerContent(
|
|||||||
fun DrawerContentPreview() {
|
fun DrawerContentPreview() {
|
||||||
|
|
||||||
val counter = DrawerItem(Route.COUNTER, Icons.Outlined.Calculate, "Counter")
|
val counter = DrawerItem(Route.COUNTER, Icons.Outlined.Calculate, "Counter")
|
||||||
val history = DrawerItem(Route.HISTORY, Icons.Outlined.List, "History")
|
val history = DrawerItem(Route.HISTORY, Icons.AutoMirrored.Outlined.List, "History")
|
||||||
val settings = DrawerItem(Route.SETTINGS, Icons.Outlined.Settings, "Settings")
|
val settings = DrawerItem(Route.SETTINGS, Icons.Outlined.Settings, "Settings")
|
||||||
AppTheme {
|
AppTheme {
|
||||||
Surface {
|
Surface {
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package me.zobrist.tichucounter.ui.layout
|
package me.zobrist.tichucounter.ui.layout
|
||||||
|
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
|||||||
11
build.gradle
11
build.gradle
@@ -1,12 +1,12 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = "1.8.22"
|
ext.kotlin_version = "1.9.24"
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:8.1.2'
|
classpath 'com.android.tools.build:gradle:8.5.2'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
@@ -15,8 +15,9 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.google.dagger.hilt.android' version '2.44' apply false
|
id 'com.google.dagger.hilt.android' version '2.51.1' apply false
|
||||||
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
|
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
|
||||||
|
id 'com.google.devtools.ksp' version '1.9.24-1.0.20' apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
@@ -25,7 +26,3 @@ allprojects {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register('clean', Delete) {
|
|
||||||
delete rootProject.buildDir
|
|
||||||
}
|
|
||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
|
||||||
|
|||||||
Reference in New Issue
Block a user