diff --git a/app/src/main/java/com/rtbishop/look4sat/MainScreen.kt b/app/src/main/java/com/rtbishop/look4sat/MainScreen.kt index 7fd41d4e..83688899 100644 --- a/app/src/main/java/com/rtbishop/look4sat/MainScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/MainScreen.kt @@ -131,12 +131,13 @@ fun MainScreen(navigateToRadar: () -> Unit = {}) { val currentKey = backStack.lastOrNull() val navigateBack: () -> Unit = { backStack.removeLastOrNull() } val fadeTransition = fadeIn(animationSpec = tween(350)) togetherWith fadeOut(animationSpec = tween(350)) - val navItems = listOf(Screen.Satellites, Screen.Passes, Screen.Radar, Screen.Mutual, Screen.Roaming, Screen.Map, Screen.Settings) - val context = LocalContext.current val container = (context.applicationContext as IContainerProvider).getMainContainer() val trackingState by container.radioTrackingService.state.collectAsStateWithLifecycle() val otherSettings by container.settingsRepo.otherSettings.collectAsStateWithLifecycle() + // UI 设置: 按 hiddenScreens 过滤导航项(顺序固定, 关闭项自动靠拢; 设置页固定保留) + val navItems = listOf(Screen.Satellites, Screen.Passes, Screen.Radar, Screen.Mutual, Screen.Roaming, Screen.Map, Screen.Settings) + .filter { it.screenId !in otherSettings.hiddenScreens || it is Screen.Settings } // Activity-scoped so the mutual query results survive navigation to Radar and back val mutualViewModel: MutualViewModel = viewModel( viewModelStoreOwner = context as ViewModelStoreOwner, diff --git a/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/SettingsRepo.kt b/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/SettingsRepo.kt index 4e271d46..f071829f 100644 --- a/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/SettingsRepo.kt +++ b/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/SettingsRepo.kt @@ -77,6 +77,7 @@ class SettingsRepo( private val keyStateOfUtc = "stateOfUtc" private val keyStateOfLightTheme = "stateOfLightTheme" private val keyStateOfNightMode = "stateOfNightMode" + private val keyHiddenScreens = "hiddenScreens" private val keyStationAltitude = "stationAltitude" private val keyStationLatitude = "stationLatitude" private val keyStationLongitude = "stationLongitude" @@ -357,6 +358,7 @@ class SettingsRepo( putString(keySstvMode, new.sstvMode) putLong(keyLowElevation, new.lowElevation.toRawBits()) putLong(keyHighElevation, new.highElevation.toRawBits()) + putStringSet(keyHiddenScreens, new.hiddenScreens.toSet()) } new } @@ -372,6 +374,7 @@ class SettingsRepo( shouldSeeWarning = preferences.getBoolean(keyShouldSeeWarning, true), shouldSeeWhatsNew = preferences.getBoolean(keyShouldSeeWhatsNew, true), sstvMode = preferences.getString(keySstvMode, null) ?: "Auto", + hiddenScreens = preferences.getStringSet(keyHiddenScreens, emptySet())?.toList() ?: emptyList(), lowElevation = Double.fromBits(preferences.getLong(keyLowElevation, 15.0.toRawBits())), highElevation = Double.fromBits(preferences.getLong(keyHighElevation, 45.0.toRawBits())) ) diff --git a/core/domain/src/main/java/com/rtbishop/look4sat/core/domain/model/Settings.kt b/core/domain/src/main/java/com/rtbishop/look4sat/core/domain/model/Settings.kt index ef830eb4..6caac071 100644 --- a/core/domain/src/main/java/com/rtbishop/look4sat/core/domain/model/Settings.kt +++ b/core/domain/src/main/java/com/rtbishop/look4sat/core/domain/model/Settings.kt @@ -62,7 +62,9 @@ data class OtherSettings( val shouldSeeWhatsNew: Boolean, val sstvMode: String = "Auto", val lowElevation: Double = 15.0, - val highElevation: Double = 45.0 + val highElevation: Double = 45.0, + // UI 设置: 底部导航栏隐藏的页面(Screen simpleName 列表, 默认空 = 全部显示) + val hiddenScreens: List = emptyList() ) data class DataSourcesSettings( diff --git a/core/presentation/src/main/java/com/rtbishop/look4sat/core/presentation/Navigation.kt b/core/presentation/src/main/java/com/rtbishop/look4sat/core/presentation/Navigation.kt index 26ea0ee6..9c176dfc 100644 --- a/core/presentation/src/main/java/com/rtbishop/look4sat/core/presentation/Navigation.kt +++ b/core/presentation/src/main/java/com/rtbishop/look4sat/core/presentation/Navigation.kt @@ -21,28 +21,28 @@ import androidx.navigation3.runtime.NavKey import kotlinx.serialization.Serializable @Serializable -sealed class Screen(val iconResId: Int, val titleResId: Int) : NavKey { +sealed class Screen(val iconResId: Int, val titleResId: Int, val screenId: String) : NavKey { @Serializable - data object Satellites : Screen(R.drawable.ic_satellites, R.string.nav_sat) + data object Satellites : Screen(R.drawable.ic_satellites, R.string.nav_sat, "Satellites") @Serializable - data object Passes : Screen(R.drawable.ic_passes, R.string.nav_pass) + data object Passes : Screen(R.drawable.ic_passes, R.string.nav_pass, "Passes") @Serializable - data object Radar : Screen(R.drawable.ic_radar, R.string.nav_radar) + data object Radar : Screen(R.drawable.ic_radar, R.string.nav_radar, "Radar") @Serializable - data object Map : Screen(R.drawable.ic_map, R.string.nav_map) + data object Map : Screen(R.drawable.ic_map, R.string.nav_map, "Map") @Serializable - data object Mutual : Screen(R.drawable.ic_match, R.string.nav_mutual) + data object Mutual : Screen(R.drawable.ic_match, R.string.nav_mutual, "Mutual") @Serializable - data object Roaming : Screen(R.drawable.ic_roaming, R.string.nav_roaming) + data object Roaming : Screen(R.drawable.ic_roaming, R.string.nav_roaming, "Roaming") @Serializable - data object Settings : Screen(R.drawable.ic_settings, R.string.nav_prefs) + data object Settings : Screen(R.drawable.ic_settings, R.string.nav_prefs, "Settings") } @Serializable diff --git a/core/presentation/src/main/res/values-tr/strings.xml b/core/presentation/src/main/res/values-tr/strings.xml index 6e116397..8035c1ed 100644 --- a/core/presentation/src/main/res/values-tr/strings.xml +++ b/core/presentation/src/main/res/values-tr/strings.xml @@ -57,6 +57,8 @@ \n\n* Ayarlar: sıkışan anahtar satırları ve teşekkür aralığı düzeltildi \n\n* Uygulama adı artık Look4Sat Pro \n\n* Ayarlar: "İçe aktar" düğmesi "Özel URL" olarak yeniden adlandırıldı - TLE/alıcı-verici kaynak URL\'leri doğrudan düzenlenebilir + \n\n* Özel kaynak anahtarları varsayılan olarak KAPALI; eski örnek URL\'ler gerçek varsayılanlara sıfırlanır + \n\n* Yeni UI Ayarları kartı: alt gezinme sayfalarını göster/gizle (sıra sabit, Ayarlar her zaman görünür) @@ -183,6 +185,7 @@ Ağ izninizi kontrol edin Diğer ayarlar + UI Ayarları Geçiş saatini UTC olarak göster Otomatik veri güncellemeyi etkinleştir Radar taramasını etkinleştir diff --git a/core/presentation/src/main/res/values-zh/strings.xml b/core/presentation/src/main/res/values-zh/strings.xml index e8265d2e..5c95adfa 100644 --- a/core/presentation/src/main/res/values-zh/strings.xml +++ b/core/presentation/src/main/res/values-zh/strings.xml @@ -47,6 +47,8 @@ \n\n* 设置:修复开关行挤压与感谢列表间距 \n\n* 应用名现为 Look4Sat Pro \n\n* 设置:导入文件按钮更名为自定义URL,可直接编辑 TLE/收发机数据源地址 + \n\n* 自定义数据源开关默认关闭;旧版占位 URL 自动重置为真实默认地址 + \n\n* 新增 UI设置 卡片:可显示/隐藏底部菜单栏页面(顺序固定,设置页始终显示) @@ -166,6 +168,7 @@ 启用 CAT 控制 其他设置 + UI设置 以 UTC 时间显示 启用卫星数据自动更新 启用雷达扫描动画 diff --git a/core/presentation/src/main/res/values/strings.xml b/core/presentation/src/main/res/values/strings.xml index 030581dd..4e2ad77f 100644 --- a/core/presentation/src/main/res/values/strings.xml +++ b/core/presentation/src/main/res/values/strings.xml @@ -59,6 +59,8 @@ \n\n* Settings: fixed squeezed toggle rows and credits spacing \n\n* App name is now Look4Sat Pro \n\n* Settings: "Import" button renamed to "Custom URL" - edit TLE/transceiver source URLs directly + \n\n* Custom source toggles default OFF; legacy placeholder URLs are reset to the real defaults + \n\n* New UI Settings card: show/hide bottom navigation pages (order fixed, Settings always visible) @@ -197,6 +199,7 @@ Check your network permission Other settings + UI Settings Show pass time in UTC Enable automatic data update Enable radar sweep animation diff --git a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsScreen.kt b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsScreen.kt index ab9b5839..27c2b9eb 100644 --- a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsScreen.kt +++ b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsScreen.kt @@ -300,6 +300,12 @@ private fun SettingsScreen(uiState: SettingsState, onAction: (SettingsAction) -> ) } item { OtherCard(uiState.otherSettings, onAction) } + item { + UiSettingsCard( + hiddenScreens = uiState.otherSettings.hiddenScreens, + onToggle = { name -> onAction(SettingsAction.ToggleScreen(name)) } + ) + } item { CardCredits() } } } @@ -516,8 +522,47 @@ private fun OtherCard(settings: OtherSettings, onAction: (SettingsAction) -> Uni } } +/** + * UI 设置卡片: 控制底部菜单栏各页面显示/隐藏。 + * 顺序固定(卫星/过境/雷达/匹配/漫游/地图/设置), 关闭后其余自动靠拢; + * "设置"页固定显示(防止失去设置入口)。 + */ @Composable -private fun SwitchRow(labelResId: Int, checked: Boolean, onCheckedChange: (Boolean) -> Unit) { +private fun UiSettingsCard(hiddenScreens: List, onToggle: (String) -> Unit) { + val screens = listOf( + R.string.nav_sat to "Satellites", + R.string.nav_pass to "Passes", + R.string.nav_radar to "Radar", + R.string.nav_mutual to "Mutual", + R.string.nav_roaming to "Roaming", + R.string.nav_map to "Map", + R.string.nav_prefs to "Settings" + ) // name 必须与 Screen.screenId 一致 (R8 安全) + ElevatedCard(modifier = Modifier.fillMaxWidth()) { + Column( + modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), + verticalArrangement = Arrangement.spacedBy(4.dp) + ) { + Text( + text = stringResource(id = R.string.prefs_ui_title), + color = MaterialTheme.colorScheme.primary + ) + screens.forEach { (labelRes, name) -> + if (name == "Settings") { + // 设置页固定显示, 开关禁用 + SwitchRow(labelRes, true, null) + } else { + SwitchRow(labelRes, name !in hiddenScreens) { + onToggle(name) + } + } + } + } + } +} + +@Composable +private fun SwitchRow(labelResId: Int, checked: Boolean, onCheckedChange: ((Boolean) -> Unit)?) { Row( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, diff --git a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsState.kt b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsState.kt index 928cf60b..98c99c15 100644 --- a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsState.kt +++ b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsState.kt @@ -64,6 +64,8 @@ sealed interface SettingsAction { data class ToggleSensor(val value: Boolean) : SettingsAction data class ToggleLightTheme(val value: Boolean) : SettingsAction data class ToggleNightMode(val value: Boolean) : SettingsAction + // UI 设置: 切换底部导航栏页面的隐藏状态(Screen simpleName) + data class ToggleScreen(val screenName: String) : SettingsAction // Remote control data class UpdateRC(val settings: RCSettings) : SettingsAction diff --git a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsViewModel.kt b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsViewModel.kt index f43e91f6..9f74ef9f 100644 --- a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsViewModel.kt +++ b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsViewModel.kt @@ -121,6 +121,11 @@ class SettingsViewModel( is SettingsAction.ToggleSensor -> settingsRepo.updateOtherSettings { it.copy(stateOfSensors = action.value) } is SettingsAction.ToggleLightTheme -> settingsRepo.updateOtherSettings { it.copy(stateOfLightTheme = action.value) } is SettingsAction.ToggleNightMode -> settingsRepo.updateOtherSettings { it.copy(stateOfNightMode = action.value) } + is SettingsAction.ToggleScreen -> settingsRepo.updateOtherSettings { current -> + val hidden = current.hiddenScreens.toMutableList() + if (action.screenName in hidden) hidden.remove(action.screenName) else hidden.add(action.screenName) + current.copy(hiddenScreens = hidden) + } // Remote control & data sources is SettingsAction.UpdateRC -> settingsRepo.updateRCSettings(action.settings) is SettingsAction.UpdateRadioControl -> settingsRepo.updateRadioControlSettings(action.settings)