diff --git a/.editorconfig b/.editorconfig index fb119c398..a0bb8f1a9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -17,7 +17,7 @@ ij_wrap_on_typing = false max_line_length = 200 ktlint_code_style = ktlint_official ktlint_function_naming_ignore_when_annotated_with=Composable -compose_allowed_composition_locals = LocalTypographySettings,LocalDI,LocalDimens,LocalWindowSize,LocalFoldableHinge +compose_allowed_composition_locals = LocalTypographySettings,LocalDI,LocalDimens,LocalWindowSizeMetrics,LocalWindowSize,LocalFoldableHinge compose_allowed_forwarding = .*Screen [{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.opml,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul,rss_kuketz,rss_morningpaper}] diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/EditFeedScreen.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/EditFeedScreen.kt index 3f11bcc62..fc5be85c0 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/EditFeedScreen.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/editfeed/EditFeedScreen.kt @@ -80,7 +80,7 @@ import com.nononsenseapps.feeder.ui.compose.theme.LocalDimens import com.nononsenseapps.feeder.ui.compose.theme.SensibleTopAppBar import com.nononsenseapps.feeder.ui.compose.theme.SetStatusBarColorToMatchScrollableTopAppBar import com.nononsenseapps.feeder.ui.compose.utils.ImmutableHolder -import com.nononsenseapps.feeder.ui.compose.utils.LocalWindowSize +import com.nononsenseapps.feeder.ui.compose.utils.LocalWindowSizeMetrics import com.nononsenseapps.feeder.ui.compose.utils.ScreenType import com.nononsenseapps.feeder.ui.compose.utils.getScreenType import com.nononsenseapps.feeder.ui.compose.utils.rememberApiPermissionState @@ -91,7 +91,7 @@ fun CreateFeedScreen( createFeedScreenViewModel: CreateFeedScreenViewModel, onOk: (Long) -> Unit, ) { - val windowSize = LocalWindowSize() + val windowSize = LocalWindowSizeMetrics.current val screenType by remember(windowSize) { derivedStateOf { @@ -121,7 +121,7 @@ fun EditFeedScreen( editFeedScreenViewModel: EditFeedScreenViewModel, onOk: (Long) -> Unit, ) { - val windowSize = LocalWindowSize() + val windowSize = LocalWindowSizeMetrics.current val screenType by remember(windowSize) { derivedStateOf { diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/ompl/OpmlImportScreen.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/ompl/OpmlImportScreen.kt index 9956660f5..9ef556574 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/ompl/OpmlImportScreen.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/ompl/OpmlImportScreen.kt @@ -51,7 +51,7 @@ import com.nononsenseapps.feeder.ui.compose.theme.FeederTheme import com.nononsenseapps.feeder.ui.compose.theme.LocalDimens import com.nononsenseapps.feeder.ui.compose.theme.SensibleTopAppBar import com.nononsenseapps.feeder.ui.compose.theme.SetStatusBarColorToMatchScrollableTopAppBar -import com.nononsenseapps.feeder.ui.compose.utils.LocalWindowSize +import com.nononsenseapps.feeder.ui.compose.utils.LocalWindowSizeMetrics import com.nononsenseapps.feeder.ui.compose.utils.PreviewThemes import com.nononsenseapps.feeder.ui.compose.utils.ProvideScaledText import com.nononsenseapps.feeder.ui.compose.utils.ScreenType @@ -115,7 +115,7 @@ fun OpmlImportScreen( } } - val windowSize = LocalWindowSize() + val windowSize = LocalWindowSizeMetrics.current val screenHeight by remember(windowSize) { derivedStateOf { when (getScreenType(windowSize)) { diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/searchfeed/SearchFeedScreen.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/searchfeed/SearchFeedScreen.kt index 4f28f9046..88e7ed6a8 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/searchfeed/SearchFeedScreen.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/searchfeed/SearchFeedScreen.kt @@ -83,7 +83,7 @@ import com.nononsenseapps.feeder.ui.compose.theme.FeederTheme import com.nononsenseapps.feeder.ui.compose.theme.LocalDimens import com.nononsenseapps.feeder.ui.compose.theme.SensibleTopAppBar import com.nononsenseapps.feeder.ui.compose.theme.SetStatusBarColorToMatchScrollableTopAppBar -import com.nononsenseapps.feeder.ui.compose.utils.LocalWindowSize +import com.nononsenseapps.feeder.ui.compose.utils.LocalWindowSizeMetrics import com.nononsenseapps.feeder.ui.compose.utils.ScreenType import com.nononsenseapps.feeder.ui.compose.utils.StableHolder import com.nononsenseapps.feeder.ui.compose.utils.getScreenType @@ -107,7 +107,7 @@ fun SearchFeedScreen( initialFeedUrl: String? = null, onClick: (SearchResult) -> Unit, ) { - val windowSize = LocalWindowSize() + val windowSize = LocalWindowSizeMetrics.current val screenType by remember(windowSize) { derivedStateOf { getScreenType(windowSize) diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/sync/SyncScreen.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/sync/SyncScreen.kt index 6f30c69a8..8fb028c24 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/sync/SyncScreen.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/sync/SyncScreen.kt @@ -88,7 +88,7 @@ import com.nononsenseapps.feeder.ui.compose.theme.LocalDimens import com.nononsenseapps.feeder.ui.compose.theme.SensibleTopAppBar import com.nononsenseapps.feeder.ui.compose.theme.SetStatusBarColorToMatchScrollableTopAppBar import com.nononsenseapps.feeder.ui.compose.utils.ImmutableHolder -import com.nononsenseapps.feeder.ui.compose.utils.LocalWindowSize +import com.nononsenseapps.feeder.ui.compose.utils.LocalWindowSizeMetrics import com.nononsenseapps.feeder.ui.compose.utils.ScreenType import com.nononsenseapps.feeder.ui.compose.utils.getScreenType import com.nononsenseapps.feeder.ui.compose.utils.onKeyEventLikeEscape @@ -208,7 +208,7 @@ fun SyncScreen( ) { val viewState: SyncScreenViewState by viewModel.viewState.collectAsStateWithLifecycle() - val windowSize = LocalWindowSize() + val windowSize = LocalWindowSizeMetrics.current val syncScreenType = getSyncScreenType( windowSize = windowSize, diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/theme/Dimensions.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/theme/Dimensions.kt index 925b1d8e8..4d1be362e 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/theme/Dimensions.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/theme/Dimensions.kt @@ -12,6 +12,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.coerceAtMost import androidx.compose.ui.unit.dp import com.nononsenseapps.feeder.ui.compose.utils.LocalWindowSize +import com.nononsenseapps.feeder.ui.compose.utils.LocalWindowSizeMetrics @Immutable class Dimensions( @@ -110,7 +111,8 @@ val LocalDimens = @Composable fun ProvideDimens(content: @Composable () -> Unit) { - val windowSizeClass = LocalWindowSize.current + val windowSize = LocalWindowSize.current + val windowSizeClass = LocalWindowSizeMetrics.current val config = LocalConfiguration.current val dimensionSet = @@ -119,17 +121,13 @@ fun ProvideDimens(content: @Composable () -> Unit) { // TV dimensions are special case tvDimensions } else { - when (val widthClass = windowSizeClass.widthSizeClass) { + when (windowSizeClass.widthSizeClass) { WindowWidthSizeClass.Compact -> phoneDimensions else -> { when (windowSizeClass.heightSizeClass) { WindowHeightSizeClass.Compact -> phoneDimensions else -> - if (widthClass == WindowWidthSizeClass.Medium) { - tabletDimensions(600.dp) - } else { - tabletDimensions(840.dp) - } + tabletDimensions(windowSize.width) } } } diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/utils/ComposeProviders.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/utils/ComposeProviders.kt index d3a30ee25..9b2f9fb5b 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/utils/ComposeProviders.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/utils/ComposeProviders.kt @@ -26,14 +26,16 @@ fun DIAwareComponentActivity.withAllProviders(content: @Composable () -> Unit) { val dynamicColors by viewModel.dynamicColors.collectAsStateWithLifecycle() val textScale by viewModel.textScale.collectAsStateWithLifecycle() withFoldableHinge { - withWindowSize { - FeederTheme( - currentTheme = currentTheme, - darkThemePreference = darkThemePreference, - dynamicColors = dynamicColors, - ) { - ProvideFontScale(fontScale = textScale) { - WithFeederTextToolbar(content) + withWindowMetrics { + withWindowSize { + FeederTheme( + currentTheme = currentTheme, + darkThemePreference = darkThemePreference, + dynamicColors = dynamicColors, + ) { + ProvideFontScale(fontScale = textScale) { + WithFeederTextToolbar(content) + } } } } diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/utils/WindowSize.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/utils/WindowSize.kt index 9b8505f85..c13a484c6 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/utils/WindowSize.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/utils/WindowSize.kt @@ -11,20 +11,35 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.compositionLocalOf +import androidx.compose.ui.graphics.toComposeRect import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.DpSize +import androidx.window.layout.WindowMetricsCalculator -val LocalWindowSize: ProvidableCompositionLocal = +val LocalWindowSizeMetrics: ProvidableCompositionLocal = compositionLocalOf { error("Missing WindowSize container!") } -@Composable -fun LocalWindowSize(): WindowSizeClass = LocalWindowSize.current +val LocalWindowSize: ProvidableCompositionLocal = + compositionLocalOf { error("Missing WindowMetrics container!") } @OptIn(ExperimentalMaterial3WindowSizeClassApi::class) @Composable fun Activity.withWindowSize(content: @Composable () -> Unit) { val windowSizeclass = calculateWindowSizeClass(activity = this) - CompositionLocalProvider(LocalWindowSize provides windowSizeclass) { + CompositionLocalProvider(LocalWindowSizeMetrics provides windowSizeclass) { + content() + } +} + +@Composable +fun Activity.withWindowMetrics(content: @Composable () -> Unit) { + LocalConfiguration.current + val density = LocalDensity.current + val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this) + val size = with(density) { metrics.bounds.toComposeRect().size.toDpSize() } + CompositionLocalProvider(LocalWindowSize provides size) { content() } } @@ -34,7 +49,7 @@ fun WithPreviewWindowSize( windowSizeclass: WindowSizeClass, content: @Composable () -> Unit, ) { - CompositionLocalProvider(LocalWindowSize provides windowSizeclass) { + CompositionLocalProvider(LocalWindowSizeMetrics provides windowSizeclass) { content() } } @@ -42,12 +57,12 @@ fun WithPreviewWindowSize( @Composable fun isCompactLandscape(): Boolean { return LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE && - LocalWindowSize.current.heightSizeClass == WindowHeightSizeClass.Compact + LocalWindowSizeMetrics.current.heightSizeClass == WindowHeightSizeClass.Compact } @Composable fun isCompactDevice(): Boolean { - val windowSize = LocalWindowSize.current + val windowSize = LocalWindowSizeMetrics.current return windowSize.heightSizeClass == WindowHeightSizeClass.Compact || windowSize.widthSizeClass == WindowWidthSizeClass.Compact }