fix(radar): 计算器 offset 改为跟随驱动计算器的转发器读写

per-satellite offset 原先只在 SelectTransmitter 里载入、并按 selectedUuid
的 catnum 保存:重开雷达页读不回(看起来"没保存"),选中被 toggle 掉后
catnum 为 null 静默丢写;且计算器页 chip 仅在 dedupe 后多于一条时渲染,
单转发器卫星(JO-97/RS-44/FO-29/AO-73/QO-100/TO-108/FO-82/QB50P1/
UKUBE-1)根本没有 chip 可点,永远触发不了载入——上游 rt-bishop 在 PR #237
评审时预言过这个加载问题。

改为 offset 跟随"驱动计算器的转发器":该转发器变化(打开/换星)即载入
已存值,按其 catnum 保存,与收发机选中状态解耦;同时删掉 loadPassData 里
的 workaround 载入与 SelectTransmitter 里的 offset 读写,单一来源、与上游
PR #265 同形便于后续合并。存储格式(satelliteOffsets 单 JSON)不变,
已存的值补丁后直接生效。

验证::feature:radar:compileDebugKotlin 与 :feature:radar:test 通过;
:core:domain:test up-to-date(domain 未改动)。
This commit is contained in:
atsunatsu committed 2026-10-05 20:42:08 +08:00
1 parent 5c12d64824
commit ad970eec77
3 files changed
+25 -14

No files matched your search

@@ -132,5 +132,12 @@ sealed interface RadarAction {
// Calculator actions
data class ChangeCalculatorOffset(val offsetKHz: String) : RadarAction
/**
* The transponder currently driving the calculator (null when the satellite has
* no linear transponder). The per-satellite offset follows it instead of the
* transceiver selection, so it loads and saves even when nothing is selected.
*/
data class CalculatorTransponderChanged(val catnum: Int?) : RadarAction
data class UpdateCalculatorFrequency(val txHz: Long?, val rxHz: Long?) : RadarAction
}
@@ -69,6 +69,7 @@ class RadarViewModel(
private val stationPos = settingsRepo.stationPosition.value
private val magDeclination = sensorsRepo.getMagDeclination(stationPos)
private var transponders: List<SatRadio> = emptyList()
private var calculatorCatnum: Int? = null
private var sstvDecoder: SstvDecoder? = null
private var sstvRecordingJob: Job? = null
private var cwDecoder: CwDecoder? = null
@@ -158,12 +159,8 @@ class RadarViewModel(
transponders = allRadios.filter { it.downlinkLow != null }
if (allRadios.isNotEmpty()) {
val firstUuid = allRadios.first().uuid
val offsetKHz = allRadios.first().catnum?.let { settingsRepo.getSatelliteOffset(it) } ?: ""
_uiState.update {
it.copy(
transceivers = it.transceivers.copy(selectedUuid = firstUuid),
calculatorOffsetKHz = offsetKHz
)
it.copy(transceivers = it.transceivers.copy(selectedUuid = firstUuid))
}
transponders.find { it.uuid == firstUuid }?.let { trackingService.setTransponder(it) }
}
@@ -241,15 +238,8 @@ class RadarViewModel(
// Compute toggle state before the update so we don't read post-update value
val isTogglingOff = _uiState.value.transceivers.selectedUuid == action.uuid
val newUuid = if (isTogglingOff) null else action.uuid
val offsetKHz = if (!isTogglingOff) {
transponders.find { it.uuid == action.uuid }
?.catnum?.let { settingsRepo.getSatelliteOffset(it) } ?: ""
} else ""
_uiState.update {
it.copy(
transceivers = it.transceivers.copy(selectedUuid = newUuid),
calculatorOffsetKHz = offsetKHz
)
it.copy(transceivers = it.transceivers.copy(selectedUuid = newUuid))
}
// Only update the tracking service when selecting a different transponder to
// avoid resetting a user-adjusted TX base on re-expand
@@ -319,7 +309,9 @@ class RadarViewModel(
_uiState.update { it.copy(cw = it.cw.copy(isExpanded = action.expanded)) }
}
is RadarAction.ChangeCalculatorOffset -> {
val catnum = _uiState.value.transceivers.selectedUuid?.let { uuid ->
// Keyed by the transponder driving the calculator, so the offset saves
// even when no transceiver is selected (or selection was toggled off)
val catnum = calculatorCatnum ?: _uiState.value.transceivers.selectedUuid?.let { uuid ->
transponders.find { it.uuid == uuid }?.catnum
}
if (catnum != null) {
@@ -327,6 +319,11 @@ class RadarViewModel(
}
_uiState.update { it.copy(calculatorOffsetKHz = action.offsetKHz) }
}
is RadarAction.CalculatorTransponderChanged -> {
calculatorCatnum = action.catnum
val offsetKHz = action.catnum?.let { settingsRepo.getSatelliteOffset(it) } ?: ""
_uiState.update { it.copy(calculatorOffsetKHz = offsetKHz) }
}
is RadarAction.UpdateCalculatorFrequency -> {
_uiState.update {
if (it.calculatorTxHz == action.txHz && it.calculatorRxHz == action.rxHz) it
@@ -176,6 +176,13 @@ fun CalculatorPage(
?: calculatorTransceivers.firstOrNull()
}
// Keep the per-satellite offset in sync with the transponder driving the
// calculator: load the saved value on open/satellite change, and remember
// its catnum so editing saves even when no transceiver is selected
LaunchedEffect(selectedTransceiver?.uuid) {
onAction(RadarAction.CalculatorTransponderChanged(selectedTransceiver?.catnum))
}
if (selectedTransceiver == null) {
EmptyTransceiversContent(modifier)
return