mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
feat(settings,ui): custom-source toggles default off; new UI Settings card; bump to 4.4.9
Two changes per user request: 1. Data source toggles default OFF with legacy-URL migration (continuation of the 4.4.8 fix, now also in the dialog): old example.com placeholder URLs are replaced by the real defaults and the custom toggles stay off, so the online update never points at a dead source after upgrading. 2. New "UI Settings" card between Other Settings and Credits: one switch per bottom-navigation page (卫星/过境/雷达/匹配/漫游/地图/设置 in fixed order). Turning a page off removes it from the nav bar and the remaining items close up automatically; order is never rearranged. The Settings entry is always visible (switch disabled) so the user can never lose access to settings. Persisted via OtherSettings.hiddenScreens (StringSet of Screen.screenId; screenId added to the Screen sealed class - simpleName is unsafe under R8). Version bump per fork convention: 4.4.8 -> 4.4.9, versionCode 449. What's-new updated in en/zh/tr. Verified: core:data + core:domain tests pass, all modules compile.
This commit is contained in:
1 parent
9a4ceddcb0
commit
c101870b71
10 files changed
+79
-12
No files matched your search
@@ -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,
|
||||
|
||||
@@ -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()))
|
||||
)
|
||||
|
||||
@@ -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<String> = emptyList()
|
||||
)
|
||||
|
||||
data class DataSourcesSettings(
|
||||
|
||||
+8
-8
@@ -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
|
||||
|
||||
@@ -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)
|
||||
</string>
|
||||
|
||||
<!-- Radar screen -->
|
||||
@@ -183,6 +185,7 @@
|
||||
<string name="prefs_net_perm_error">Ağ izninizi kontrol edin</string>
|
||||
|
||||
<string name="prefs_other_title">Diğer ayarlar</string>
|
||||
<string name="prefs_ui_title">UI Ayarları</string>
|
||||
<string name="prefs_other_switch_utc">Geçiş saatini UTC olarak göster</string>
|
||||
<string name="prefs_other_switch_update">Otomatik veri güncellemeyi etkinleştir</string>
|
||||
<string name="prefs_other_switch_sweep">Radar taramasını etkinleştir</string>
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
\n\n* 设置:修复开关行挤压与感谢列表间距
|
||||
\n\n* 应用名现为 Look4Sat Pro
|
||||
\n\n* 设置:导入文件按钮更名为自定义URL,可直接编辑 TLE/收发机数据源地址
|
||||
\n\n* 自定义数据源开关默认关闭;旧版占位 URL 自动重置为真实默认地址
|
||||
\n\n* 新增 UI设置 卡片:可显示/隐藏底部菜单栏页面(顺序固定,设置页始终显示)
|
||||
</string>
|
||||
|
||||
<!-- Radar screen -->
|
||||
@@ -166,6 +168,7 @@
|
||||
<string name="rc_enable_switch">启用 CAT 控制</string>
|
||||
|
||||
<string name="prefs_other_title">其他设置</string>
|
||||
<string name="prefs_ui_title">UI设置</string>
|
||||
<string name="prefs_other_switch_utc">以 UTC 时间显示</string>
|
||||
<string name="prefs_other_switch_update">启用卫星数据自动更新</string>
|
||||
<string name="prefs_other_switch_sweep">启用雷达扫描动画</string>
|
||||
|
||||
@@ -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)
|
||||
</string>
|
||||
|
||||
<!-- Radar screen -->
|
||||
@@ -197,6 +199,7 @@
|
||||
<string name="prefs_net_perm_error">Check your network permission</string>
|
||||
|
||||
<string name="prefs_other_title">Other settings</string>
|
||||
<string name="prefs_ui_title">UI Settings</string>
|
||||
<string name="prefs_other_switch_utc">Show pass time in UTC</string>
|
||||
<string name="prefs_other_switch_update">Enable automatic data update</string>
|
||||
<string name="prefs_other_switch_sweep">Enable radar sweep animation</string>
|
||||
|
||||
+46
-1
@@ -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<String>, 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,
|
||||
|
||||
@@ -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
|
||||
|
||||
+5
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user