More fixes for SettingsScreen.kt and its states

pull/122/head
Arty Bishop 2023-03-12 13:04:12 +00:00
rodzic a8e5bf3e43
commit 1f63cea626
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 5C71CFDC37AD73CC
5 zmienionych plików z 181 dodań i 230 usunięć

Wyświetl plik

@ -82,13 +82,17 @@ fun MapScreen(viewModel: MapViewModel = hiltViewModel()) {
}
private fun setStationPosition(stationPos: GeoPos, mapView: MapView) {
Marker(mapView).apply {
setInfoWindow(null)
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
icon = ContextCompat.getDrawable(mapView.context, R.drawable.ic_position)
position = GeoPoint(stationPos.lat, stationPos.lon)
mapView.overlays[0] = this
mapView.invalidate()
try {
Marker(mapView).apply {
setInfoWindow(null)
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
icon = ContextCompat.getDrawable(mapView.context, R.drawable.ic_position)
position = GeoPoint(stationPos.lat, stationPos.lon)
mapView.overlays[0] = this
mapView.invalidate()
}
} catch (exception: Exception) {
Timber.d(exception)
}
}
@ -97,20 +101,24 @@ private fun setPositions(
) {
val markers = FolderOverlay()
posMap.entries.forEach {
Marker(mapView).apply {
setInfoWindow(null)
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER)
icon = getCustomTextIcon(it.key.data.name, mapView)
try {
position = GeoPoint(it.value.lat, it.value.lon)
} catch (exception: IllegalArgumentException) {
println(exception.stackTraceToString())
try {
Marker(mapView).apply {
setInfoWindow(null)
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER)
icon = getCustomTextIcon(it.key.data.name, mapView)
try {
position = GeoPoint(it.value.lat, it.value.lon)
} catch (exception: IllegalArgumentException) {
println(exception.stackTraceToString())
}
setOnMarkerClickListener { _, _ ->
action(it.key)
return@setOnMarkerClickListener true
}
markers.add(this)
}
setOnMarkerClickListener { _, _ ->
action(it.key)
return@setOnMarkerClickListener true
}
markers.add(this)
} catch (exception: Exception) {
Timber.d(exception)
}
}
mapView.overlays[3] = markers

Wyświetl plik

@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
@ -25,7 +24,6 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import com.rtbishop.look4sat.BuildConfig
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.domain.model.OtherSettings
import com.rtbishop.look4sat.presentation.CardButton
import com.rtbishop.look4sat.presentation.MainTheme
import com.rtbishop.look4sat.presentation.gotoUrl
@ -50,7 +48,7 @@ fun SettingsScreen(navController: NavController) {
else -> Manifest.permission.BLUETOOTH_CONNECT
}
val bluetoothRequest = rememberLauncherForActivityResult(bluetoothContract) { isGranted ->
viewModel.setBTEnabled(isGranted)
// viewModel.setBTEnabled(isGranted)
if (!isGranted) showToast(context, bluetoothError)
}
val locationContract = ActivityResultContracts.RequestMultiplePermissions()
@ -59,51 +57,43 @@ fun SettingsScreen(navController: NavController) {
val locationPermFine = Manifest.permission.ACCESS_FINE_LOCATION
val locationRequest = rememberLauncherForActivityResult(locationContract) { permissions ->
when {
permissions[locationPermFine] == true -> viewModel.setPositionFromGps()
permissions[locationPermCoarse] == true -> viewModel.setPositionFromNet()
permissions[locationPermFine] == true -> viewModel.locationSettings.value.setGpsLoc
permissions[locationPermCoarse] == true -> viewModel.locationSettings.value.setGpsLoc
else -> showToast(context, locationError)
}
}
val contentContract = ActivityResultContracts.GetContent()
val contentRequest = rememberLauncherForActivityResult(contentContract) { uri ->
uri?.let { viewModel.updateFromFile(uri.toString()) }
uri?.let { viewModel.dataSettings.value.updateFromFile(uri.toString()) }
}
// Location settings
val locSettings = viewModel.locationSettings.value
val setGpsLoc = { locationRequest.launch(arrayOf(locationPermCoarse, locationPermFine)) }
val geoPos = viewModel.getStationPosition()
val showPosDialog = rememberSaveable { mutableStateOf(false) }
val togglePosDialog = { showPosDialog.value = showPosDialog.value.not() }
val savePos = { lat: Double, lon: Double -> viewModel.setStationPosition(lat, lon) }
if (showPosDialog.value) {
PositionDialog(lat = geoPos.lat, lon = geoPos.lon, hide = togglePosDialog, save = savePos)
PositionDialog(
locSettings.getLatitude,
locSettings.getLongitude,
togglePosDialog,
locSettings.setManualLoc
)
}
val qthLocator = viewModel.getStationLocator()
val showLocDialog = rememberSaveable { mutableStateOf(false) }
val toggleLocDialog = { showLocDialog.value = showLocDialog.value.not() }
val saveLocator = { locator: String -> viewModel.setPositionFromQth(locator) }
if (showLocDialog.value) {
LocatorDialog(qthLocator = qthLocator, hide = toggleLocDialog, save = saveLocator)
LocatorDialog(locSettings.getLocator, toggleLocDialog, locSettings.setQthLoc)
}
// Data settings
val updateFromWeb = { viewModel.updateFromWeb() }
val updateFromFile = { contentRequest.launch("*/*") }
val clearAllData = { viewModel.clearAllData() }
// Other settings
val otherSettings = viewModel.otherSettings.collectAsState()
val setUtc = { value: Boolean -> viewModel.setUtcState(value) }
val setUpdate = { value: Boolean -> viewModel.setUpdateState(value) }
val setSweep = { value: Boolean -> viewModel.setSweepState(value) }
val setSensor = { value: Boolean -> viewModel.setSensorState(value) }
// Screen setup
LazyColumn(
modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)
) {
item { CardAbout(BuildConfig.VERSION_NAME) }
item { LocationCard(setGpsLoc, togglePosDialog, toggleLocDialog) }
item { DataCard(updateFromWeb, updateFromFile, clearAllData) }
item { OtherCard(otherSettings.value, setUtc, setUpdate, setSweep, setSensor) }
item { LocationCard(locSettings, setGpsLoc, togglePosDialog, toggleLocDialog) }
item { DataCard(viewModel.dataSettings.value) { contentRequest.launch("*/*") } }
item { OtherCard(viewModel.otherSettings.value) }
item { CardCredits() }
}
}
@ -164,36 +154,33 @@ private fun CardAbout(version: String, modifier: Modifier = Modifier) {
@Preview(showBackground = true)
@Composable
private fun LocationCardPreview() {
MainTheme { LocationCard({}, {}, {}) }
MainTheme { }
}
@Composable
private fun LocationCard(
setGpsLoc: () -> Unit, togglePosDialog: () -> Unit, toggleLocDialog: () -> Unit
settings: LocationSettings,
setGpsLoc: () -> Unit,
togglePosDialog: () -> Unit,
toggleLocDialog: () -> Unit
) {
val context = LocalContext.current
// setPositionText(viewModel.getStationPosition())
ElevatedCard(modifier = Modifier.fillMaxWidth()) {
Column(modifier = Modifier.padding(4.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(text = "Station position")
LinearProgressIndicator(
modifier = Modifier
.weight(1f)
.padding(start = 6.dp, end = 6.dp)
)
UpdateIndicator(isUpdating = settings.getUpdating, Modifier.weight(1f))
}
Row(
horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()
) {
Text(text = "Updated: 3 Mar 2023 - 15:51")
Text(text = "QTH: IO91vl")
Text(text = "Updated: ${settings.getLastUpdated}")
Text(text = "QTH: ${settings.getLocator}")
}
Row(
horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()
) {
Text(text = "Latitude: *")
Text(text = "Longitude: *")
Text(text = "Latitude: ${settings.getLatitude}")
Text(text = "Longitude: ${settings.getLongitude}")
}
Row(horizontalArrangement = Arrangement.SpaceEvenly) {
CardButton(
@ -216,48 +203,40 @@ private fun LocationCard(
@Preview(showBackground = true)
@Composable
private fun DataCardPreview() {
MainTheme { DataCard({}, {}, {}) }
MainTheme { }
}
@Composable
private fun DataCard(updateOnline: () -> Unit, updateFile: () -> Unit, clearData: () -> Unit) {
val context = LocalContext.current
// setUpdateTime(viewModel.getLastUpdateTime())
// viewModel.entriesTotal
// viewModel.radiosTotal
private fun DataCard(settings: DataSettings, updateFromFile: () -> Unit) {
ElevatedCard(modifier = Modifier.fillMaxWidth()) {
Column(modifier = Modifier.padding(4.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(text = "Satellite data")
LinearProgressIndicator(
modifier = Modifier
.weight(1f)
.padding(start = 6.dp, end = 6.dp)
)
UpdateIndicator(isUpdating = settings.getUpdating, Modifier.weight(1f))
}
Row(
horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()
) {
Text(text = "Updated: 3 Mar 2023 - 15:51")
Text(text = "Updated: ${settings.getLastUpdated}")
Text(text = "")
}
Row(
horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()
) {
Text(text = "Satellites: 7749")
Text(text = "Transceivers: 2240")
Text(text = "Satellites: ${settings.getSatellites}")
Text(text = "Transceivers: ${settings.getRadios}")
}
Row(horizontalArrangement = Arrangement.SpaceEvenly) {
CardButton(
onClick = updateOnline, // viewModel.updateFromWeb()
onClick = settings.updateFromWeb, // viewModel.updateFromWeb()
text = stringResource(id = R.string.btn_web), modifier = Modifier.weight(1f)
)
CardButton(
onClick = updateFile, // contentRequest.launch("*/*")
onClick = updateFromFile, // contentRequest.launch("*/*")
text = stringResource(id = R.string.btn_file), modifier = Modifier.weight(1f)
)
CardButton(
onClick = clearData, // viewModel.clearAllData()
onClick = settings.clearAllData, // viewModel.clearAllData()
text = stringResource(id = R.string.btn_clear), modifier = Modifier.weight(1f)
)
}
@ -317,13 +296,7 @@ private fun OtherCardPreview() {
}
@Composable
private fun OtherCard(
settings: OtherSettings,
setUtc: (Boolean) -> Unit,
setUpdate: (Boolean) -> Unit,
setSweep: (Boolean) -> Unit,
setSensor: (Boolean) -> Unit
) {
private fun OtherCard(settings: OtherSettings) {
ElevatedCard(modifier = Modifier.fillMaxWidth()) {
Column(modifier = Modifier.padding(4.dp)) {
Text(text = stringResource(id = R.string.other_title))
@ -333,7 +306,7 @@ private fun OtherCard(
modifier = Modifier.fillMaxWidth()
) {
Text(text = stringResource(id = R.string.other_switch_utc))
Switch(checked = settings.isUtcEnabled, onCheckedChange = { setUtc(it) })
Switch(checked = settings.getUtc, onCheckedChange = { settings.setUtc(it) })
} // viewModel.setUseUTC(isChecked)
Row(
horizontalArrangement = Arrangement.SpaceBetween,
@ -341,7 +314,7 @@ private fun OtherCard(
modifier = Modifier.fillMaxWidth()
) {
Text(text = stringResource(id = R.string.other_switch_update))
Switch(checked = settings.isUpdateEnabled, onCheckedChange = { setUpdate(it) })
Switch(checked = settings.getUpdate, onCheckedChange = { settings.setUpdate(it) })
} // AutoUpdateEnabled(isChecked)
Row(
horizontalArrangement = Arrangement.SpaceBetween,
@ -349,7 +322,7 @@ private fun OtherCard(
modifier = Modifier.fillMaxWidth()
) {
Text(text = stringResource(id = R.string.other_switch_sweep))
Switch(checked = settings.isSweepEnabled, onCheckedChange = { setSweep(it) })
Switch(checked = settings.getSweep, onCheckedChange = { settings.setSweep(it) })
} // viewModel.setShowSweep(isChecked)
Row(
horizontalArrangement = Arrangement.SpaceBetween,
@ -357,65 +330,15 @@ private fun OtherCard(
modifier = Modifier.fillMaxWidth()
) {
Text(text = stringResource(id = R.string.other_switch_sensors))
Switch(checked = settings.isSensorEnabled, onCheckedChange = { setSensor(it) })
Switch(checked = settings.getSensor, onCheckedChange = { settings.setSensor(it) })
} // viewModel.setUseCompass(isChecked)
}
}
}
//
//private fun handleStationPosition(pos: DataState<GeoPos>) {
// when (pos) {
// is DataState.Success -> {
// setPositionText(pos.data)
// binding.settingsLocation.locationProgress.isIndeterminate = false
// viewModel.setPositionHandled()
// showToast(getString(R.string.location_success))
// }
// is DataState.Error -> {
// binding.settingsLocation.locationProgress.isIndeterminate = false
// viewModel.setPositionHandled()
// showToast(pos.message.toString())
// }
// DataState.Loading -> {
// binding.settingsLocation.locationProgress.isIndeterminate = true
// }
// DataState.Handled -> {}
// }
//}
//
//private fun setPositionText(geoPos: GeoPos) {
// binding.run {
// val latFormat = getString(R.string.location_lat)
// val lonFormat = getString(R.string.location_lon)
// settingsLocation.locationLat.text = String.format(latFormat, geoPos.lat)
// settingsLocation.locationLon.text = String.format(lonFormat, geoPos.lon)
// }
//}
//
//private fun handleSatState(state: DataState<Long>) {
// when (state) {
// is DataState.Success -> {
// binding.settingsData.dataProgress.isIndeterminate = false
// setUpdateTime(state.data)
// viewModel.setUpdateHandled()
// if (state.data == 0L) {
// showToast(getString(R.string.data_clear_success))
// } else {
// showToast(getString(R.string.data_success))
// }
// }
// is DataState.Error -> {
// binding.settingsData.dataProgress.isIndeterminate = false
// viewModel.setUpdateHandled()
// showToast(getString(R.string.data_error))
// }
// is DataState.Loading -> {
// binding.settingsData.dataProgress.isIndeterminate = true
// }
// is DataState.Handled -> {}
// }
//}
//
//private fun setUpdateTime(updateTime: Long) {
// val updatePattern = getString(R.string.data_update)
@ -469,3 +392,10 @@ private fun CardCredits(modifier: Modifier = Modifier) {
}
}
}
@Composable
private fun UpdateIndicator(isUpdating: Boolean, modifier: Modifier = Modifier) = if (isUpdating) {
LinearProgressIndicator(modifier = modifier.padding(start = 6.dp, end = 6.dp))
} else {
LinearProgressIndicator(modifier = modifier.padding(start = 6.dp, end = 6.dp), progress = 0f)
}

Wyświetl plik

@ -0,0 +1,33 @@
package com.rtbishop.look4sat.presentation.settingsScreen
data class LocationSettings(
val getUpdating: Boolean,
val getLastUpdated: Long,
val getLatitude: Double,
val getLongitude: Double,
val getLocator: String,
val setGpsLoc: () -> Unit,
val setManualLoc: (Double, Double) -> Unit,
val setQthLoc: (String) -> Unit
)
data class DataSettings(
val getUpdating: Boolean,
val getLastUpdated: Long,
val getSatellites: Int,
val getRadios: Int,
val updateFromWeb: () -> Unit,
val updateFromFile: (String) -> Unit,
val clearAllData: () -> Unit
)
data class OtherSettings(
val getUtc: Boolean,
val getUpdate: Boolean,
val getSweep: Boolean,
val getSensor: Boolean,
val setUtc: (Boolean) -> Unit,
val setUpdate: (Boolean) -> Unit,
val setSweep: (Boolean) -> Unit,
val setSensor: (Boolean) -> Unit
)

Wyświetl plik

@ -17,17 +17,16 @@
*/
package com.rtbishop.look4sat.presentation.settingsScreen
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.rtbishop.look4sat.domain.IDataRepository
import com.rtbishop.look4sat.domain.ILocationManager
import com.rtbishop.look4sat.domain.ISettingsManager
import com.rtbishop.look4sat.domain.model.DataState
import com.rtbishop.look4sat.domain.model.OtherSettings
import com.rtbishop.look4sat.domain.predict.GeoPos
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
@ -37,100 +36,89 @@ class SettingsViewModel @Inject constructor(
private val settings: ISettingsManager
) : ViewModel() {
private val _otherSettings = MutableStateFlow(
OtherSettings(
settings.isUtcEnabled(),
settings.isUpdateEnabled(),
settings.isSweepEnabled(),
settings.isSensorEnabled()
)
)
val otherSettings: StateFlow<OtherSettings> = _otherSettings
private val defaultLocationSettings = LocationSettings(false,
settings.getLastUpdateTime(),
locationManager.getStationPosition().lat,
locationManager.getStationPosition().lon,
settings.loadStationLocator(),
{ locationManager.setPositionFromGps() },
{ lat, lon -> locationManager.setStationPosition(lat, lon) },
{ locationManager.setPositionFromQth(it) })
var locationSettings = mutableStateOf(defaultLocationSettings)
private set
fun setUtcState(value: Boolean) {
private val defaultDataSettings = DataSettings(false,
settings.getLastUpdateTime(),
0,
0,
{ repository.updateFromWeb() },
{ repository.updateFromFile(it) },
{ repository.clearAllData() })
var dataSettings = mutableStateOf(defaultDataSettings)
private set
private val defaultOtherSettings = OtherSettings(settings.isUtcEnabled(),
settings.isUpdateEnabled(),
settings.isSweepEnabled(),
settings.isSensorEnabled(),
{ setUtc(it) },
{ setUpdate(it) },
{ setSweep(it) },
{ setSensor(it) })
var otherSettings = mutableStateOf(defaultOtherSettings)
private set
init {
viewModelScope.launch {
repository.updateState.collect {
val isUpdating = it is DataState.Loading
dataSettings.value = dataSettings.value.copy(
getUpdating = isUpdating, getLastUpdated = settings.getLastUpdateTime()
)
}
}
viewModelScope.launch {
combine(repository.getEntriesTotal(), repository.getRadiosTotal()) { sats, radios ->
dataSettings.value =
dataSettings.value.copy(getSatellites = sats, getRadios = radios)
}.collect {
}
}
}
private fun setUtc(value: Boolean) {
settings.setUtcState(value)
_otherSettings.value = otherSettings.value.copy(isUtcEnabled = value)
otherSettings.value = otherSettings.value.copy(getUtc = value)
}
fun setUpdateState(value: Boolean) {
private fun setUpdate(value: Boolean) {
settings.setUpdateState(value)
_otherSettings.value = otherSettings.value.copy(isUpdateEnabled = value)
otherSettings.value = otherSettings.value.copy(getUpdate = value)
}
fun setSweepState(value: Boolean) {
private fun setSweep(value: Boolean) {
settings.setSweepState(value)
_otherSettings.value = otherSettings.value.copy(isSweepEnabled = value)
otherSettings.value = otherSettings.value.copy(getSweep = value)
}
fun setSensorState(value: Boolean) {
private fun setSensor(value: Boolean) {
settings.setSensorState(value)
_otherSettings.value = otherSettings.value.copy(isSensorEnabled = value)
otherSettings.value = otherSettings.value.copy(getSensor = value)
}
val entriesTotal = repository.getEntriesTotal()
val radiosTotal = repository.getRadiosTotal()
fun updateFromFile(uri: String) = repository.updateFromFile(uri)
fun updateFromWeb() = repository.updateFromWeb()
fun clearAllData() = repository.clearAllData()
fun getUseUTC(): Boolean = settings.isUtcEnabled()
fun getLastUpdateTime(): Long = settings.getLastUpdateTime()
fun getAutoUpdateEnabled(): Boolean = settings.isUpdateEnabled()
fun getUseCompass(): Boolean = settings.isSensorEnabled()
fun getShowSweep(): Boolean = settings.isSweepEnabled()
fun getRotatorEnabled(): Boolean = settings.getRotatorEnabled()
fun setRotatorEnabled(value: Boolean) = settings.setRotatorEnabled(value)
fun getRotatorServer(): String = settings.getRotatorServer()
fun setRotatorServer(value: String) = settings.setRotatorServer(value)
fun getRotatorPort(): String = settings.getRotatorPort()
fun setRotatorPort(value: String) = settings.setRotatorPort(value)
fun getBTEnabled(): Boolean = settings.getBTEnabled()
fun setBTEnabled(value: Boolean) = settings.setBTEnabled(value)
fun getBTFormat(): String = settings.getBTFormat()
fun setBTFormat(value: String) = settings.setBTFormat(value)
// fun getRotatorEnabled(): Boolean = settings.getRotatorEnabled()
// fun setRotatorEnabled(value: Boolean) = settings.setRotatorEnabled(value)
// fun getRotatorServer(): String = settings.getRotatorServer()
// fun setRotatorServer(value: String) = settings.setRotatorServer(value)
// fun getRotatorPort(): String = settings.getRotatorPort()
// fun setRotatorPort(value: String) = settings.setRotatorPort(value)
// fun getBTEnabled(): Boolean = settings.getBTEnabled()
// fun setBTEnabled(value: Boolean) = settings.setBTEnabled(value)
// fun getBTFormat(): String = settings.getBTFormat()
// fun setBTFormat(value: String) = settings.setBTFormat(value)
// fun getBTDeviceName(): String = settings.getBTDeviceName()
// fun setBTDeviceName(value: String) = settings.setBTDeviceName(value)
fun getBTDeviceAddr(): String = settings.getBTDeviceAddr()
fun setBTDeviceAddr(value: String) = settings.setBTDeviceAddr(value)
fun getDataUpdateState() = repository.updateState
fun setUpdateHandled() = repository.setUpdateStateHandled()
val stationPosition: SharedFlow<DataState<GeoPos>> = locationManager.stationPosition
fun getStationPosition(): GeoPos = locationManager.getStationPosition()
fun getStationLocator(): String = settings.loadStationLocator()
fun setStationPosition(lat: Double, lon: Double) = locationManager.setStationPosition(lat, lon)
fun setPositionFromGps() = locationManager.setPositionFromGps()
fun setPositionFromNet() = locationManager.setPositionFromNet()
fun setPositionFromQth(qthString: String) = locationManager.setPositionFromQth(qthString)
fun setPositionHandled() = locationManager.setPositionHandled()
// fun getBTDeviceAddr(): String = settings.getBTDeviceAddr()
// fun setBTDeviceAddr(value: String) = settings.setBTDeviceAddr(value)
}

Wyświetl plik

@ -1,8 +0,0 @@
package com.rtbishop.look4sat.domain.model
data class OtherSettings(
val isUtcEnabled: Boolean,
val isUpdateEnabled: Boolean,
val isSweepEnabled: Boolean,
val isSensorEnabled: Boolean
)