From 46d2b6576c5437115c507dbb4982bee8ba542a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Tue, 3 Feb 2026 17:48:06 +0800 Subject: [PATCH] Fix WindowSizeClass breakpoint compat --- app/build.gradle.kts | 2 +- .../io/nekohasekai/sfa/compose/MainActivity.kt | 5 +++-- .../sfa/compose/component/qr/QRSDialog.kt | 5 +++-- .../sfa/compose/screen/log/LogScreen.kt | 5 +++-- .../sfa/compat/WindowSizeClassCompat.kt | 17 +++++++++++++++++ .../sfa/compat/WindowSizeClassCompat.kt | 10 ++++++++++ 6 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 app/src/minApi21/java/io/nekohasekai/sfa/compat/WindowSizeClassCompat.kt create mode 100644 app/src/minApi23/java/io/nekohasekai/sfa/compat/WindowSizeClassCompat.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 87f3128..f5dac68 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -265,7 +265,7 @@ dependencies { "otherLegacyImplementation"("com.github.topjohnwu.libsu:service:$libsuVersion") // Compose dependencies - API 23+ (play/other) - val composeBom23 = platform("androidx.compose:compose-bom:2025.12.01") + val composeBom23 = platform("androidx.compose:compose-bom:2026.01.01") val activityVersion23 = "1.12.2" val lifecycleComposeVersion23 = "2.10.0" diff --git a/app/src/main/java/io/nekohasekai/sfa/compose/MainActivity.kt b/app/src/main/java/io/nekohasekai/sfa/compose/MainActivity.kt index 486f7eb..9a37232 100644 --- a/app/src/main/java/io/nekohasekai/sfa/compose/MainActivity.kt +++ b/app/src/main/java/io/nekohasekai/sfa/compose/MainActivity.kt @@ -78,7 +78,6 @@ import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController -import androidx.window.core.layout.WindowSizeClass import dev.jeziellago.compose.markdowntext.MarkdownText import io.nekohasekai.libbox.Libbox import io.nekohasekai.sfa.Application @@ -86,6 +85,8 @@ import io.nekohasekai.sfa.BuildConfig import io.nekohasekai.sfa.R import io.nekohasekai.sfa.bg.ServiceConnection import io.nekohasekai.sfa.bg.ServiceNotification +import io.nekohasekai.sfa.compat.WindowSizeClassCompat +import io.nekohasekai.sfa.compat.isWidthAtLeastBreakpointCompat import io.nekohasekai.sfa.compose.base.GlobalEventBus import io.nekohasekai.sfa.compose.base.SelectableMessageDialog import io.nekohasekai.sfa.compose.base.UiEvent @@ -281,7 +282,7 @@ class MainActivity : val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass val useNavigationRail = - windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) + windowSizeClass.isWidthAtLeastBreakpointCompat(WindowSizeClassCompat.WIDTH_DP_MEDIUM_LOWER_BOUND) // Snackbar state val snackbarHostState = remember { SnackbarHostState() } diff --git a/app/src/main/java/io/nekohasekai/sfa/compose/component/qr/QRSDialog.kt b/app/src/main/java/io/nekohasekai/sfa/compose/component/qr/QRSDialog.kt index 2eddc13..e130040 100644 --- a/app/src/main/java/io/nekohasekai/sfa/compose/component/qr/QRSDialog.kt +++ b/app/src/main/java/io/nekohasekai/sfa/compose/component/qr/QRSDialog.kt @@ -51,8 +51,9 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties -import androidx.window.core.layout.WindowSizeClass import io.nekohasekai.sfa.R +import io.nekohasekai.sfa.compat.WindowSizeClassCompat +import io.nekohasekai.sfa.compat.isWidthAtLeastBreakpointCompat import io.nekohasekai.sfa.qrs.QRSConstants import io.nekohasekai.sfa.qrs.QRSEncoder import kotlinx.coroutines.delay @@ -61,7 +62,7 @@ import kotlinx.coroutines.delay fun QRSDialog(profileData: ByteArray, profileName: String, onDismiss: () -> Unit) { val context = LocalContext.current val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass - val isTablet = windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) + val isTablet = windowSizeClass.isWidthAtLeastBreakpointCompat(WindowSizeClassCompat.WIDTH_DP_MEDIUM_LOWER_BOUND) val coroutineScope = rememberCoroutineScope() var fps by remember { mutableIntStateOf(QRSConstants.DEFAULT_FPS) } var sliceSize by remember { mutableIntStateOf(QRSConstants.DEFAULT_SLICE_SIZE) } diff --git a/app/src/main/java/io/nekohasekai/sfa/compose/screen/log/LogScreen.kt b/app/src/main/java/io/nekohasekai/sfa/compose/screen/log/LogScreen.kt index 886629b..e4ab1f4 100644 --- a/app/src/main/java/io/nekohasekai/sfa/compose/screen/log/LogScreen.kt +++ b/app/src/main/java/io/nekohasekai/sfa/compose/screen/log/LogScreen.kt @@ -90,9 +90,10 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.content.FileProvider import androidx.lifecycle.viewmodel.compose.viewModel -import androidx.window.core.layout.WindowSizeClass import io.nekohasekai.sfa.Application import io.nekohasekai.sfa.R +import io.nekohasekai.sfa.compat.WindowSizeClassCompat +import io.nekohasekai.sfa.compat.isWidthAtLeastBreakpointCompat import io.nekohasekai.sfa.compose.topbar.OverrideTopBar import io.nekohasekai.sfa.constant.Status import java.io.File @@ -119,7 +120,7 @@ fun LogScreen( val uiState by resolvedViewModel.uiState.collectAsState() val context = LocalContext.current val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass - val isTablet = windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) + val isTablet = windowSizeClass.isWidthAtLeastBreakpointCompat(WindowSizeClassCompat.WIDTH_DP_MEDIUM_LOWER_BOUND) val listState = rememberLazyListState() val coroutineScope = rememberCoroutineScope() val resolvedTitle = title ?: stringResource(R.string.title_log) diff --git a/app/src/minApi21/java/io/nekohasekai/sfa/compat/WindowSizeClassCompat.kt b/app/src/minApi21/java/io/nekohasekai/sfa/compat/WindowSizeClassCompat.kt new file mode 100644 index 0000000..3b6cecd --- /dev/null +++ b/app/src/minApi21/java/io/nekohasekai/sfa/compat/WindowSizeClassCompat.kt @@ -0,0 +1,17 @@ +package io.nekohasekai.sfa.compat + +import androidx.window.core.layout.WindowSizeClass +import androidx.window.core.layout.WindowWidthSizeClass + +object WindowSizeClassCompat { + const val WIDTH_DP_MEDIUM_LOWER_BOUND = 600 + const val WIDTH_DP_EXPANDED_LOWER_BOUND = 840 +} + +fun WindowSizeClass.isWidthAtLeastBreakpointCompat(breakpointDp: Int): Boolean = when { + breakpointDp <= WindowSizeClassCompat.WIDTH_DP_MEDIUM_LOWER_BOUND -> + windowWidthSizeClass != WindowWidthSizeClass.COMPACT + breakpointDp <= WindowSizeClassCompat.WIDTH_DP_EXPANDED_LOWER_BOUND -> + windowWidthSizeClass == WindowWidthSizeClass.EXPANDED + else -> windowWidthSizeClass == WindowWidthSizeClass.EXPANDED +} diff --git a/app/src/minApi23/java/io/nekohasekai/sfa/compat/WindowSizeClassCompat.kt b/app/src/minApi23/java/io/nekohasekai/sfa/compat/WindowSizeClassCompat.kt new file mode 100644 index 0000000..5f93315 --- /dev/null +++ b/app/src/minApi23/java/io/nekohasekai/sfa/compat/WindowSizeClassCompat.kt @@ -0,0 +1,10 @@ +package io.nekohasekai.sfa.compat + +import androidx.window.core.layout.WindowSizeClass + +object WindowSizeClassCompat { + const val WIDTH_DP_MEDIUM_LOWER_BOUND = 600 + const val WIDTH_DP_EXPANDED_LOWER_BOUND = 840 +} + +fun WindowSizeClass.isWidthAtLeastBreakpointCompat(breakpointDp: Int): Boolean = isWidthAtLeastBreakpoint(breakpointDp)