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 815fb997..f1dd7e9d 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
@@ -76,6 +76,7 @@ class SettingsRepo(
private val keyStateOfUtc = "stateOfUtc"
private val keyStateOfLightTheme = "stateOfLightTheme"
private val keyStateOfNightMode = "stateOfNightMode"
+ private val keyStateOfRoamingLive = "stateOfRoamingLive"
private val keyStationAltitude = "stationAltitude"
private val keyStationLatitude = "stationLatitude"
private val keyStationLongitude = "stationLongitude"
@@ -351,6 +352,7 @@ class SettingsRepo(
putBoolean(keyStateOfUtc, new.stateOfUtc)
putBoolean(keyStateOfLightTheme, new.stateOfLightTheme)
putBoolean(keyStateOfNightMode, new.stateOfNightMode)
+ putBoolean(keyStateOfRoamingLive, new.stateOfRoamingLive)
putBoolean(keyShouldSeeWarning, new.shouldSeeWarning)
putBoolean(keyShouldSeeWhatsNew, new.shouldSeeWhatsNew)
putString(keySstvMode, new.sstvMode)
@@ -368,6 +370,7 @@ class SettingsRepo(
stateOfUtc = preferences.getBoolean(keyStateOfUtc, false),
stateOfLightTheme = preferences.getBoolean(keyStateOfLightTheme, false),
stateOfNightMode = preferences.getBoolean(keyStateOfNightMode, false),
+ stateOfRoamingLive = preferences.getBoolean(keyStateOfRoamingLive, true),
shouldSeeWarning = preferences.getBoolean(keyShouldSeeWarning, true),
shouldSeeWhatsNew = preferences.getBoolean(keyShouldSeeWhatsNew, true),
sstvMode = preferences.getString(keySstvMode, null) ?: "Auto",
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..610d8b11 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
@@ -58,6 +58,7 @@ data class OtherSettings(
val stateOfUtc: Boolean,
val stateOfLightTheme: Boolean,
val stateOfNightMode: Boolean = false,
+ val stateOfRoamingLive: Boolean = true,
val shouldSeeWarning: Boolean,
val shouldSeeWhatsNew: Boolean,
val sstvMode: String = "Auto",
diff --git a/core/presentation/src/main/res/values-tr/strings.xml b/core/presentation/src/main/res/values-tr/strings.xml
index a9ff9f22..775b4b41 100644
--- a/core/presentation/src/main/res/values-tr/strings.xml
+++ b/core/presentation/src/main/res/values-tr/strings.xml
@@ -186,6 +186,7 @@
Radar taramasını etkinleştir
Radar görünümünü döndürmek için sensörleri kullan
Kırmızı gece filtresini etkinleştir
+ Roaming konumunu canlı güncelle
Elevasyon vurgusu
Düşük < %1$d°
diff --git a/core/presentation/src/main/res/values-zh/strings.xml b/core/presentation/src/main/res/values-zh/strings.xml
index 3f179459..fab23541 100644
--- a/core/presentation/src/main/res/values-zh/strings.xml
+++ b/core/presentation/src/main/res/values-zh/strings.xml
@@ -10,6 +10,7 @@
过境
雷达
匹配
+ 漫游
地图
设置
@@ -161,6 +162,7 @@
启用雷达扫描动画
使用传感器旋转雷达视图
启用红色夜间模式
+ 漫游位置实时更新
仰角高亮
低 < %1$d°
diff --git a/core/presentation/src/main/res/values/strings.xml b/core/presentation/src/main/res/values/strings.xml
index ca7ae6a0..01ef7861 100644
--- a/core/presentation/src/main/res/values/strings.xml
+++ b/core/presentation/src/main/res/values/strings.xml
@@ -197,6 +197,7 @@
Enable radar sweep animation
Use sensors to rotate radar view
Enable red night mode filter
+ Update Roaming position live
Elevation highlight
Low < %1$d°
diff --git a/feature/roaming/src/main/java/com/rtbishop/look4sat/feature/roaming/RoamingScreen.kt b/feature/roaming/src/main/java/com/rtbishop/look4sat/feature/roaming/RoamingScreen.kt
index 54cfbedd..07690fd3 100644
--- a/feature/roaming/src/main/java/com/rtbishop/look4sat/feature/roaming/RoamingScreen.kt
+++ b/feature/roaming/src/main/java/com/rtbishop/look4sat/feature/roaming/RoamingScreen.kt
@@ -18,20 +18,21 @@
package com.rtbishop.look4sat.feature.roaming
import androidx.compose.foundation.background
-import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -39,164 +40,214 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import com.rtbishop.look4sat.core.presentation.CardButton
-
-private val InfoCyan = Color(0xFF0CCFE2)
-private val GridBlue = Color(0xFF12ACE0)
-private val LabelBlue = Color(0xFF135678)
-private val PositionRed = Color(0xFFFF0000)
-private val DividerWhite = Color(0xFFF7F7F7)
+import com.rtbishop.look4sat.core.presentation.LocalSpacing
+import com.rtbishop.look4sat.core.presentation.ScreenColumn
+import com.rtbishop.look4sat.core.presentation.TopBar
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+/**
+ * Roaming (漫游) page: a faithful port of the QTH定位器 location panel —
+ * GPS status + date/time header, DMS & decimal coordinates, the big 8-char
+ * Maidenhead locator, and a 3x3 grid of neighboring squares (center column
+ * and row are wider/taller, matching the reference app). Styled with the
+ * Look4Sat Material 3 theme.
+ */
@Composable
fun RoamingScreen(viewModel: RoamingViewModel) {
val state by viewModel.uiState.collectAsStateWithLifecycle()
- Column(modifier = Modifier.fillMaxSize()) {
- InfoHeader(state = state, onGpsClick = viewModel::onGpsClick)
- GridPanel(state = state)
+ ScreenColumn(
+ topBar = {
+ TopBar { Text(text = "漫游", fontSize = 20.sp, fontWeight = FontWeight.Bold) }
+ }
+ ) {
+ val spacing = LocalSpacing.current
+ Column(verticalArrangement = Arrangement.spacedBy(spacing.medium)) {
+ InfoCard(state = state)
+ GridCard(state = state)
+ }
}
}
@Composable
-private fun InfoHeader(state: RoamingState, onGpsClick: () -> Unit) {
- Column(
- modifier = Modifier
- .fillMaxWidth()
- .background(InfoCyan)
- .padding(horizontal = 16.dp, vertical = 10.dp)
- ) {
- // Top row: GPS status + big locator
- Row(verticalAlignment = Alignment.CenterVertically) {
- Text(
- text = "GPS",
- fontSize = 20.sp,
- fontWeight = FontWeight.Medium,
- color = Color.Black
- )
- Spacer(modifier = Modifier.width(8.dp))
- Box(
- modifier = Modifier
- .size(12.dp)
- .clip(CircleShape)
- .background(if (state.qthLocator != "----") Color(0xFF3BAF52) else Color.Gray)
- )
- Spacer(modifier = Modifier.weight(1f))
+private fun InfoCard(state: RoamingState) {
+ val colorScheme = MaterialTheme.colorScheme
+ ElevatedCard(modifier = Modifier.fillMaxWidth()) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(16.dp),
+ verticalArrangement = Arrangement.spacedBy(8.dp)
+ ) {
+ // Top bar: GPS status + date + time
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Text(
+ text = "GPS",
+ fontSize = 16.sp,
+ fontWeight = FontWeight.Medium,
+ color = colorScheme.onSurface
+ )
+ Spacer(modifier = Modifier.width(6.dp))
+ Box(
+ modifier = Modifier
+ .size(10.dp)
+ .clip(CircleShape)
+ .background(if (state.gpsEnabled) colorScheme.primary else colorScheme.outline)
+ )
+ Spacer(modifier = Modifier.weight(1f))
+ Text(
+ text = SimpleDateFormat("dd MMM yyyy", Locale.getDefault()).format(Date()),
+ fontSize = 14.sp,
+ color = colorScheme.onSurfaceVariant
+ )
+ Spacer(modifier = Modifier.width(12.dp))
+ Text(
+ text = SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date()),
+ fontSize = 16.sp,
+ fontWeight = FontWeight.Medium,
+ color = colorScheme.onSurface
+ )
+ }
+ // Coordinates: DMS + decimal
+ CoordinateRow(label = "纬度", value = state.latitude, isLat = true)
+ CoordinateRow(label = "经度", value = state.longitude, isLat = false)
+ // Big locator, centered
Text(
text = state.qthLocator,
- fontSize = 30.sp,
+ fontSize = 34.sp,
fontWeight = FontWeight.Bold,
fontFamily = FontFamily.Monospace,
- color = Color.Black
+ color = colorScheme.primary,
+ textAlign = TextAlign.Center,
+ modifier = Modifier.fillMaxWidth()
)
}
- Spacer(modifier = Modifier.height(10.dp))
- // Lat / Lon rows with DMS + decimal
- CoordinateRow(label = "Lat", value = state.latitude, isLat = true)
- Spacer(modifier = Modifier.height(4.dp))
- CoordinateRow(label = "Lon", value = state.longitude, isLat = false)
- Spacer(modifier = Modifier.height(10.dp))
- CardButton(
- onClick = onGpsClick,
- text = "GPS 定位",
- modifier = Modifier.fillMaxWidth()
- )
}
}
@Composable
private fun CoordinateRow(label: String, value: Double, isLat: Boolean) {
- Row(
- verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier.fillMaxWidth()
- ) {
+ val colorScheme = MaterialTheme.colorScheme
+ Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
Text(
text = label,
- fontSize = 16.sp,
- fontWeight = FontWeight.Medium,
- color = Color.Black,
- modifier = Modifier.width(44.dp)
- )
- Text(
- text = formatDms(value, isLat),
fontSize = 15.sp,
- color = Color.Black
+ fontWeight = FontWeight.Medium,
+ color = colorScheme.onSurface,
+ modifier = Modifier.width(40.dp)
)
+ Text(text = formatDms(value, isLat), fontSize = 15.sp, color = colorScheme.onSurface)
Spacer(modifier = Modifier.weight(1f))
Text(
text = "${formatDecimal(value)}°",
fontSize = 14.sp,
- color = LabelBlue
+ color = colorScheme.onSurfaceVariant
)
}
}
+/**
+ * 3x3 grid of 4-char squares. Column widths 21.4% : 56.2% : 21.4% and row
+ * heights 31.5% : 35.9% : 31.7% mirror the reference app: the center column
+ * is ~2.6x wider and the center row is the tallest, so the current square
+ * dominates the panel.
+ */
@Composable
-private fun GridPanel(state: RoamingState) {
- Column(
- modifier = Modifier
- .fillMaxSize()
- .background(GridBlue)
- .padding(4.dp)
- ) {
- // 3x3 grid: row 0 = north
- for (row in 0..2) {
- Row(
- modifier = Modifier
- .fillMaxWidth()
- .weight(1f),
- horizontalArrangement = Arrangement.spacedBy(4.dp)
- ) {
- for (col in 0..2) {
- val index = row * 3 + col
- val isCenter = index == 4
- GridCell(
- label = state.gridSquares.getOrElse(index) { "----" },
- isCenter = isCenter,
- showMarker = isCenter && state.qthLocator != "----",
- modifier = Modifier.weight(1f)
- )
- }
- }
- if (row < 2) Spacer(modifier = Modifier.height(4.dp))
+private fun GridCard(state: RoamingState) {
+ ElevatedCard(modifier = Modifier.fillMaxWidth()) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(10.dp),
+ verticalArrangement = Arrangement.spacedBy(6.dp)
+ ) {
+ GridRow(state, row = 0, heightFraction = 0.315f)
+ GridRow(state, row = 1, heightFraction = 0.359f)
+ GridRow(state, row = 2, heightFraction = 0.317f)
}
}
}
+@Composable
+private fun GridRow(state: RoamingState, row: Int, heightFraction: Float) {
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.spacedBy(6.dp)
+ ) {
+ GridCell(
+ label = state.gridSquares.getOrElse(row * 3 + 0) { "----" },
+ isCenter = false,
+ markerX = state.markerX,
+ markerY = state.markerY,
+ modifier = Modifier.weight(0.214f)
+ )
+ GridCell(
+ label = state.gridSquares.getOrElse(row * 3 + 1) { "----" },
+ isCenter = row == 1,
+ markerX = state.markerX,
+ markerY = state.markerY,
+ showMarker = row == 1 && state.qthLocator != "----",
+ modifier = Modifier.weight(0.562f)
+ )
+ GridCell(
+ label = state.gridSquares.getOrElse(row * 3 + 2) { "----" },
+ isCenter = false,
+ markerX = state.markerX,
+ markerY = state.markerY,
+ modifier = Modifier.weight(0.214f)
+ )
+ }
+}
+
@Composable
private fun GridCell(
label: String,
isCenter: Boolean,
- showMarker: Boolean,
+ markerX: Float,
+ markerY: Float,
+ showMarker: Boolean = false,
modifier: Modifier = Modifier
) {
- Box(
+ val colorScheme = MaterialTheme.colorScheme
+ val cellBackground = if (isCenter) colorScheme.secondaryContainer else colorScheme.surfaceVariant
+ val labelColor = if (isCenter) colorScheme.onSecondaryContainer else colorScheme.onSurfaceVariant
+ BoxWithConstraints(
contentAlignment = Alignment.Center,
modifier = modifier
- .aspectRatio(1f)
- .background(if (isCenter) InfoCyan else GridBlue)
- .border(1.dp, DividerWhite)
+ .height(84.dp)
+ .clip(MaterialTheme.shapes.medium)
+ .background(cellBackground)
) {
+ // Capture constraints at the BoxWithConstraints scope (Column scope would shadow them)
+ val width = maxWidth
+ val height = maxHeight
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(
text = label,
- fontSize = if (isCenter) 26.sp else 16.sp,
+ fontSize = if (isCenter) 22.sp else 14.sp,
fontWeight = if (isCenter) FontWeight.Bold else FontWeight.Normal,
- color = LabelBlue,
+ color = labelColor,
textAlign = TextAlign.Center
)
if (showMarker) {
Spacer(modifier = Modifier.height(4.dp))
+ // Red marker at the fractional position inside the center cell
+ val density = LocalDensity.current
+ val offsetX = with(density) { (width * (markerX - 0.5f)).toPx().toDp() }
+ val offsetY = with(density) { (height * (markerY - 0.5f)).toPx().toDp() }
Box(
modifier = Modifier
.size(12.dp)
- .background(PositionRed)
- .border(2.dp, DividerWhite)
+ .background(colorScheme.error)
+ .offset(x = offsetX, y = offsetY)
)
}
}
diff --git a/feature/roaming/src/main/java/com/rtbishop/look4sat/feature/roaming/RoamingViewModel.kt b/feature/roaming/src/main/java/com/rtbishop/look4sat/feature/roaming/RoamingViewModel.kt
index 70444867..d0882671 100644
--- a/feature/roaming/src/main/java/com/rtbishop/look4sat/feature/roaming/RoamingViewModel.kt
+++ b/feature/roaming/src/main/java/com/rtbishop/look4sat/feature/roaming/RoamingViewModel.kt
@@ -27,19 +27,24 @@ import com.rtbishop.look4sat.core.domain.repository.ISettingsRepo
import com.rtbishop.look4sat.core.domain.utility.positionToQth
import com.rtbishop.look4sat.core.domain.utility.qthNeighbors
import com.rtbishop.look4sat.core.domain.utility.qthToSquare
+import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
+import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
data class RoamingState(
val latitude: Double = 0.0,
val longitude: Double = 0.0,
- val altitude: Double = 0.0,
val qthLocator: String = "----",
val gridSquares: List = List(9) { "----" },
- val isUpdating: Boolean = false,
- val messageResId: Int = 0
+ /** Fractional position of the red marker inside the center cell, 0..1. */
+ val markerX: Float = 0.5f,
+ val markerY: Float = 0.5f,
+ /** True when a fresh GPS fix is available (station position updated recently). */
+ val gpsEnabled: Boolean = false,
+ val isUpdating: Boolean = false
)
class RoamingViewModel(private val settingsRepo: ISettingsRepo) : ViewModel() {
@@ -47,19 +52,42 @@ class RoamingViewModel(private val settingsRepo: ISettingsRepo) : ViewModel() {
private val _uiState = MutableStateFlow(RoamingState())
val uiState: StateFlow = _uiState
+ private var liveEnabled: Boolean = true
+
init {
+ // Follow station position updates
viewModelScope.launch {
settingsRepo.stationPosition.collect { geoPos ->
- _uiState.update { it.copy(isUpdating = false, messageResId = 0).withPosition(geoPos) }
+ _uiState.update { state ->
+ state.copy(isUpdating = false, gpsEnabled = isFixFresh(geoPos)).withPosition(geoPos)
+ }
+ }
+ }
+ // Follow the "live update" preference; when enabled, periodically refresh the fix
+ viewModelScope.launch {
+ settingsRepo.otherSettings.collect { other ->
+ liveEnabled = other.stateOfRoamingLive
+ if (liveEnabled) refreshPosition()
+ }
+ }
+ viewModelScope.launch {
+ while (isActive) {
+ delay(30_000L)
+ if (liveEnabled) refreshPosition()
+ _uiState.update { state ->
+ state.copy(gpsEnabled = isFixFresh(settingsRepo.stationPosition.value))
+ }
}
}
}
- fun onGpsClick() {
- val success = settingsRepo.setStationPosition()
- if (success) {
- _uiState.update { it.copy(isUpdating = true) }
- }
+ /** Ask the settings repo for the latest fix (triggers GPS request if stale). */
+ private fun refreshPosition() {
+ settingsRepo.setStationPosition()
+ }
+
+ private fun isFixFresh(pos: GeoPos): Boolean {
+ return pos.timestamp > 0L && System.currentTimeMillis() - pos.timestamp < 600_000L
}
private fun RoamingState.withPosition(pos: GeoPos): RoamingState {
@@ -69,12 +97,31 @@ class RoamingViewModel(private val settingsRepo: ISettingsRepo) : ViewModel() {
return copy(
latitude = pos.latitude,
longitude = pos.longitude,
- altitude = pos.altitude,
qthLocator = locator,
- gridSquares = squares
+ gridSquares = squares,
+ markerX = markerFraction(pos.longitude, square, isLat = false),
+ markerY = markerFraction(pos.latitude, square, isLat = true)
)
}
+ /**
+ * Fractional position of [value] (lon or lat) inside its 4-char square.
+ * A square spans 2° of longitude and 1° of latitude; the fraction is
+ * measured from the square's south-west corner, 0..1.
+ */
+ private fun markerFraction(value: Double, square: String, isLat: Boolean): Float {
+ if (square.length != 4) return 0.5f
+ val fieldIndex = (square[if (isLat) 1 else 0].uppercaseChar().code - 65).coerceIn(0, 17)
+ val squareIndex = square[if (isLat) 3 else 2].digitToIntOrNull() ?: return 0.5f
+ val cellSize = if (isLat) 1.0 else 2.0
+ val cellStart = if (isLat) {
+ fieldIndex * 10.0 + squareIndex - 90.0
+ } else {
+ fieldIndex * 20.0 + squareIndex * 2.0 - 180.0
+ }
+ return ((value - cellStart) / cellSize).coerceIn(0.0, 1.0).toFloat()
+ }
+
companion object {
fun factory(container: IMainContainer) = viewModelFactory {
initializer { RoamingViewModel(container.settingsRepo) }
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 ebfefc44..468a4b73 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
@@ -488,7 +488,7 @@ private fun OtherCard(settings: OtherSettings, onAction: (SettingsAction) -> Uni
ElevatedCard(
modifier = Modifier
.fillMaxWidth()
- .height(268.dp)
+ .height(296.dp)
) {
Column(modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)) {
Text(
@@ -510,6 +510,9 @@ private fun OtherCard(settings: OtherSettings, onAction: (SettingsAction) -> Uni
SwitchRow(R.string.prefs_other_switch_night_mode, settings.stateOfNightMode) {
onAction(SettingsAction.ToggleNightMode(it))
}
+ SwitchRow(R.string.prefs_other_switch_roaming_live, settings.stateOfRoamingLive) {
+ onAction(SettingsAction.ToggleRoamingLive(it))
+ }
}
}
}
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..4b7e667f 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,7 @@ sealed interface SettingsAction {
data class ToggleSensor(val value: Boolean) : SettingsAction
data class ToggleLightTheme(val value: Boolean) : SettingsAction
data class ToggleNightMode(val value: Boolean) : SettingsAction
+ data class ToggleRoamingLive(val value: Boolean) : 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..fc646d14 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,7 @@ 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.ToggleRoamingLive -> settingsRepo.updateOtherSettings { it.copy(stateOfRoamingLive = action.value) }
// Remote control & data sources
is SettingsAction.UpdateRC -> settingsRepo.updateRCSettings(action.settings)
is SettingsAction.UpdateRadioControl -> settingsRepo.updateRadioControlSettings(action.settings)