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)