Skip to content

Commit 2f52aea

Browse files
committed
Restore card transparency sync
1 parent df9df86 commit 2f52aea

9 files changed

Lines changed: 279 additions & 137 deletions

File tree

app/src/main/java/com/anatdx/icepatch/ui/MainActivity.kt

Lines changed: 77 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import androidx.compose.animation.Crossfade
1414
import androidx.compose.animation.EnterTransition
1515
import androidx.compose.animation.ExitTransition
1616
import androidx.compose.animation.core.tween
17+
import androidx.compose.animation.core.FastOutSlowInEasing
1718
import androidx.compose.animation.fadeIn
1819
import androidx.compose.animation.fadeOut
1920
import androidx.compose.animation.scaleOut
@@ -187,60 +188,92 @@ class MainActivity : AppCompatActivity() {
187188
val bottomBarRoutes = remember {
188189
BottomBarDestination.entries.map { it.direction.route }.toSet()
189190
}
191+
val bottomBarRouteIndex = remember {
192+
BottomBarDestination.entries
193+
.mapIndexed { index, destination -> destination.direction.route to index }
194+
.toMap()
195+
}
190196
val state by APApplication.apStateLiveData.observeAsState(APApplication.State.UNKNOWN_STATE)
191197
val kPatchReady = state != APApplication.State.UNKNOWN_STATE
192198
val aPatchReady = state == APApplication.State.ANDROIDPATCH_INSTALLED
193199
val visibleDestinations = remember(state) {
194200
BottomBarDestination.entries.filter { destination ->
195201
!(destination.kPatchRequired && !kPatchReady) && !(destination.aPatchRequired && !aPatchReady)
196-
}.toSet()
202+
}
197203
}
198204

