diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 378c185..032aeb0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -34,7 +34,7 @@ android { defaultConfig { applicationId = appId minSdk = 24 - targetSdk = 34 + targetSdk = 35 versionCode = 18 versionName = "1.0.18" vectorDrawables.useSupportLibrary = true diff --git a/app/src/main/java/io/github/yamin8000/dooz/content/MainActivity.kt b/app/src/main/java/io/github/yamin8000/dooz/content/MainActivity.kt index b0511b3..a9d025d 100644 --- a/app/src/main/java/io/github/yamin8000/dooz/content/MainActivity.kt +++ b/app/src/main/java/io/github/yamin8000/dooz/content/MainActivity.kt @@ -24,10 +24,12 @@ package io.github.yamin8000.dooz.content import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge import androidx.core.view.WindowCompat internal class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { + enableEdgeToEdge() super.onCreate(savedInstanceState) setContent { MainNavigation() } WindowCompat.setDecorFitsSystemWindows(window, false) diff --git a/app/src/main/java/io/github/yamin8000/dooz/content/MainTopAppBar.kt b/app/src/main/java/io/github/yamin8000/dooz/content/MainTopAppBar.kt index fff94fb..1f695cf 100644 --- a/app/src/main/java/io/github/yamin8000/dooz/content/MainTopAppBar.kt +++ b/app/src/main/java/io/github/yamin8000/dooz/content/MainTopAppBar.kt @@ -20,25 +20,15 @@ package io.github.yamin8000.dooz.content -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.twotone.Help import androidx.compose.material.icons.twotone.Settings import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import io.github.yamin8000.dooz.R import io.github.yamin8000.dooz.ui.composables.AnimatedAppIcon @@ -91,20 +81,4 @@ private fun SettingsIcon( contentDescription = stringResource(R.string.settings), onClick = onSettingsIconClick ) -} - -@Composable -private fun NavigationIcon( - appName: String -) { - Icon( - painter = painterResource(R.drawable.ic_launcher_foreground), - contentDescription = appName, - tint = MaterialTheme.colorScheme.background, - modifier = Modifier - .padding(8.dp) - .size(32.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.onBackground) - ) } \ No newline at end of file diff --git a/app/src/main/java/io/github/yamin8000/dooz/content/game/GameContent.kt b/app/src/main/java/io/github/yamin8000/dooz/content/game/GameContent.kt index 87cdb8d..dd42c00 100644 --- a/app/src/main/java/io/github/yamin8000/dooz/content/game/GameContent.kt +++ b/app/src/main/java/io/github/yamin8000/dooz/content/game/GameContent.kt @@ -48,7 +48,6 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.twotone.Undo import androidx.compose.material.icons.twotone.Games -import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.BottomAppBar import androidx.compose.material3.Card import androidx.compose.material3.ExperimentalMaterial3Api @@ -59,6 +58,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment @@ -329,7 +329,7 @@ private fun DoozItem( .background(backgroundColor) .clickable( interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(), + indication = ripple(), enabled = clickable, onClick = onClick ), diff --git a/app/src/main/java/io/github/yamin8000/dooz/content/game/GameState.kt b/app/src/main/java/io/github/yamin8000/dooz/content/game/GameState.kt index 1f1079a..fb53476 100644 --- a/app/src/main/java/io/github/yamin8000/dooz/content/game/GameState.kt +++ b/app/src/main/java/io/github/yamin8000/dooz/content/game/GameState.kt @@ -34,16 +34,21 @@ import androidx.compose.ui.hapticfeedback.HapticFeedback import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalHapticFeedback -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.lifecycle.LifecycleCoroutineScope +import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.lifecycleScope import io.github.yamin8000.dooz.R import io.github.yamin8000.dooz.content.settings import io.github.yamin8000.dooz.game.FirstPlayerPolicy -import io.github.yamin8000.dooz.game.GameConstants.gameDefaultSize +import io.github.yamin8000.dooz.game.GameConstants.GAME_DEFAULT_SIZE import io.github.yamin8000.dooz.game.logic.GameLogic import io.github.yamin8000.dooz.game.logic.SimpleGameLogic -import io.github.yamin8000.dooz.model.* +import io.github.yamin8000.dooz.model.AiDifficulty +import io.github.yamin8000.dooz.model.DoozCell +import io.github.yamin8000.dooz.model.GamePlayersType +import io.github.yamin8000.dooz.model.GameType +import io.github.yamin8000.dooz.model.Player +import io.github.yamin8000.dooz.model.PlayerType import io.github.yamin8000.dooz.ui.RingShape import io.github.yamin8000.dooz.ui.XShape import io.github.yamin8000.dooz.ui.toName @@ -154,7 +159,7 @@ class GameState( } private suspend fun prepareGameRules() { - gameSize.intValue = dataStore.getInt(Constants.gameSize) ?: gameDefaultSize + gameSize.intValue = dataStore.getInt(Constants.gameSize) ?: GAME_DEFAULT_SIZE gamePlayersType.value = GamePlayersType.valueOf( dataStore.getString(Constants.gamePlayersType) ?: GamePlayersType.PvC.name ) @@ -370,7 +375,7 @@ fun rememberHomeState( context: Context = LocalContext.current, coroutineScope: LifecycleCoroutineScope = LocalLifecycleOwner.current.lifecycleScope, doozCells: MutableState>> = rememberSaveable { mutableStateOf(emptyList()) }, - gameSize: MutableIntState = rememberSaveable { mutableIntStateOf(gameDefaultSize) }, + gameSize: MutableIntState = rememberSaveable { mutableIntStateOf(GAME_DEFAULT_SIZE) }, currentPlayer: MutableState = rememberSaveable { mutableStateOf(null) }, players: MutableState> = rememberSaveable { mutableStateOf(listOf()) }, gamePlayersType: MutableState = rememberSaveable { diff --git a/app/src/main/java/io/github/yamin8000/dooz/content/game/PlayersInfoContent.kt b/app/src/main/java/io/github/yamin8000/dooz/content/game/PlayersInfoContent.kt index 8a1e58d..5e0fead 100644 --- a/app/src/main/java/io/github/yamin8000/dooz/content/game/PlayersInfoContent.kt +++ b/app/src/main/java/io/github/yamin8000/dooz/content/game/PlayersInfoContent.kt @@ -20,12 +20,16 @@ package io.github.yamin8000.dooz.content.game -import androidx.compose.animation.* +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutVertically +import androidx.compose.animation.togetherWith import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.ContentAlpha import androidx.compose.material3.Icon import androidx.compose.material3.OutlinedCard import androidx.compose.runtime.Composable @@ -80,7 +84,7 @@ internal fun PlayerCard( firstPlayerPolicy: FirstPlayerPolicy, isCurrentPlayer: Boolean = true ) { - val alpha = if (isCurrentPlayer) ContentAlpha.high else ContentAlpha.disabled + val alpha = if (isCurrentPlayer) 1f else .38f OutlinedCard( modifier = modifier.alpha(alpha) diff --git a/app/src/main/java/io/github/yamin8000/dooz/content/settings/SettingsState.kt b/app/src/main/java/io/github/yamin8000/dooz/content/settings/SettingsState.kt index 4e80cc5..c4af2c0 100644 --- a/app/src/main/java/io/github/yamin8000/dooz/content/settings/SettingsState.kt +++ b/app/src/main/java/io/github/yamin8000/dooz/content/settings/SettingsState.kt @@ -30,7 +30,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalLifecycleOwner +import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.lifecycleScope import io.github.yamin8000.dooz.R @@ -170,7 +170,7 @@ class SettingsState( _gamePlayersType.value = GamePlayersType.valueOf( dataStore.getString(Constants.gamePlayersType) ?: GamePlayersType.PvC.name ) - _gameSize.intValue = dataStore.getInt(Constants.gameSize) ?: GameConstants.gameDefaultSize + _gameSize.intValue = dataStore.getInt(Constants.gameSize) ?: GameConstants.GAME_DEFAULT_SIZE _firstPlayerName.value = dataStore.getString(Constants.firstPlayerName) ?: defaultFirstPlayerName _secondPlayerName.value = @@ -199,7 +199,7 @@ fun rememberSettingsState( gamePlayersType: MutableState = rememberSaveable { mutableStateOf(GamePlayersType.PvC) }, - gameSize: MutableIntState = rememberSaveable { mutableIntStateOf(GameConstants.gameDefaultSize) }, + gameSize: MutableIntState = rememberSaveable { mutableIntStateOf(GameConstants.GAME_DEFAULT_SIZE) }, firstPlayerName: MutableState = rememberSaveable { mutableStateOf(context.getString(R.string.first_player_default_name)) }, secondPlayerName: MutableState = rememberSaveable { mutableStateOf(context.getString(R.string.second_player_default_name)) }, firstPlayerShape: MutableState = rememberSaveable { mutableStateOf(Constants.Shapes.xShape) }, diff --git a/app/src/main/java/io/github/yamin8000/dooz/game/GameConstants.kt b/app/src/main/java/io/github/yamin8000/dooz/game/GameConstants.kt index 59397f4..17ebe1f 100644 --- a/app/src/main/java/io/github/yamin8000/dooz/game/GameConstants.kt +++ b/app/src/main/java/io/github/yamin8000/dooz/game/GameConstants.kt @@ -22,5 +22,5 @@ package io.github.yamin8000.dooz.game object GameConstants { val gameSizeRange = 3..7 - const val gameDefaultSize = 3 + const val GAME_DEFAULT_SIZE = 3 } \ No newline at end of file diff --git a/app/src/main/java/io/github/yamin8000/dooz/ui/Shapes.kt b/app/src/main/java/io/github/yamin8000/dooz/ui/Shapes.kt index f509357..11c6291 100644 --- a/app/src/main/java/io/github/yamin8000/dooz/ui/Shapes.kt +++ b/app/src/main/java/io/github/yamin8000/dooz/ui/Shapes.kt @@ -32,8 +32,8 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.GenericShape import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf @@ -195,7 +195,7 @@ fun ClickableShape( .size(size) .clickable( interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(), + indication = ripple(), onClick = onClick ), content = { diff --git a/app/src/main/java/io/github/yamin8000/dooz/ui/composables/Composables.kt b/app/src/main/java/io/github/yamin8000/dooz/ui/composables/Composables.kt index dcec694..67ac8ec 100644 --- a/app/src/main/java/io/github/yamin8000/dooz/ui/composables/Composables.kt +++ b/app/src/main/java/io/github/yamin8000/dooz/ui/composables/Composables.kt @@ -28,7 +28,6 @@ import androidx.compose.animation.core.VectorConverter import androidx.compose.animation.core.animate import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.tween -import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable @@ -36,35 +35,22 @@ import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.ime import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.items -import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.twotone.ArrowBack -import androidx.compose.material.ripple.rememberRipple -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonColors -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.ButtonElevation import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.RadioButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Snackbar import androidx.compose.material3.SnackbarDefaults @@ -73,6 +59,7 @@ import androidx.compose.material3.Switch import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarScrollBehavior +import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect @@ -83,7 +70,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.input.nestedscroll.nestedScroll @@ -111,52 +97,13 @@ fun Ripple( content = content, modifier = modifier.combinedClickable( interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(), + indication = ripple(), onClick = onClick, onLongClick = onLongClick ) ) } -@Composable -fun ButtonWithIcon( - onClick: () -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, - shape: Shape = ButtonDefaults.shape, - colors: ButtonColors = ButtonDefaults.buttonColors(), - elevation: ButtonElevation? = ButtonDefaults.buttonElevation(), - border: BorderStroke? = null, - contentPadding: PaddingValues = ButtonDefaults.ContentPadding, - interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, - icon: @Composable () -> Unit, - content: @Composable RowScope.() -> Unit, -) { - Button( - onClick = onClick, - modifier = modifier, - enabled = enabled, - shape = shape, - colors = colors, - elevation = elevation, - border = border, - contentPadding = contentPadding, - interactionSource = interactionSource, - content = { - Row( - modifier = modifier.fillMaxSize(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterHorizontally), - content = { - if (isFontScaleNormal()) - icon() - content() - } - ) - } - ) -} - @Composable fun MySnackbar( modifier: Modifier = Modifier, @@ -215,52 +162,6 @@ fun SwitchWithText( ) } -@Composable -fun RadioGroup( - //unstable - columns: GridCells = GridCells.Fixed(2), - options: List, - currentOption: T, - onOptionChange: (T) -> Unit, - optionStringProvider: (T) -> String -) { - LazyVerticalGrid( - modifier = Modifier.height(100.dp), - verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterVertically), - horizontalArrangement = Arrangement.spacedBy(16.dp), - columns = columns, - content = { - items(options) { option -> - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(4.dp), - modifier = Modifier - .selectable( - selected = (option == currentOption), - onClick = { onOptionChange(option) }, - role = Role.RadioButton - ), - content = { - PersianText( - text = optionStringProvider(option), - modifier = Modifier - .padding(vertical = 16.dp, horizontal = 2.dp) - .weight(5f) - ) - RadioButton( - selected = (option == currentOption), - onClick = null, - modifier = Modifier - .padding(4.dp) - .weight(1f) - ) - } - ) - } - } - ) -} - @Composable fun ClickableIcon( modifier: Modifier = Modifier, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4895a7e..5f3135a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,12 +1,12 @@ [versions] -activityCompose = "1.9.1" -composeLibs = "1.6.8" +activityCompose = "1.9.2" +composeLibs = "1.7.0" coreKtx = "1.13.1" datastorePreferences = "1.1.1" -material3 = "1.2.1" -navigationCompose = "2.7.7" -kotlin = "2.0.10" -android-application = "8.5.2" +material3 = "1.3.0" +navigationCompose = "2.8.0" +kotlin = "2.0.20" +android-application = "8.6.0" [libraries] androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activityCompose" }