fix: restore saved per-satellite calculator offset on open

The per-satellite doppler offset was loaded only inside SelectTransmitter, so
it never came back when the radar page was reopened, and it was saved under
the selected transceiver catnum - null after toggling the selection off, which
dropped the write silently. The CalculatorPage chips that trigger
SelectTransmitter are only rendered when a satellite has more than one linear
transponder after deduplication, so single-transponder satellites (JO-97,
RS-44, FO-29, AO-73, QO-100, TO-108, FO-82, QB50P1, UKUBE-1) had no way to
load it at all.

The offset now follows the transponder driving the calculator: it loads when
that transponder changes and saves under its catnum regardless of selection.
This commit is contained in:
atsunatsu committed 2026-10-05 20:00:17 +08:00
1 parent 5d792a0fc8
commit ccf1cff351
3 files changed
+24 -10

No files matched your search

@@ -101,4 +101,11 @@ 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
}
@@ -70,6 +70,7 @@ class RadarViewModel(
private var compassOffset = settingsRepo.otherSettings.value.radarCompassOffset
private var compassOffsetElev = settingsRepo.otherSettings.value.radarCompassOffsetElev
private var transponders: List<SatRadio> = emptyList()
private var calculatorCatnum: Int? = null
private var sstvDecoder: SstvDecoder? = null
private var sstvRecordingJob: Job? = null
private var sensorCollectionJob: Job? = null
@@ -260,16 +261,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
// Load the saved offset for the newly selected satellite
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
@@ -320,7 +313,9 @@ class RadarViewModel(
_uiState.update { it.copy(sstv = it.sstv.copy(currentFrame = null)) }
}
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) {
@@ -328,6 +323,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) }
}
}
}
@@ -140,6 +140,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