199-
val defaultTransitions = object : NavHostAnimatedDestinationStyle() {
200-
override val enterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition =
201-
{
202-
// If the target is a detail page (not a bottom navigation page), slide in from the right
203-
if (targetState.destination.route !in bottomBarRoutes) {
204-
slideInHorizontally(initialOffsetX = { it })
205-
} else {
206-
// Otherwise (switching between bottom navigation pages), use fade in
207-
fadeIn(animationSpec = tween(340))
205+
val defaultTransitions = remember(bottomBarRoutes, bottomBarRouteIndex) {
206+
object : NavHostAnimatedDestinationStyle() {
207+
override val enterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition =
208+
{
209+
val fromIndex = bottomBarRouteIndex[initialState.destination.route]
210+
val toIndex = bottomBarRouteIndex[targetState.destination.route]
211+
if (fromIndex != null && toIndex != null) {
212+
val slideFrom = if (toIndex > fromIndex) { { width: Int -> width / 3 } } else { { width: Int -> -width / 3 } }
213+
slideInHorizontally(
214+
initialOffsetX = slideFrom,
215+
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
216+
) + fadeIn(animationSpec = tween(durationMillis = 240, easing = FastOutSlowInEasing))
217+
} else if (targetState.destination.route !in bottomBarRoutes) {
218+
slideInHorizontally(
219+
initialOffsetX = { it / 2 },
220+
animationSpec = tween(durationMillis = 320, easing = FastOutSlowInEasing)
221+
) + fadeIn(animationSpec = tween(durationMillis = 260, easing = FastOutSlowInEasing))
222+
} else {
223+
fadeIn(animationSpec = tween(220, easing = FastOutSlowInEasing))
224+
}
208225
}
209-
}
210226

211-
override val exitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition =
212-
{
213-
// If navigating from the home page (bottom navigation page) to a detail page, slide out to the left
214-
if (initialState.destination.route in bottomBarRoutes && targetState.destination.route !in bottomBarRoutes) {
215-
slideOutHorizontally(targetOffsetX = { -it / 4 }) + fadeOut()
216-
} else {
217-
// Otherwise (switching between bottom navigation pages), use fade out
218-
fadeOut(animationSpec = tween(340))
227+
override val exitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition =
228+
{
229+
val fromIndex = bottomBarRouteIndex[initialState.destination.route]
230+
val toIndex = bottomBarRouteIndex[targetState.destination.route]
231+
if (fromIndex != null && toIndex != null) {
232+
val slideTo = if (toIndex > fromIndex) { { width: Int -> -width / 6 } } else { { width: Int -> width / 6 } }
233+
slideOutHorizontally(
234+
targetOffsetX = slideTo,
235+
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
236+
) + fadeOut(animationSpec = tween(durationMillis = 210, easing = FastOutSlowInEasing))
237+
} else if (initialState.destination.route in bottomBarRoutes && targetState.destination.route !in bottomBarRoutes) {
238+
slideOutHorizontally(
239+
targetOffsetX = { -it / 6 },
240+
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
241+
) + fadeOut(
242+
animationSpec = tween(durationMillis = 220, easing = FastOutSlowInEasing)
243+
)
244+
} else {
245+
fadeOut(animationSpec = tween(durationMillis = 220, easing = FastOutSlowInEasing))
246+
}
219247
}
220-
}
221248

222-
override val popEnterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition =
223-
{
224-
// If returning to the home page (bottom navigation page), slide in from the left
225-
if (targetState.destination.route in bottomBarRoutes) {
226-
slideInHorizontally(initialOffsetX = { -it / 4 }) + fadeIn()
227-
} else {
228-
// Otherwise (e.g., returning between multiple detail pages), use default fade in
229-
fadeIn(animationSpec = tween(340))
249+
override val popEnterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition =
250+
{
251+
if (targetState.destination.route in bottomBarRoutes) {
252+
slideInHorizontally(
253+
initialOffsetX = { -it / 6 },
254+
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
255+
) + fadeIn(
256+
animationSpec = tween(durationMillis = 240, easing = FastOutSlowInEasing)
257+
)
258+
} else {
259+
fadeIn(animationSpec = tween(durationMillis = 220, easing = FastOutSlowInEasing))
260+
}
230261
}
231-
}
232262

233-
override val popExitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition =
234-
{
235-
// If returning from a detail page (not a bottom navigation page), scale down and fade out
236-
if (initialState.destination.route !in bottomBarRoutes) {
237-
scaleOut(targetScale = 0.9f) + fadeOut()
238-
} else {
239-
// Otherwise, use default fade out
240-
fadeOut(animationSpec = tween(340))
263+
override val popExitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition =
264+
{
265+
if (initialState.destination.route !in bottomBarRoutes) {
266+
scaleOut(
267+
targetScale = 0.96f,
268+
animationSpec = tween(durationMillis = 260, easing = FastOutSlowInEasing)
269+
) + fadeOut(animationSpec = tween(durationMillis = 220, easing = FastOutSlowInEasing))
270+
} else {
271+
fadeOut(animationSpec = tween(durationMillis = 180, easing = FastOutSlowInEasing))
272+
}
241273
}
242-
}
274+
}
243275
}
276+
val navHostEngine = rememberNavHostEngine(navHostContentAlignment = Alignment.TopCenter)
244277

245278
ShortcutIntentHandler(currentIntent = currentIntent, navigator = navigator)
246279

@@ -362,7 +395,7 @@ class MainActivity : AppCompatActivity() {
362395
DestinationsNavHost(
363396
navGraph = NavGraphs.root,
364397
navController = navController,
365-
engine = rememberNavHostEngine(navHostContentAlignment = Alignment.TopCenter),
398+
engine = navHostEngine,
366399
defaultTransitions = defaultTransitions
367400
)
368401
}
@@ -377,7 +410,7 @@ class MainActivity : AppCompatActivity() {
377410
DestinationsNavHost(
378411
navGraph = NavGraphs.root,
379412
navController = navController,
380-
engine = rememberNavHostEngine(navHostContentAlignment = Alignment.TopCenter),
413+
engine = navHostEngine,
381414
defaultTransitions = defaultTransitions
382415
)
383416
}
@@ -440,7 +473,7 @@ private fun ShortcutIntentHandler(
440473

441474

442475
@Composable
443-
private fun BottomBar(navController: NavHostController, visibleDestinations: Set<BottomBarDestination>) {
476+
private fun BottomBar(navController: NavHostController, visibleDestinations: List<BottomBarDestination>) {
444477
val navigator = navController.rememberDestinationsNavigator()
445478
val background = rememberBackgroundConfig()
446479

@@ -460,6 +493,7 @@ private fun BottomBar(navController: NavHostController, visibleDestinations: Set
460493
onClick = {
461494
if (isCurrentDestOnBackStack) {
462495
navigator.popBackStack(destination.direction, false)
496+
return@NavigationBarItem
463497
}
464498
navigator.navigate(destination.direction) {
465499
popUpTo(NavGraphs.root) {
@@ -492,7 +526,7 @@ private fun BottomBar(navController: NavHostController, visibleDestinations: Set
492526
}
493527

494528
@Composable
495-
private fun SideBar(navController: NavHostController, modifier: Modifier = Modifier, visibleDestinations: Set<BottomBarDestination>) {
529+
private fun SideBar(navController: NavHostController, modifier: Modifier = Modifier, visibleDestinations: List<BottomBarDestination>) {
496530
val navigator = navController.rememberDestinationsNavigator()
497531

498532
Crossfade(
@@ -514,6 +548,7 @@ private fun SideBar(navController: NavHostController, modifier: Modifier = Modif
514548
onClick = {
515549
if (isCurrentDestOnBackStack) {
516550
navigator.popBackStack(destination.direction, false)
551+
return@NavigationRailItem
517552
}
518553
navigator.navigate(destination.direction) {
519554
popUpTo(NavGraphs.root) {

app/src/main/java/com/anatdx/icepatch/ui/component/SettingsGroupCard.kt

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,49 @@ import androidx.compose.foundation.layout.ColumnScope
55
import androidx.compose.foundation.layout.fillMaxWidth
66
import androidx.compose.foundation.layout.padding
77
import androidx.compose.foundation.shape.RoundedCornerShape
8+
import androidx.compose.ui.draw.clip
89
import androidx.compose.material3.MaterialTheme
910
import androidx.compose.material3.Surface
1011
import androidx.compose.material3.Text
1112
import androidx.compose.runtime.Composable
1213
import androidx.compose.ui.Modifier
14+
import androidx.compose.ui.graphics.Color
15+
import androidx.compose.ui.graphics.lerp
16+
import androidx.compose.ui.graphics.luminance
1317
import androidx.compose.ui.unit.dp
18+
import com.anatdx.icepatch.ui.theme.rememberCardStyleConfig
1419

1520
@Composable
1621
fun SettingsGroupCard(
1722
title: String? = null,
1823
modifier: Modifier = Modifier,
24+
alphaOverride: Float? = null,
25+
dimOverride: Float? = null,
1926
content: @Composable ColumnScope.() -> Unit
2027
) {
28+
val shape = RoundedCornerShape(20.dp)
29+
val style = rememberCardStyleConfig()
30+
val alpha = alphaOverride ?: style.alpha
31+
val dim = dimOverride ?: style.dim
32+
val base = MaterialTheme.colorScheme.surfaceVariant
33+
val dimTarget = if (base.luminance() < 0.5f) Color.Black else Color.White
34+
val dimmed = if (dim <= 0f) base else lerp(base, dimTarget, dim)
35+
val containerColor = dimmed.copy(alpha = alpha)
36+
val contentColor = if (containerColor.luminance() < 0.5f) {
37+
MaterialTheme.colorScheme.onSurface
38+
} else {
39+
MaterialTheme.colorScheme.onSurfaceVariant
40+
}
41+
2142
Surface(
22-
modifier = modifier.fillMaxWidth(),
23-
color = MaterialTheme.colorScheme.surface,
24-
tonalElevation = 1.dp,
43+
modifier = modifier
44+
.fillMaxWidth()
45+
.clip(shape),
46+
color = containerColor,
47+
contentColor = contentColor,
48+
tonalElevation = 0.dp,
2549
shadowElevation = 0.dp,
26-
shape = RoundedCornerShape(20.dp)
50+
shape = shape
2751
) {
2852
Column(modifier = Modifier.fillMaxWidth().padding(12.dp)) {
2953
if (!title.isNullOrBlank()) {

app/src/main/java/com/anatdx/icepatch/ui/component/SettingsItem.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
55
import androidx.compose.foundation.selection.toggleable
66
import androidx.compose.material3.Icon
77
import androidx.compose.material3.ListItem
8+
import androidx.compose.material3.ListItemDefaults
89
import androidx.compose.material3.LocalContentColor
910
import androidx.compose.material3.MaterialTheme
1011
import androidx.compose.material3.RadioButton
@@ -13,6 +14,7 @@ import androidx.compose.material3.Text
1314
import androidx.compose.runtime.Composable
1415
import androidx.compose.runtime.remember
1516
import androidx.compose.ui.Modifier
17+
import androidx.compose.ui.graphics.Color
1618
import androidx.compose.ui.graphics.vector.ImageVector
1719
import androidx.compose.ui.semantics.Role
1820

@@ -36,6 +38,10 @@ fun SwitchItem(
3638
indication = LocalIndication.current,
3739
onValueChange = onCheckedChange
3840
),
41+
colors = ListItemDefaults.colors(
42+
containerColor = Color.Transparent,
43+
disabledContainerColor = Color.Transparent
44+
),
3945
headlineContent = {
4046
Text(
4147
title,
@@ -73,6 +79,10 @@ fun RadioItem(
7379
onClick: () -> Unit,
7480
) {
7581
ListItem(
82+
colors = ListItemDefaults.colors(
83+
containerColor = Color.Transparent,
84+
disabledContainerColor = Color.Transparent
85+
),
7686
headlineContent = {
7787
Text(title)
7888
},

app/src/main/java/com/anatdx/icepatch/ui/screen/APM.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ import com.anatdx.icepatch.ui.component.WarningCard
107107
import com.anatdx.icepatch.ui.component.pinnedScrollBehavior
108108
import com.anatdx.icepatch.ui.component.rememberConfirmDialog
109109
import com.anatdx.icepatch.ui.component.rememberLoadingDialog
110+
import com.anatdx.icepatch.ui.theme.CardStyleProvider
110111
import com.anatdx.icepatch.ui.viewmodel.APModuleViewModel
111112
import com.anatdx.icepatch.util.DownloadListener
112113
import com.anatdx.icepatch.util.ModuleShortcut
@@ -763,10 +764,13 @@ private fun ModuleItem(
763764
val decoration = if (!module.remove) TextDecoration.None else TextDecoration.LineThrough
764765
val moduleAuthor = stringResource(id = R.string.apm_author)
765766
val viewModel = viewModel<APModuleViewModel>()
767+
val cardContainerColor = CardStyleProvider.styledContainerColor(MaterialTheme.colorScheme.surfaceVariant)
768+
val cardContentColor = CardStyleProvider.contentColorFor(cardContainerColor)
766769
Surface(
767770
modifier = modifier,
768-
color = MaterialTheme.colorScheme.surface,
769-
tonalElevation = 1.dp,
771+
color = cardContainerColor,
772+
contentColor = cardContentColor,
773+
tonalElevation = 0.dp,
770774
shape = RoundedCornerShape(20.dp)
771775
) {
772776

@@ -865,7 +869,7 @@ private fun ModuleItem(
865869

866870
HorizontalDivider(
867871
thickness = 1.5.dp,
868-
color = MaterialTheme.colorScheme.surface,
872+
color = cardContainerColor.copy(alpha = 0.45f),
869873
modifier = Modifier.padding(top = 8.dp)
870874
)
871875

app/src/main/java/com/anatdx/icepatch/ui/screen/Home.kt

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -892,13 +892,16 @@ private fun getDeviceInfo(): String {
892892
private fun InfoCard(kpState: APApplication.State, apState: APApplication.State) {
893893
val prefs = APApplication.sharedPreferences
894894
val hideOtherInfo = prefs.getBoolean("is_hide_other_info", false)
895+
val cardContainer = CardStyleProvider.styledContainerColor(MaterialTheme.colorScheme.surfaceVariant)
896+
val cardContent = CardStyleProvider.contentColorFor(cardContainer)
895897
fun allow(key: String): Boolean {
896898
return !hideOtherInfo || prefs.getBoolean("home_info_$key", true)
897899
}
898900

899901
Surface(
900-
color = MaterialTheme.colorScheme.surface,
901-
tonalElevation = 1.dp,
902+
color = cardContainer,
903+
contentColor = cardContent,
904+
tonalElevation = 0.dp,
902905
shadowElevation = 0.dp,
903906
shape = RoundedCornerShape(20.dp)
904907
) {
@@ -1070,10 +1073,13 @@ fun UpdateCard() {
10701073
@Composable
10711074
fun LearnMoreCard() {
10721075
val uriHandler = LocalUriHandler.current
1076+
val cardContainer = CardStyleProvider.styledContainerColor(MaterialTheme.colorScheme.surfaceVariant)
1077+
val cardContent = CardStyleProvider.contentColorFor(cardContainer)
10731078

10741079
Surface(
1075-
color = MaterialTheme.colorScheme.surface,
1076-
tonalElevation = 1.dp,
1080+
color = cardContainer,
1081+
contentColor = cardContent,
1082+
tonalElevation = 0.dp,
10771083
shadowElevation = 0.dp,
10781084
shape = RoundedCornerShape(20.dp)
10791085
) {
@@ -1097,4 +1103,4 @@ fun LearnMoreCard() {
10971103
}
10981104
}
10991105
}
1100-
}
1106+
}

0 commit comments

Comments
 (0)