Minor fixes for entries, settings and maps

This commit is contained in:
Arty Bishop committed 2025-12-27 15:01:33 +00:00
1 parent 942c7ce65f
commit 5d2a870319
10 files changed
+140 -125

No files matched your search

@@ -26,6 +26,7 @@ import com.rtbishop.look4sat.framework.data.remote.NetworkSource
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import org.osmdroid.config.Configuration
class MainContainer(private val context: Context) { class MainContainer(private val context: Context) {
@@ -70,6 +71,7 @@ class MainContainer(private val context: Context) {
private fun provideSettingsRepository(): ISettingsRepository { private fun provideSettingsRepository(): ISettingsRepository {
val manager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager val manager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
val preferences = context.getSharedPreferences("default", Context.MODE_PRIVATE) val preferences = context.getSharedPreferences("default", Context.MODE_PRIVATE)
Configuration.getInstance().load(context, preferences)
return SettingsRepository(manager, preferences) return SettingsRepository(manager, preferences)
} }
} }
@@ -124,15 +124,17 @@ class SettingsRepository(
//endregion //endregion
override fun saveEntriesSelection(catnums: List<Int>) { private val _satelliteSelection = MutableStateFlow(loadEntriesSelection())
val stringList = catnums.map { catnum -> catnum.toString() } override val satelliteSelection: StateFlow<List<Int>> = _satelliteSelection
preferences.edit { putStringSet(keySelection, stringList.toSet()) }
override fun saveEntriesSelection(catnums: List<Int>) = preferences.edit {
putStringSet(keySelection, catnums.map { catnum -> catnum.toString() }.toSet())
_satelliteSelection.value = catnums
} }
override fun loadEntriesSelection(): List<Int> { private fun loadEntriesSelection(): List<Int> {
val catnums = val catNums = preferences.getStringSet(keySelection, emptySet())
preferences.getStringSet(keySelection, emptySet())?.map { catnum -> catnum.toInt() } return catNums?.map { catnum -> catnum.toInt() }?.sorted() ?: emptyList()
return catnums?.sorted() ?: emptyList()
} }
override fun saveSatType(type: String, catnums: List<Int>) { override fun saveSatType(type: String, catnums: List<Int>) {
@@ -10,12 +10,19 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material3.* import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ElevatedButton
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.composed import androidx.compose.ui.composed
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@@ -31,6 +38,16 @@ fun CardButton(onClick: () -> Unit, text: String, modifier: Modifier = Modifier)
) { Text(text = text, fontSize = 17.sp) } ) { Text(text = text, fontSize = 17.sp) }
} }
@Composable
fun CardIcon(onClick: () -> Unit, iconId: Int, description: String? = null) {
val clickableModifier = Modifier.clickable { onClick() }
ElevatedCard(modifier = Modifier.size(48.dp)) {
Box(modifier = clickableModifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Icon(painter = painterResource(id = iconId), contentDescription = description)
}
}
}
@Composable @Composable
fun CardLoadingIndicator() { fun CardLoadingIndicator() {
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) { Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) {
@@ -6,6 +6,7 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
@@ -13,8 +14,10 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
@@ -25,6 +28,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.rtbishop.look4sat.R import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.model.DataState import com.rtbishop.look4sat.model.DataState
import com.rtbishop.look4sat.model.SatItem import com.rtbishop.look4sat.model.SatItem
import com.rtbishop.look4sat.presentation.CardIcon
import com.rtbishop.look4sat.presentation.CardLoadingIndicator import com.rtbishop.look4sat.presentation.CardLoadingIndicator
import com.rtbishop.look4sat.presentation.MainTheme import com.rtbishop.look4sat.presentation.MainTheme
import com.rtbishop.look4sat.presentation.dialogs.TypesDialog import com.rtbishop.look4sat.presentation.dialogs.TypesDialog
@@ -50,12 +54,7 @@ fun EntriesScreen(navToPasses: () -> Unit) {
viewModel.saveSelection() viewModel.saveSelection()
navToPasses() navToPasses()
}) })
Row(horizontalArrangement = Arrangement.spacedBy(6.dp), modifier = Modifier.height(48.dp)) { MiddleBar(viewModel.getSatType(), { toggleDialog() }, { unselectAll() }, { selectAll() })
EntryTypeCard(
type = viewModel.getSatType(), { toggleDialog() }, modifier = Modifier.weight(1f)
)
SelectionCard(unselectAll = { unselectAll() }, selectAll = { selectAll() })
}
EntriesCard(state = state.value) { list, value -> viewModel.updateSelection(list, value) } EntriesCard(state = state.value) { list, value -> viewModel.updateSelection(list, value) }
} }
} }
@@ -64,83 +63,81 @@ fun EntriesScreen(navToPasses: () -> Unit) {
@Composable @Composable
private fun TopBarPreview() = MainTheme { TopBar({}, {}) } private fun TopBarPreview() = MainTheme { TopBar({}, {}) }
@Preview(showBackground = true)
@Composable
private fun MiddleBarPreview() = MainTheme { MiddleBar({}, {}) }
@Preview(showBackground = true)
@Composable
private fun EntryPreview() {
val satItem = SatItem(45555, "SatName", emptyList(), true)
MainTheme { Entry(item = satItem, onSelected = { _, _ -> run {} }, modifier = Modifier) }
}
@Preview(showBackground = true)
@Composable
private fun EntriesPreview() {
MainTheme { EntriesCard(DataState.Loading) { _, _ -> run {} } }
}
@Composable @Composable
private fun TopBar(setQuery: (String) -> Unit, saveSelection: () -> Unit) { private fun TopBar(setQuery: (String) -> Unit, saveSelection: () -> Unit) {
Row(horizontalArrangement = Arrangement.spacedBy(6.dp), modifier = Modifier.height(56.dp)) { Row(horizontalArrangement = Arrangement.spacedBy(6.dp), modifier = Modifier.height(48.dp)) {
SearchBar(setQuery = { setQuery(it) }, modifier = Modifier.weight(1f)) SearchBar(setQuery = { setQuery(it) }, modifier = Modifier.weight(1f))
SaveButton(saveSelection = { saveSelection() }, modifier = Modifier.height(56.dp)) SaveButton(saveSelection = { saveSelection() }, modifier = Modifier.height(48.dp))
} }
} }
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun SearchBar(setQuery: (String) -> Unit, modifier: Modifier = Modifier) { private fun SearchBar(setQuery: (String) -> Unit, modifier: Modifier = Modifier) {
val currentQuery = rememberSaveable { mutableStateOf("") } val currentQuery = rememberSaveable { mutableStateOf("") }
OutlinedTextField( val setNewQuery = { newValue: String ->
value = currentQuery.value,
onValueChange = { newValue ->
currentQuery.value = newValue currentQuery.value = newValue
setQuery(newValue) setQuery(newValue)
}, }
maxLines = 1, ElevatedCard(modifier = modifier.height(48.dp)) {
// label = { Text(text = stringResource(id = R.string.entries_search_hint)) }, Row(
placeholder = { Text(text = stringResource(id = R.string.entries_search_hint)) }, horizontalArrangement = Arrangement.Start,
leadingIcon = { verticalAlignment = Alignment.CenterVertically,
Icon( modifier = Modifier.padding(start = 12.dp)
painter = painterResource(id = R.drawable.ic_search), ) {
contentDescription = null Icon(painter = painterResource(id = R.drawable.ic_search), contentDescription = null)
) BasicTextField(
}, value = currentQuery.value,
trailingIcon = { onValueChange = { setNewQuery(it) },
Icon(painter = painterResource(id = R.drawable.ic_close), singleLine = true,
contentDescription = null, modifier = modifier.padding(start = 12.dp),
modifier = Modifier.onClick { textStyle = TextStyle(
currentQuery.value = "" fontSize = 16.sp,
setQuery("") fontWeight = FontWeight.Medium,
}) color = MaterialTheme.colorScheme.onSurface
},
shape = MaterialTheme.shapes.medium,
colors = TextFieldDefaults.outlinedTextFieldColors(
containerColor = MaterialTheme.colorScheme.surface,
focusedBorderColor = MaterialTheme.colorScheme.onSurfaceVariant,
unfocusedBorderColor = MaterialTheme.colorScheme.onSurfaceVariant
), ),
modifier = modifier decorationBox = { innerTextField ->
if (currentQuery.value.isEmpty()) {
Text(
text = stringResource(id = R.string.entries_search_hint),
fontSize = 16.sp,
fontWeight = FontWeight.Normal,
color = MaterialTheme.colorScheme.onSurfaceVariant
) )
}
innerTextField()
},
cursorBrush = SolidColor(MaterialTheme.colorScheme.onSurface)
)
IconButton(onClick = { setNewQuery("") }) {
Icon(painter = painterResource(id = R.drawable.ic_close), contentDescription = null)
}
}
}
} }
@Composable @Composable
private fun SaveButton(saveSelection: () -> Unit, modifier: Modifier = Modifier) { private fun SaveButton(saveSelection: () -> Unit, modifier: Modifier = Modifier) {
ElevatedButton( val clickableModifier = modifier.clickable { saveSelection() }
onClick = { saveSelection() }, colors = ButtonDefaults.buttonColors( ElevatedCard(
containerColor = MaterialTheme.colorScheme.primary, modifier = Modifier.width(102.dp),
contentColor = MaterialTheme.colorScheme.onPrimary colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.primary)
), shape = MaterialTheme.shapes.medium, modifier = modifier.width(96.dp) ) {
) { Icon(painter = painterResource(id = R.drawable.ic_checkmark), contentDescription = null) } Box(modifier = clickableModifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Icon(painter = painterResource(id = R.drawable.ic_checkmark), contentDescription = null)
}
}
} }
@Preview(showBackground = true)
@Composable @Composable
private fun MiddleBar(unselectAll: () -> Unit, selectAll: () -> Unit) { private fun MiddleBarPreview() = MainTheme { MiddleBar("Amateur", {}, {}, {}) }
@Composable
private fun MiddleBar(type: String, navigate: () -> Unit, uncheck: () -> Unit, check: () -> Unit) {
Row(horizontalArrangement = Arrangement.spacedBy(6.dp), modifier = Modifier.height(48.dp)) { Row(horizontalArrangement = Arrangement.spacedBy(6.dp), modifier = Modifier.height(48.dp)) {
EntryTypeCard(type = "Amateur", {}, modifier = Modifier.weight(1f)) EntryTypeCard(type = type, { navigate() }, modifier = Modifier.weight(1f))
SelectionCard(unselectAll = { unselectAll() }, selectAll = { selectAll() }) CardIcon(onClick = { uncheck() }, iconId = R.drawable.ic_checkbox_off)
CardIcon(onClick = { check() }, iconId = R.drawable.ic_checkbox_on)
} }
} }
@@ -163,27 +160,17 @@ private fun EntryTypeCard(type: String, onClick: () -> Unit, modifier: Modifier
text = "Type: $type", text = "Type: $type",
fontSize = 16.sp, fontSize = 16.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
modifier = modifier.padding(start = 16.dp, end = 6.dp, bottom = 2.dp) modifier = modifier.padding(start = 12.dp, end = 6.dp, bottom = 2.dp)
) )
} }
} }
} }
@Preview(showBackground = true)
@Composable @Composable
private fun SelectionCard(unselectAll: () -> Unit, selectAll: () -> Unit) { private fun EntryPreview() {
ElevatedCard { val satItem = SatItem(45555, "SatName", emptyList(), true)
Row(modifier = Modifier.width(96.dp)) { MainTheme { Entry(item = satItem, onSelected = { _, _ -> run {} }, modifier = Modifier) }
val unselectIcon = painterResource(id = R.drawable.ic_checkbox_off)
val selectIcon = painterResource(id = R.drawable.ic_checkbox_on)
val iconColor = MaterialTheme.colorScheme.onSurface
IconButton(onClick = { unselectAll() }) {
Icon(painter = unselectIcon, contentDescription = null, tint = iconColor)
}
IconButton(onClick = { selectAll() }) {
Icon(painter = selectIcon, contentDescription = null, tint = iconColor)
}
}
}
} }
@Composable @Composable
@@ -216,6 +203,12 @@ private fun Entry(item: SatItem, onSelected: (List<Int>, Boolean) -> Unit, modif
} }
} }
@Preview(showBackground = true)
@Composable
private fun EntriesPreview() {
MainTheme { EntriesCard(DataState.Loading) { _, _ -> run {} } }
}
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun EntriesCard(state: DataState<List<SatItem>>, onSelected: (List<Int>, Boolean) -> Unit) { fun EntriesCard(state: DataState<List<SatItem>>, onSelected: (List<Int>, Boolean) -> Unit) {
@@ -24,21 +24,23 @@ import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory import androidx.lifecycle.viewmodel.viewModelFactory
import com.rtbishop.look4sat.MainApplication import com.rtbishop.look4sat.MainApplication
import com.rtbishop.look4sat.domain.IDataRepository import com.rtbishop.look4sat.domain.IDataRepository
import com.rtbishop.look4sat.domain.ISatelliteRepository
import com.rtbishop.look4sat.domain.ISettingsRepository import com.rtbishop.look4sat.domain.ISettingsRepository
import com.rtbishop.look4sat.model.DataState import com.rtbishop.look4sat.model.DataState
import com.rtbishop.look4sat.model.SatItem import com.rtbishop.look4sat.model.SatItem
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.* import java.util.*
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
class EntriesViewModel( class EntriesViewModel(
private val dataRepository: IDataRepository, private val dataRepository: IDataRepository,
private val satelliteRepository: ISatelliteRepository, private val settingsRepository: ISettingsRepository,
private val settingsRepository: ISettingsRepository private val dispatcher: CoroutineDispatcher = Dispatchers.Default
) : ViewModel() { ) : ViewModel() {
private val satType = MutableStateFlow("All") private val satType = MutableStateFlow("All")
@@ -67,7 +69,7 @@ class EntriesViewModel(
} }
fun selectCurrentItems(selectAll: Boolean) = viewModelScope.launch { fun selectCurrentItems(selectAll: Boolean) = viewModelScope.launch {
updateSelection(itemsWithQuery.first().map { item -> item.catnum }, selectAll) updateEntriesSelection(itemsWithQuery.first().map { item -> item.catnum }, selectAll)
} }
fun setQuery(query: String) { fun setQuery(query: String) {
@@ -77,16 +79,14 @@ class EntriesViewModel(
fun saveSelection() = viewModelScope.launch { fun saveSelection() = viewModelScope.launch {
val newSelection = itemsFromRepo.value.filter { it.isSelected }.map { it.catnum } val newSelection = itemsFromRepo.value.filter { it.isSelected }.map { it.catnum }
settingsRepository.saveEntriesSelection(newSelection) settingsRepository.saveEntriesSelection(newSelection)
val selectedIds = settingsRepository.loadEntriesSelection()
val satellites = dataRepository.getEntriesWithIds(selectedIds)
val stationPos = settingsRepository.stationPosition.value
val timeRef = System.currentTimeMillis()
val hoursAhead = settingsRepository.getHoursAhead()
val minElev = settingsRepository.getMinElevation()
satelliteRepository.calculatePasses(satellites, stationPos, timeRef, hoursAhead, minElev)
} }
fun updateSelection(catNums: List<Int>, isSelected: Boolean) { fun updateSelection(catNums: List<Int>, isSelected: Boolean) = viewModelScope.launch {
updateEntriesSelection(catNums, isSelected)
}
private suspend fun updateEntriesSelection(catNums: List<Int>, isSelected: Boolean) {
withContext(dispatcher) {
itemsFromRepo.value.let { itemsAll -> itemsFromRepo.value.let { itemsAll ->
val copiedList = itemsAll.map { item -> item.copy() } val copiedList = itemsAll.map { item -> item.copy() }
catNums.forEach { catnum -> catNums.forEach { catnum ->
@@ -95,22 +95,24 @@ class EntriesViewModel(
itemsFromRepo.value = copiedList itemsFromRepo.value = copiedList
} }
} }
private fun filterByType(items: List<SatItem>, type: String): List<SatItem> {
if (type == "All") return items
val catnums = settingsRepository.loadSatType(type)
if (catnums.isEmpty()) return items
return items.filter { item -> item.catnum in catnums }
} }
private fun filterByQuery(items: List<SatItem>, query: String): List<SatItem> { private suspend fun filterByType(items: List<SatItem>, type: String): List<SatItem> {
if (query.isBlank()) return items return withContext(dispatcher) {
return try { if (type == "All") return@withContext items
val catnums = settingsRepository.loadSatType(type)
if (catnums.isEmpty()) return@withContext items
return@withContext items.filter { item -> item.catnum in catnums }
}
}
private suspend fun filterByQuery(items: List<SatItem>, query: String): List<SatItem> {
return withContext(dispatcher) {
if (query.isBlank()) return@withContext items
return@withContext try {
items.filter { it.catnum == query.toInt() } items.filter { it.catnum == query.toInt() }
} catch (e: Exception) { } catch (e: Exception) {
items.filter { item -> items.filter { item -> item.name.lowercase().contains(query.lowercase()) }
val itemName = item.name.lowercase(Locale.getDefault())
itemName.contains(query.lowercase(Locale.getDefault()))
} }
} }
} }
@@ -122,7 +124,6 @@ class EntriesViewModel(
val container = (this[applicationKey] as MainApplication).container val container = (this[applicationKey] as MainApplication).container
EntriesViewModel( EntriesViewModel(
container.dataRepository, container.dataRepository,
container.satelliteRepository,
container.settingsRepository container.settingsRepository
) )
} }
@@ -1,6 +1,5 @@
package com.rtbishop.look4sat.presentation.map package com.rtbishop.look4sat.presentation.map
import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
@@ -32,7 +31,6 @@ import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.domain.Satellite import com.rtbishop.look4sat.domain.Satellite
import com.rtbishop.look4sat.model.GeoPos import com.rtbishop.look4sat.model.GeoPos
import com.rtbishop.look4sat.model.SatPos import com.rtbishop.look4sat.model.SatPos
import org.osmdroid.config.Configuration
import org.osmdroid.tileprovider.tilesource.XYTileSource import org.osmdroid.tileprovider.tilesource.XYTileSource
import org.osmdroid.util.GeoPoint import org.osmdroid.util.GeoPoint
import org.osmdroid.views.CustomZoomButtonsController import org.osmdroid.views.CustomZoomButtonsController
@@ -66,9 +64,6 @@ private val labelRect = Rect()
@Composable @Composable
fun MapScreen() { fun MapScreen() {
val viewModel = viewModel(MapViewModel::class.java, factory = MapViewModel.Factory) val viewModel = viewModel(MapViewModel::class.java, factory = MapViewModel.Factory)
val context = LocalContext.current
val preferences = context.getSharedPreferences("default", Context.MODE_PRIVATE)
Configuration.getInstance().load(context, preferences)
viewModel.selectDefaultSatellite(-1) viewModel.selectDefaultSatellite(-1)
val stationPos = viewModel.stationPos.collectAsState(initial = null) val stationPos = viewModel.stationPos.collectAsState(initial = null)
val positions = viewModel.positions.collectAsState(initial = null) val positions = viewModel.positions.collectAsState(initial = null)
@@ -92,7 +92,7 @@ class MapViewModel(
fun selectDefaultSatellite(catnum: Int) { fun selectDefaultSatellite(catnum: Int) {
viewModelScope.launch { viewModelScope.launch {
val selectedIds = settingsRepository.loadEntriesSelection() val selectedIds = settingsRepository.satelliteSelection.value
dataRepository.getEntriesWithIds(selectedIds).also { satellites -> dataRepository.getEntriesWithIds(selectedIds).also { satellites ->
if (satellites.isNotEmpty()) { if (satellites.isNotEmpty()) {
allSatellites = satellites allSatellites = satellites
@@ -87,12 +87,14 @@ class PassesViewModel(
} }
} }
} }
viewModelScope.launch {
settingsRepository.satelliteSelection.collect { calculatePasses() }
}
viewModelScope.launch { viewModelScope.launch {
dataRepository.updateState.collect { updateState -> dataRepository.updateState.collect { updateState ->
if (updateState is DataState.Success) calculatePasses() if (updateState is DataState.Success) calculatePasses()
} }
} }
calculatePasses()
} }
fun shouldUseUTC() = settingsRepository.isUtcEnabled() fun shouldUseUTC() = settingsRepository.isUtcEnabled()
@@ -100,18 +102,17 @@ class PassesViewModel(
fun calculatePasses( fun calculatePasses(
hoursAhead: Int = 1, hoursAhead: Int = 1,
minElevation: Double = settingsRepository.getMinElevation(), minElevation: Double = settingsRepository.getMinElevation(),
timeRef: Long = System.currentTimeMillis(), timeRef: Long = System.currentTimeMillis()
selection: List<Int>? = null
) { ) {
viewModelScope.launch { viewModelScope.launch {
_passes.emit(DataState.Loading) _passes.emit(DataState.Loading)
// _timerText.postValue(timerDefaultText) // _timerText.postValue(timerDefaultText)
passesProcessing?.cancelAndJoin() passesProcessing?.cancelAndJoin()
selection?.let { items -> settingsRepository.saveEntriesSelection(items) } // selection?.let { items -> settingsRepository.saveEntriesSelection(items) }
settingsRepository.setHoursAhead(hoursAhead) settingsRepository.setHoursAhead(hoursAhead)
settingsRepository.setMinElevation(minElevation) settingsRepository.setMinElevation(minElevation)
val stationPos = settingsRepository.stationPosition.value val stationPos = settingsRepository.stationPosition.value
val selectedIds = settingsRepository.loadEntriesSelection() val selectedIds = settingsRepository.satelliteSelection.value
val satellites = dataRepository.getEntriesWithIds(selectedIds) val satellites = dataRepository.getEntriesWithIds(selectedIds)
satelliteRepository.calculatePasses( satelliteRepository.calculatePasses(
satellites, stationPos, timeRef, hoursAhead, minElevation satellites, stationPos, timeRef, hoursAhead, minElevation
@@ -22,9 +22,13 @@ import com.rtbishop.look4sat.domain.ISettingsRepository
import com.rtbishop.look4sat.model.DataState import com.rtbishop.look4sat.model.DataState
import com.rtbishop.look4sat.model.SatEntry import com.rtbishop.look4sat.model.SatEntry
import com.rtbishop.look4sat.model.SatItem import com.rtbishop.look4sat.model.SatItem
import kotlinx.coroutines.* import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import java.io.InputStream import java.io.InputStream
import java.util.zip.ZipInputStream import java.util.zip.ZipInputStream
@@ -56,7 +60,7 @@ class DataRepository(
override suspend fun getEntriesWithIds(ids: List<Int>) = entrySource.getEntriesWithIds(ids) override suspend fun getEntriesWithIds(ids: List<Int>) = entrySource.getEntriesWithIds(ids)
override suspend fun getEntriesWithSelection(): List<SatItem> { override suspend fun getEntriesWithSelection(): List<SatItem> {
val selectedIds = settingsRepository.loadEntriesSelection() val selectedIds = settingsRepository.satelliteSelection.value
return getEntriesWithModes().onEach { it.isSelected = it.catnum in selectedIds } return getEntriesWithModes().onEach { it.isSelected = it.catnum in selectedIds }
} }
@@ -24,6 +24,8 @@ interface ISettingsRepository {
val stationPosition: StateFlow<GeoPos> val stationPosition: StateFlow<GeoPos>
val satelliteSelection: StateFlow<List<Int>>
fun setGpsPosition(): Boolean fun setGpsPosition(): Boolean
fun setGeoPosition(latitude: Double, longitude: Double, altitude: Double = 0.0): Boolean fun setGeoPosition(latitude: Double, longitude: Double, altitude: Double = 0.0): Boolean
@@ -64,8 +66,6 @@ interface ISettingsRepository {
fun saveEntriesSelection(catnums: List<Int>) fun saveEntriesSelection(catnums: List<Int>)
fun loadEntriesSelection(): List<Int>
fun saveSatType(type: String, catnums: List<Int>) fun saveSatType(type: String, catnums: List<Int>)
fun loadSatType(type: String): List<Int> fun loadSatType(type: String): List<Int>