summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-07-02 16:56:37 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-07-02 16:56:37 +0330
commitc71241a13c9ab8afb9999d05dfa1d3c6721d2fc7 (patch)
tree783829b37de74e0e38fad4b307adda5241d21bd4
parentae2cb569694734d2d9c1c1eb60e73cff46dab8e5 (diff)
better page animation
-rw-r--r--app/build.gradle.kts4
-rw-r--r--app/release/app-release.apkbin1214911 -> 1214911 bytes
-rw-r--r--app/release/baselineProfiles/0/app-release.dmbin4722 -> 4005 bytes
-rw-r--r--app/release/baselineProfiles/1/app-release.dmbin4683 -> 3964 bytes
-rw-r--r--app/release/output-metadata.json4
-rw-r--r--app/src/main/java/com/a404m/mine_game/ui/page/Game.kt22
-rw-r--r--app/src/main/java/com/a404m/mine_game/ui/page/Route.kt71
-rw-r--r--app/src/main/java/com/a404m/mine_game/ui/utils/modifier/Extension.kt74
8 files changed, 123 insertions, 52 deletions
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 1599144..cb523e2 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -12,8 +12,8 @@ android {
applicationId = "com.a404m.mine_game"
minSdk = 24
targetSdk = 36
- versionCode = 3
- versionName = "0.2.1"
+ versionCode = 4
+ versionName = "0.2.2"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
diff --git a/app/release/app-release.apk b/app/release/app-release.apk
index bf4e7d0..243c95d 100644
--- a/app/release/app-release.apk
+++ b/app/release/app-release.apk
Binary files differ
diff --git a/app/release/baselineProfiles/0/app-release.dm b/app/release/baselineProfiles/0/app-release.dm
index e9b3a6e..f0ae0d6 100644
--- a/app/release/baselineProfiles/0/app-release.dm
+++ b/app/release/baselineProfiles/0/app-release.dm
Binary files differ
diff --git a/app/release/baselineProfiles/1/app-release.dm b/app/release/baselineProfiles/1/app-release.dm
index 1bbb929..dcd7671 100644
--- a/app/release/baselineProfiles/1/app-release.dm
+++ b/app/release/baselineProfiles/1/app-release.dm
Binary files differ
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
index c560e47..c06fbb5 100644
--- a/app/release/output-metadata.json
+++ b/app/release/output-metadata.json
@@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
- "versionCode": 3,
- "versionName": "0.2.1",
+ "versionCode": 4,
+ "versionName": "0.2.2",
"outputFile": "app-release.apk"
}
],
diff --git a/app/src/main/java/com/a404m/mine_game/ui/page/Game.kt b/app/src/main/java/com/a404m/mine_game/ui/page/Game.kt
index c5f25e0..0d4bdc9 100644
--- a/app/src/main/java/com/a404m/mine_game/ui/page/Game.kt
+++ b/app/src/main/java/com/a404m/mine_game/ui/page/Game.kt
@@ -4,6 +4,10 @@ import android.util.Log
import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
+import androidx.compose.foundation.gestures.awaitEachGesture
+import androidx.compose.foundation.gestures.calculateZoom
+import androidx.compose.foundation.hoverable
+import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -33,10 +37,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import androidx.compose.ui.util.fastAny
import androidx.compose.ui.window.Dialog
import com.a404m.mine_game.R
import com.a404m.mine_game.core.TAG
@@ -49,6 +56,7 @@ import com.a404m.mine_game.ui.utils.modifier.freeScrollWithTransformGesture
import com.a404m.mine_game.ui.utils.modifier.model.rememberFreeScrollState
import com.a404m.mine_game.ui.utils.showToast
import com.a404m.mine_game.utils.PersianDate
+import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
@@ -452,15 +460,11 @@ fun Cell(
else MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(0),
)
- .let {
- if (!cell.isOpened) {
- it.clickable {
- onSelect()
- }
- } else {
- it
- }
- }
+ .clickable(
+ role = Role.Tab,
+ enabled = !cell.isOpened,
+ onClick = onSelect,
+ )
.padding(8.dp * zoom),
contentAlignment = Alignment.Center,
) {
diff --git a/app/src/main/java/com/a404m/mine_game/ui/page/Route.kt b/app/src/main/java/com/a404m/mine_game/ui/page/Route.kt
index 13de5b4..29caa22 100644
--- a/app/src/main/java/com/a404m/mine_game/ui/page/Route.kt
+++ b/app/src/main/java/com/a404m/mine_game/ui/page/Route.kt
@@ -1,10 +1,19 @@
package com.a404m.mine_game.ui.page
import android.util.Log
+import androidx.compose.animation.AnimatedContentScope
+import androidx.compose.animation.AnimatedContentTransitionScope
+import androidx.compose.animation.EnterTransition
+import androidx.compose.animation.ExitTransition
+import androidx.compose.animation.core.tween
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
+import androidx.navigation.NamedNavArgument
+import androidx.navigation.NavBackStackEntry
+import androidx.navigation.NavDeepLink
import androidx.navigation.NavGraph.Companion.findStartDestination
+import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
@@ -25,7 +34,7 @@ fun Route(
navController = navController,
startDestination = AppRoute.getSplashRoute(),
) {
- composable(
+ composableCustom(
route = AppRoute.getSplashStaticRoute(),
) {
Log.d(
@@ -44,7 +53,7 @@ fun Route(
},
)
}
- composable(
+ composableCustom(
route = AppRoute.getHomeStaticRoute(),
) {
HomePage(
@@ -69,7 +78,7 @@ fun Route(
onGoToAbout = {}
)
}
- composable(
+ composableCustom(
route = AppRoute.getGameStaticRoute(),
arguments = AppRoute.getGameArguments(),
) {
@@ -96,8 +105,8 @@ fun Route(
navController.popBackStack()
},
onNewGame = {
- navController.navigate(AppRoute.getGameRoute(true)){
- popUpTo(AppRoute.getGameStaticRoute()){
+ navController.navigate(AppRoute.getGameRoute(true)) {
+ popUpTo(AppRoute.getGameStaticRoute()) {
inclusive = true
}
}
@@ -105,7 +114,7 @@ fun Route(
gameState = gameState,
)
}
- composable(
+ composableCustom(
route = AppRoute.getControlsStaticRoute(),
) {
ControlsPage(
@@ -114,7 +123,7 @@ fun Route(
},
)
}
- composable(
+ composableCustom(
route = AppRoute.getSettingsStaticRoute(),
) {
SettingsPage(
@@ -152,14 +161,46 @@ object AppRoute {
fun getSettingsStaticRoute() = "/$SETTINGS"
fun getSettingsRoute() = "/$SETTINGS"
+}
- /*
- fun getChatStaticRoute() = "/$CHAT/{chat_id}"
- fun getChatRoute(chat: Chat) = "/$CHAT/${chat.id}"
- fun getChatArguments() = listOf(
- navArgument("chat_id") {
- type = NavType.IntType
- },
+fun NavGraphBuilder.composableCustom(
+ route: String,
+ arguments: List<NamedNavArgument> = emptyList(),
+ deepLinks: List<NavDeepLink> = emptyList(),
+ content: @Composable AnimatedContentScope.(NavBackStackEntry) -> Unit,
+) {
+ val millis = 350
+
+ val enterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition? =
+ {
+ slideIntoContainer(
+ AnimatedContentTransitionScope.SlideDirection.Left,
+ animationSpec = tween(millis),
+ )
+ }
+
+ val exitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition? =
+ {
+ slideOutOfContainer(
+ AnimatedContentTransitionScope.SlideDirection.Right,
+ animationSpec = tween(millis),
+ )
+ }
+
+ val popExitTransition =
+ exitTransition
+
+ val popEnterTransition =
+ enterTransition
+
+ this.composable(
+ route = route,
+ arguments = arguments,
+ deepLinks = deepLinks,
+ enterTransition = enterTransition,
+ exitTransition = exitTransition,
+ popEnterTransition = popEnterTransition,
+ popExitTransition = popExitTransition,
+ content = content,
)
- */
} \ No newline at end of file
diff --git a/app/src/main/java/com/a404m/mine_game/ui/utils/modifier/Extension.kt b/app/src/main/java/com/a404m/mine_game/ui/utils/modifier/Extension.kt
index 9401a62..ae5e068 100644
--- a/app/src/main/java/com/a404m/mine_game/ui/utils/modifier/Extension.kt
+++ b/app/src/main/java/com/a404m/mine_game/ui/utils/modifier/Extension.kt
@@ -63,16 +63,22 @@ fun Modifier.freeScroll(
val velocityTracker = remember { VelocityTracker() }
val fling = flingBehavior ?: ScrollableDefaults.flingBehavior()
- this.horizontalScroll(
- state = state.horizontalScrollState,
- enabled = false,
- reverseScrolling = horizontalReverseScrolling
- ).verticalScroll(
- state = state.verticalScrollState,
- enabled = false,
- reverseScrolling = verticalReverseScrolling
- )
- .pointerInput(enabled, horizontalReverseScrolling, verticalReverseScrolling) {
+ this
+ .horizontalScroll(
+ state = state.horizontalScrollState,
+ enabled = false,
+ reverseScrolling = horizontalReverseScrolling
+ )
+ .verticalScroll(
+ state = state.verticalScrollState,
+ enabled = false,
+ reverseScrolling = verticalReverseScrolling
+ )
+ .pointerInput(
+ enabled,
+ horizontalReverseScrolling,
+ verticalReverseScrolling
+ ) {
if (!enabled) return@pointerInput
coroutineScope {
@@ -124,16 +130,22 @@ fun Modifier.freeScrollWithTransformGesture(
val velocityTracker = remember { VelocityTracker() }
val fling = flingBehavior ?: ScrollableDefaults.flingBehavior()
- this.horizontalScroll(
- state = state.horizontalScrollState,
- enabled = false,
- reverseScrolling = horizontalReverseScrolling
- ).verticalScroll(
- state = state.verticalScrollState,
- enabled = false,
- reverseScrolling = verticalReverseScrolling
- )
- .pointerInput(enabled, horizontalReverseScrolling, verticalReverseScrolling) {
+ this
+ .horizontalScroll(
+ state = state.horizontalScrollState,
+ enabled = false,
+ reverseScrolling = horizontalReverseScrolling
+ )
+ .verticalScroll(
+ state = state.verticalScrollState,
+ enabled = false,
+ reverseScrolling = verticalReverseScrolling
+ )
+ .pointerInput(
+ enabled,
+ horizontalReverseScrolling,
+ verticalReverseScrolling
+ ) {
if (!enabled) return@pointerInput
coroutineScope {
@@ -149,7 +161,12 @@ fun Modifier.freeScrollWithTransformGesture(
velocityTracker = velocityTracker,
coroutineScope = this
)
- onGesture(centroid, pan, zoom, rotation)
+ onGesture(
+ centroid,
+ pan,
+ zoom,
+ rotation
+ )
},
onEnd = {
onEnd(
@@ -213,7 +230,10 @@ private fun onDrag(
else
state.verticalScrollState.value,
)
- velocityTracker.addPosition(time, position)
+ velocityTracker.addPosition(
+ time,
+ position
+ )
}
}
@@ -272,7 +292,7 @@ internal suspend fun PointerInputScope.detectFreeScrollGestures(
do {
val event = awaitPointerEvent()
- val canceled = event.changes.fastAny { it.isConsumed }
+ val canceled = event.changes.fastAny { it.isConsumed && false }
if (!canceled) {
val dragEvent = event.changes.fastFirstOrNull { it.id == pointer }
@@ -307,7 +327,13 @@ internal suspend fun PointerInputScope.detectFreeScrollGestures(
zoomChange != 1f ||
panChange != Offset.Zero
) {
- onGesture(centroid, panChange, zoomChange, effectiveRotation, dragEvent)
+ onGesture(
+ centroid,
+ panChange,
+ zoomChange,
+ effectiveRotation,
+ dragEvent
+ )
}
event.changes.fastForEach {
if (it.positionChanged()) {