From 94c5f90fbbfd0702fed68802881b21b4a87ce528 Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Wed, 20 Aug 2025 11:26:02 +0800 Subject: [PATCH] compose: details: Adjust adaptive screens based on latest alpha changes * WindowWidthSizeClass is deprecated, switch to WindowSizeClass and breakpoints instead with flipped logic * Specify a dragHandle and adaptStratergy for supporting pane to levitate on single pane screens Signed-off-by: Aayush Gupta --- .../aurora/extensions/WindowAdaptiveInfo.kt | 11 +++-- .../compose/ui/details/AppDetailsScreen.kt | 40 +++++++++++++++++-- .../compose/ui/details/DetailsExodusScreen.kt | 11 +++-- .../ui/details/DetailsManualDownloadScreen.kt | 10 +++-- .../compose/ui/details/DetailsMoreScreen.kt | 11 +++-- .../ui/details/DetailsPermissionScreen.kt | 11 +++-- .../compose/ui/details/DetailsReviewScreen.kt | 11 +++-- .../ui/details/DetailsScreenshotScreen.kt | 11 +++-- .../ui/details/components/AppActions.kt | 10 +++-- .../details/components/AppRatingAndReviews.kt | 10 +++-- 10 files changed, 99 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/com/aurora/extensions/WindowAdaptiveInfo.kt b/app/src/main/java/com/aurora/extensions/WindowAdaptiveInfo.kt index 01b9db188..13fb4835a 100644 --- a/app/src/main/java/com/aurora/extensions/WindowAdaptiveInfo.kt +++ b/app/src/main/java/com/aurora/extensions/WindowAdaptiveInfo.kt @@ -9,7 +9,7 @@ import androidx.compose.material3.adaptive.WindowAdaptiveInfo import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.res.painterResource -import androidx.window.core.layout.WindowWidthSizeClass +import androidx.window.core.layout.WindowSizeClass import com.aurora.store.R /** @@ -17,7 +17,10 @@ import com.aurora.store.R */ val WindowAdaptiveInfo.adaptiveNavigationIcon: Painter @Composable - get() = when (windowSizeClass.windowWidthSizeClass) { - WindowWidthSizeClass.COMPACT -> painterResource(R.drawable.ic_arrow_back) - else -> painterResource(R.drawable.ic_cancel) + get() = when { + windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) -> { + painterResource(R.drawable.ic_cancel) + } + + else -> painterResource(R.drawable.ic_arrow_back) } diff --git a/app/src/main/java/com/aurora/store/compose/ui/details/AppDetailsScreen.kt b/app/src/main/java/com/aurora/store/compose/ui/details/AppDetailsScreen.kt index 1074d8b16..8be19bec4 100644 --- a/app/src/main/java/com/aurora/store/compose/ui/details/AppDetailsScreen.kt +++ b/app/src/main/java/com/aurora/store/compose/ui/details/AppDetailsScreen.kt @@ -6,6 +6,7 @@ package com.aurora.store.compose.ui.details import android.content.ActivityNotFoundException +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -16,16 +17,24 @@ import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Icon +import androidx.compose.material3.LocalMinimumInteractiveComponentSize import androidx.compose.material3.Scaffold +import androidx.compose.material3.VerticalDragHandle +import androidx.compose.material3.adaptive.WindowAdaptiveInfo +import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo +import androidx.compose.material3.adaptive.layout.AdaptStrategy import androidx.compose.material3.adaptive.layout.AnimatedPane import androidx.compose.material3.adaptive.layout.PaneAdaptedValue +import androidx.compose.material3.adaptive.layout.SupportingPaneScaffoldDefaults import androidx.compose.material3.adaptive.layout.SupportingPaneScaffoldRole +import androidx.compose.material3.adaptive.layout.calculatePaneScaffoldDirective import androidx.compose.material3.adaptive.navigation.NavigableSupportingPaneScaffold import androidx.compose.material3.adaptive.navigation.rememberSupportingPaneScaffoldNavigator import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -194,10 +203,19 @@ private fun ScreenContentApp( onCancelDownload: () -> Unit = {}, onUninstall: () -> Unit = {}, onOpen: () -> Unit = {}, - onTestingSubscriptionChange: (subscribe: Boolean) -> Unit = {} + onTestingSubscriptionChange: (subscribe: Boolean) -> Unit = {}, + windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfo() ) { val context = LocalContext.current - val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() + val scaffoldDirective = calculatePaneScaffoldDirective(windowAdaptiveInfo) + val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator( + scaffoldDirective = scaffoldDirective, + adaptStrategies = SupportingPaneScaffoldDefaults.adaptStrategies( + supportingPaneAdaptStrategy = AdaptStrategy + .Levitate() + .onlyIfSinglePane(scaffoldDirective) + ) + ) val coroutineScope = rememberCoroutineScope() val shouldShowMenuOnMainPane = scaffoldNavigator .scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Hidden @@ -423,8 +441,12 @@ private fun ScreenContentApp( scaffoldNavigator.currentDestination?.contentKey?.let { screen -> AnimatedPane { when (screen) { - is Screen.DetailsReview -> DetailsReviewScreen(onNavigateUp = ::showMainPane) - is Screen.DetailsExodus -> DetailsExodusScreen(onNavigateUp = ::showMainPane) + is Screen.DetailsReview -> DetailsReviewScreen( + onNavigateUp = ::showMainPane + ) + is Screen.DetailsExodus -> DetailsExodusScreen( + onNavigateUp = ::showMainPane + ) is Screen.DetailsMore -> DetailsMoreScreen( onNavigateUp = ::showMainPane, onNavigateToAppDetails = onNavigateToAppDetails @@ -449,6 +471,16 @@ private fun ScreenContentApp( } } } + }, + paneExpansionDragHandle = { state -> + VerticalDragHandle( + modifier = Modifier.paneExpansionDraggable( + state = state, + minTouchTargetSize = LocalMinimumInteractiveComponentSize.current, + interactionSource = remember { MutableInteractionSource() } + ), + interactionSource = remember { MutableInteractionSource() } + ) } ) } diff --git a/app/src/main/java/com/aurora/store/compose/ui/details/DetailsExodusScreen.kt b/app/src/main/java/com/aurora/store/compose/ui/details/DetailsExodusScreen.kt index 411f0e3fd..5ae239996 100644 --- a/app/src/main/java/com/aurora/store/compose/ui/details/DetailsExodusScreen.kt +++ b/app/src/main/java/com/aurora/store/compose/ui/details/DetailsExodusScreen.kt @@ -22,7 +22,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.window.core.layout.WindowWidthSizeClass +import androidx.window.core.layout.WindowSizeClass import com.aurora.Constants.EXODUS_REPORT_URL import com.aurora.extensions.adaptiveNavigationIcon import com.aurora.extensions.browse @@ -49,9 +49,12 @@ fun DetailsExodusScreen( val exodusReport by appDetailsViewModel.exodusReport.collectAsStateWithLifecycle() val trackers by detailsExodusViewModel.trackers.collectAsStateWithLifecycle() - val topAppBarTitle = when (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass) { - WindowWidthSizeClass.COMPACT -> app!!.displayName - else -> stringResource(R.string.details_privacy) + val topAppBarTitle = when { + windowAdaptiveInfo.windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) -> { + stringResource(R.string.details_privacy) + } + + else -> app!!.displayName } ScreenContent( diff --git a/app/src/main/java/com/aurora/store/compose/ui/details/DetailsManualDownloadScreen.kt b/app/src/main/java/com/aurora/store/compose/ui/details/DetailsManualDownloadScreen.kt index 97c31da20..1cd36bcd6 100644 --- a/app/src/main/java/com/aurora/store/compose/ui/details/DetailsManualDownloadScreen.kt +++ b/app/src/main/java/com/aurora/store/compose/ui/details/DetailsManualDownloadScreen.kt @@ -43,6 +43,7 @@ import androidx.compose.ui.unit.dp import androidx.core.text.isDigitsOnly import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.window.core.layout.WindowSizeClass import androidx.window.core.layout.WindowWidthSizeClass import com.aurora.extensions.adaptiveNavigationIcon import com.aurora.extensions.toast @@ -63,9 +64,12 @@ fun DetailsManualDownloadScreen( val context = LocalContext.current val app by viewModel.app.collectAsStateWithLifecycle() - val topAppBarTitle = when (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass) { - WindowWidthSizeClass.COMPACT -> app!!.displayName - else -> stringResource(R.string.title_manual_download) + val topAppBarTitle = when { + windowAdaptiveInfo.windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) -> { + stringResource(R.string.title_manual_download) + } + + else -> app!!.displayName } LaunchedEffect(key1 = Unit) { diff --git a/app/src/main/java/com/aurora/store/compose/ui/details/DetailsMoreScreen.kt b/app/src/main/java/com/aurora/store/compose/ui/details/DetailsMoreScreen.kt index f1f8390fc..8f5248e90 100644 --- a/app/src/main/java/com/aurora/store/compose/ui/details/DetailsMoreScreen.kt +++ b/app/src/main/java/com/aurora/store/compose/ui/details/DetailsMoreScreen.kt @@ -31,7 +31,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.window.core.layout.WindowWidthSizeClass +import androidx.window.core.layout.WindowSizeClass import coil3.compose.LocalAsyncImagePreviewHandler import com.aurora.extensions.adaptiveNavigationIcon import com.aurora.gplayapi.data.models.App @@ -74,9 +74,12 @@ private fun ScreenContent( onNavigateToAppDetails: (packageName: String) -> Unit = {}, windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfo() ) { - val topAppBarTitle = when (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass) { - WindowWidthSizeClass.COMPACT -> app.displayName - else -> stringResource(R.string.details_more_about_app) + val topAppBarTitle = when { + windowAdaptiveInfo.windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) -> { + stringResource(R.string.details_more_about_app) + } + + else -> app.displayName } Scaffold( diff --git a/app/src/main/java/com/aurora/store/compose/ui/details/DetailsPermissionScreen.kt b/app/src/main/java/com/aurora/store/compose/ui/details/DetailsPermissionScreen.kt index e4c8fd8ac..442c0e5ea 100644 --- a/app/src/main/java/com/aurora/store/compose/ui/details/DetailsPermissionScreen.kt +++ b/app/src/main/java/com/aurora/store/compose/ui/details/DetailsPermissionScreen.kt @@ -25,7 +25,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.window.core.layout.WindowWidthSizeClass +import androidx.window.core.layout.WindowSizeClass import com.aurora.extensions.adaptiveNavigationIcon import com.aurora.gplayapi.data.models.App import com.aurora.store.R @@ -48,9 +48,12 @@ fun DetailsPermissionScreen( val app by appDetailsViewModel.app.collectAsStateWithLifecycle() val permissionsInfo by detailsPermissionViewModel.permissionsInfo.collectAsStateWithLifecycle() - val topAppBarTitle = when (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass) { - WindowWidthSizeClass.COMPACT -> app!!.displayName - else -> stringResource(R.string.details_permission) + val topAppBarTitle = when { + windowAdaptiveInfo.windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) -> { + stringResource(R.string.details_permission) + } + + else -> app!!.displayName } ScreenContent( diff --git a/app/src/main/java/com/aurora/store/compose/ui/details/DetailsReviewScreen.kt b/app/src/main/java/com/aurora/store/compose/ui/details/DetailsReviewScreen.kt index 9d3d95650..99489b0c1 100644 --- a/app/src/main/java/com/aurora/store/compose/ui/details/DetailsReviewScreen.kt +++ b/app/src/main/java/com/aurora/store/compose/ui/details/DetailsReviewScreen.kt @@ -37,7 +37,7 @@ import androidx.paging.PagingData import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems import androidx.paging.compose.itemKey -import androidx.window.core.layout.WindowWidthSizeClass +import androidx.window.core.layout.WindowSizeClass import coil3.compose.LocalAsyncImagePreviewHandler import com.aurora.extensions.adaptiveNavigationIcon import com.aurora.gplayapi.data.models.Review @@ -63,9 +63,12 @@ fun DetailsReviewScreen( val app by appDetailsViewModel.app.collectAsStateWithLifecycle() val reviews = detailsReviewViewModel.reviews.collectAsLazyPagingItems() - val topAppBarTitle = when (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass) { - WindowWidthSizeClass.COMPACT -> app!!.displayName - else -> stringResource(R.string.details_ratings) + val topAppBarTitle = when { + windowAdaptiveInfo.windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) -> { + stringResource(R.string.details_ratings) + } + + else -> app!!.displayName } ScreenContent( diff --git a/app/src/main/java/com/aurora/store/compose/ui/details/DetailsScreenshotScreen.kt b/app/src/main/java/com/aurora/store/compose/ui/details/DetailsScreenshotScreen.kt index 85289067f..78129da93 100644 --- a/app/src/main/java/com/aurora/store/compose/ui/details/DetailsScreenshotScreen.kt +++ b/app/src/main/java/com/aurora/store/compose/ui/details/DetailsScreenshotScreen.kt @@ -21,7 +21,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.window.core.layout.WindowWidthSizeClass +import androidx.window.core.layout.WindowSizeClass import com.aurora.extensions.adaptiveNavigationIcon import com.aurora.gplayapi.data.models.Artwork import com.aurora.store.R @@ -38,9 +38,12 @@ fun DetailsScreenshotScreen( ) { val app by viewModel.app.collectAsStateWithLifecycle() - val topAppBarTitle = when (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass) { - WindowWidthSizeClass.COMPACT -> app!!.displayName - else -> stringResource(R.string.details_more_about_app) + val topAppBarTitle = when { + windowAdaptiveInfo.windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) -> { + stringResource(R.string.details_more_about_app) + } + + else -> app!!.displayName } ScreenContent( diff --git a/app/src/main/java/com/aurora/store/compose/ui/details/components/AppActions.kt b/app/src/main/java/com/aurora/store/compose/ui/details/components/AppActions.kt index e9405e7c8..b57009e90 100644 --- a/app/src/main/java/com/aurora/store/compose/ui/details/components/AppActions.kt +++ b/app/src/main/java/com/aurora/store/compose/ui/details/components/AppActions.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview +import androidx.window.core.layout.WindowSizeClass import androidx.window.core.layout.WindowWidthSizeClass import com.aurora.store.R @@ -49,9 +50,12 @@ fun AppActions( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_medium)) ) { - val buttonWidthModifier = when (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass) { - WindowWidthSizeClass.COMPACT -> Modifier.weight(1F) - else -> Modifier.widthIn(min = dimensionResource(R.dimen.width_button)) + val buttonWidthModifier = when { + windowAdaptiveInfo.windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) -> { + Modifier.widthIn(min = dimensionResource(R.dimen.width_button)) + } + + else -> Modifier.weight(1F) } FilledTonalButton( diff --git a/app/src/main/java/com/aurora/store/compose/ui/details/components/AppRatingAndReviews.kt b/app/src/main/java/com/aurora/store/compose/ui/details/components/AppRatingAndReviews.kt index b4716b4a4..a43388d48 100644 --- a/app/src/main/java/com/aurora/store/compose/ui/details/components/AppRatingAndReviews.kt +++ b/app/src/main/java/com/aurora/store/compose/ui/details/components/AppRatingAndReviews.kt @@ -30,6 +30,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.util.fastForEach +import androidx.window.core.layout.WindowSizeClass import androidx.window.core.layout.WindowWidthSizeClass import com.aurora.gplayapi.data.models.App import com.aurora.gplayapi.data.models.Rating @@ -64,9 +65,12 @@ fun AppRatingAndReviews( if (it.sum() == 0F) return } - val avgRating = when (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass) { - WindowWidthSizeClass.COMPACT -> String.format(Locale.getDefault(), "%.1f", rating.average) - else -> String.format(Locale.getDefault(), "%.1f / 5.0", rating.average) + val avgRating = when { + windowAdaptiveInfo.windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) -> { + String.format(Locale.getDefault(), "%.1f / 5.0", rating.average) + } + + else -> String.format(Locale.getDefault(), "%.1f", rating.average) } HeaderComposable(