From 92eec290b187c2e1019c3074452003597a60b494 Mon Sep 17 00:00:00 2001 From: Arty Bishop Date: Tue, 15 Feb 2022 11:32:03 +0000 Subject: [PATCH] Moved satellite selections storage to SharedPreferences --- .../look4sat/framework/SettingsHandler.kt | 11 +++++ .../look4sat/framework/local/EntriesDao.kt | 41 +++++------------- .../look4sat/framework/local/LocalSource.kt | 30 ++++++------- .../look4sat/framework/model/SatItem.kt | 2 +- .../entriesScreen/EntriesViewModel.kt | 8 ++-- .../settingsScreen/SettingsViewModel.kt | 10 ++--- .../rtbishop/look4sat/data/DataRepository.kt | 42 +++++++++++-------- .../rtbishop/look4sat/data/ILocalSource.kt | 13 +++--- .../look4sat/data/ISettingsHandler.kt | 4 ++ .../look4sat/domain/IDataRepository.kt | 23 +++++----- 10 files changed, 88 insertions(+), 96 deletions(-) diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/SettingsHandler.kt b/app/src/main/java/com/rtbishop/look4sat/framework/SettingsHandler.kt index f5b20e22..473966db 100644 --- a/app/src/main/java/com/rtbishop/look4sat/framework/SettingsHandler.kt +++ b/app/src/main/java/com/rtbishop/look4sat/framework/SettingsHandler.kt @@ -44,6 +44,7 @@ class SettingsHandler @Inject constructor(private val prefs: SharedPreferences) const val keyLongitude = "stationLon" // const val keyPositionGPS = "setPositionGPS" // const val keyPositionQTH = "setPositionQTH" + const val keySelection = "selection" } override fun loadStationPosition(): GeoPos { @@ -60,6 +61,16 @@ class SettingsHandler @Inject constructor(private val prefs: SharedPreferences) } } + override fun saveSatelliteSelection(catnums: List) { + val stringList = catnums.map { catnum -> catnum.toString() } + prefs.edit { putStringSet(keySelection, stringList.toSet()) } + } + + override fun loadSatelliteSelection(): List { + val catnums = prefs.getStringSet(keySelection, emptySet())?.map { catnum -> catnum.toInt() } + return catnums?.sorted() ?: emptyList() + } + override fun getHoursAhead(): Int { return prefs.getInt(keyHoursAhead, 8) } diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/local/EntriesDao.kt b/app/src/main/java/com/rtbishop/look4sat/framework/local/EntriesDao.kt index edbd4e84..d5cc9e62 100644 --- a/app/src/main/java/com/rtbishop/look4sat/framework/local/EntriesDao.kt +++ b/app/src/main/java/com/rtbishop/look4sat/framework/local/EntriesDao.kt @@ -20,48 +20,29 @@ package com.rtbishop.look4sat.framework.local import androidx.room.* import com.rtbishop.look4sat.framework.model.SatEntry import com.rtbishop.look4sat.framework.model.SatItem -import kotlinx.coroutines.flow.Flow @Dao interface EntriesDao { @Transaction @Query("SELECT catnum, name, isSelected FROM entries ORDER BY name ASC") - fun getSatelliteItems(): Flow> + suspend fun getAllSatellites(): List - @Query("SELECT catnum FROM entries WHERE isSelected = 1") - suspend fun getEntriesSelection(): List + @Transaction + suspend fun getSelectedSatellites(catnums: List): List { + val selectedSatellites = mutableListOf() + catnums.chunked(999).forEach { chunkedList -> + selectedSatellites.addAll(getSelectedSatellitesChunked(chunkedList)) + } + return selectedSatellites + } - @Query("SELECT * FROM entries WHERE isSelected = 1") - suspend fun getSelectedSatellites(): List + @Query("SELECT * FROM entries WHERE catnum IN (:catnums)") + suspend fun getSelectedSatellitesChunked(catnums: List): List @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertEntries(entries: List) - @Transaction - suspend fun updateEntries(entries: List) { - val entriesSelection = getEntriesSelection() - insertEntries(entries) - restoreEntriesSelection(entriesSelection) - } - - @Transaction - suspend fun restoreEntriesSelection(catnums: List) { - updateEntriesSelection(catnums) - } - - @Transaction - suspend fun updateEntriesSelection(catnums: List) { - clearEntriesSelection() - catnums.forEach { catnum -> updateEntrySelection(catnum) } - } - - @Query("UPDATE entries SET isSelected = 1 WHERE catnum = :catnum") - suspend fun updateEntrySelection(catnum: Int) - - @Query("UPDATE entries SET isSelected = 0") - suspend fun clearEntriesSelection() - @Query("DELETE FROM entries") suspend fun deleteEntries() } diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/local/LocalSource.kt b/app/src/main/java/com/rtbishop/look4sat/framework/local/LocalSource.kt index fd4415a8..404fddae 100644 --- a/app/src/main/java/com/rtbishop/look4sat/framework/local/LocalSource.kt +++ b/app/src/main/java/com/rtbishop/look4sat/framework/local/LocalSource.kt @@ -29,8 +29,6 @@ import com.rtbishop.look4sat.framework.toDomainItems import com.rtbishop.look4sat.framework.toFramework import com.rtbishop.look4sat.framework.toFrameworkEntries import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map import kotlinx.coroutines.withContext import java.io.InputStream @@ -41,8 +39,16 @@ class LocalSource( private val transmittersDao: TransmittersDao, ) : ILocalSource { - override fun getSatelliteItems(): Flow> { - return entriesDao.getSatelliteItems().map { items -> items.toDomainItems() } + override suspend fun getAllSatellites(): List { + return entriesDao.getAllSatellites().toDomainItems() + } + + override suspend fun getSelectedSatellites(catnums: List): List { + return entriesDao.getSelectedSatellites(catnums).map { entry -> entry.tle.createSat() } + } + + override suspend fun getTransmitters(catnum: Int): List { + return transmittersDao.getTransmitters(catnum).toDomain() } @Suppress("BlockingMethodInNonBlockingContext") @@ -50,27 +56,15 @@ class LocalSource( return withContext(ioDispatcher) { resolver.openInputStream(Uri.parse(uri)) } } - override suspend fun getSelectedSatellites(): List { - return entriesDao.getSelectedSatellites().map { entry -> entry.tle.createSat() } - } - - override suspend fun getTransmitters(catnum: Int): List { - return transmittersDao.getTransmitters(catnum).toDomain() - } - override suspend fun updateEntries(entries: List) { - entriesDao.updateEntries(entries.toFrameworkEntries()) - } - - override suspend fun updateEntriesSelection(catnums: List) { - entriesDao.updateEntriesSelection(catnums) + entriesDao.insertEntries(entries.toFrameworkEntries()) } override suspend fun updateTransmitters(transmitters: List) { transmittersDao.updateTransmitters(transmitters.toFramework()) } - override suspend fun clearData() { + override suspend fun clearAllData() { entriesDao.deleteEntries() transmittersDao.deleteTransmitters() } diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/model/SatItem.kt b/app/src/main/java/com/rtbishop/look4sat/framework/model/SatItem.kt index cc183f14..c18289fc 100644 --- a/app/src/main/java/com/rtbishop/look4sat/framework/model/SatItem.kt +++ b/app/src/main/java/com/rtbishop/look4sat/framework/model/SatItem.kt @@ -22,7 +22,7 @@ import androidx.room.Relation data class SatItem( val catnum: Int, val name: String, - var isSelected: Boolean, + var isSelected: Boolean = false, @Relation( parentColumn = "catnum", entity = Transmitter::class, diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt index 4b73e452..b9ec76cd 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt @@ -34,9 +34,7 @@ class EntriesViewModel @Inject constructor( private val transModes = MutableLiveData(preferences.loadModesSelection()) private val currentQuery = MutableLiveData(String()) - private val itemsFromRepo = liveData { - repository.getSatelliteItems().collect { itemsAll -> emit(itemsAll) } - } as MutableLiveData + private val itemsFromRepo = liveData { emit(repository.getAllSatellites()) } as MutableLiveData private val itemsWithModes = transModes.switchMap { modes -> itemsFromRepo.map { items -> filterByModes(items, modes) } } @@ -69,8 +67,8 @@ class EntriesViewModel @Inject constructor( fun saveSelection() { itemsFromRepo.value?.let { itemsAll -> - val selectedIds = itemsAll.filter { it.isSelected }.map { it.catnum } - repository.updateSelection(selectedIds) + val filteredItems = itemsAll.filter { item -> item.isSelected } + repository.updatesSelection(filteredItems.map { item -> item.catnum }) } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SettingsViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SettingsViewModel.kt index 7304a05c..5bf0a81b 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SettingsViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SettingsViewModel.kt @@ -18,15 +18,15 @@ class SettingsViewModel @Inject constructor( ) : ViewModel() { fun updateDataFromFile(uri: String) { - repository.updateDataFromFile(uri) + repository.updateFromFile(uri) } fun updateDataFromWeb(sources: List) { - repository.updateDataFromWeb(sources) + repository.updateFromWeb(sources) } fun clearData() { - repository.clearData() + repository.clearAllData() } fun getUseUTC(): Boolean = settings.getUseUTC() @@ -53,9 +53,9 @@ class SettingsViewModel @Inject constructor( fun setRotatorPort(value: String) = settings.setRotatorPort(value) - fun getUpdateState() = repository.dataUpdateState + fun getUpdateState() = repository.updateState - fun setUpdateHandled() = repository.setDataUpdateHandled() + fun setUpdateHandled() = repository.setUpdateStateHandled() val stationPosition: SharedFlow> = locationHandler.stationPosition diff --git a/core/src/main/java/com/rtbishop/look4sat/data/DataRepository.kt b/core/src/main/java/com/rtbishop/look4sat/data/DataRepository.kt index 2439a932..0d4c3342 100644 --- a/core/src/main/java/com/rtbishop/look4sat/data/DataRepository.kt +++ b/core/src/main/java/com/rtbishop/look4sat/data/DataRepository.kt @@ -22,8 +22,8 @@ import com.rtbishop.look4sat.domain.IDataRepository import com.rtbishop.look4sat.domain.model.DataState import com.rtbishop.look4sat.domain.model.SatEntry import com.rtbishop.look4sat.domain.model.SatItem +import com.rtbishop.look4sat.domain.predict.Satellite import kotlinx.coroutines.* -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import java.io.InputStream @@ -43,13 +43,23 @@ class DataRepository( _updateState.value = DataState.Error(exception.message) } private val _updateState = MutableStateFlow>(DataState.Handled) - override val dataUpdateState: StateFlow> = _updateState + override val updateState: StateFlow> = _updateState - override fun setDataUpdateHandled() { - _updateState.value = DataState.Handled + override suspend fun getAllSatellites(): List { + val selection = settings.loadSatelliteSelection() + val satellites = localSource.getAllSatellites() + satellites.forEach { satItem -> satItem.isSelected = satItem.catnum in selection } + return satellites } - override fun updateDataFromFile(uri: String) { + override suspend fun getSelectedSatellites(): List { + val selection = settings.loadSatelliteSelection() + return localSource.getSelectedSatellites(selection) + } + + override suspend fun getTransmitters(catnum: Int) = localSource.getTransmitters(catnum) + + override fun updateFromFile(uri: String) { repositoryScope.launch(exceptionHandler) { _updateState.value = DataState.Loading val updateTimeMillis = measureTimeMillis { @@ -61,7 +71,7 @@ class DataRepository( } } - override fun updateDataFromWeb(sources: List) { + override fun updateFromWeb(sources: List) { _updateState.value = DataState.Loading repositoryScope.launch(exceptionHandler) { settings.saveDataSources(sources) @@ -102,23 +112,21 @@ class DataRepository( } } - override fun clearData() { + override fun updatesSelection(catnums: List) { repositoryScope.launch { - _updateState.value = DataState.Loading - localSource.clearData() - _updateState.value = DataState.Success(0L) + settings.saveSatelliteSelection(catnums) } } - override fun getSatelliteItems(): Flow> = localSource.getSatelliteItems() + override fun setUpdateStateHandled() { + _updateState.value = DataState.Handled + } - override suspend fun getSelectedSatellites() = localSource.getSelectedSatellites() - - override suspend fun getTransmitters(catnum: Int) = localSource.getTransmitters(catnum) - - override fun updateSelection(catnums: List) { + override fun clearAllData() { repositoryScope.launch { - localSource.updateEntriesSelection(catnums) + _updateState.value = DataState.Loading + localSource.clearAllData() + _updateState.value = DataState.Success(0L) } } diff --git a/core/src/main/java/com/rtbishop/look4sat/data/ILocalSource.kt b/core/src/main/java/com/rtbishop/look4sat/data/ILocalSource.kt index 5e8ebb45..b30cd2a3 100644 --- a/core/src/main/java/com/rtbishop/look4sat/data/ILocalSource.kt +++ b/core/src/main/java/com/rtbishop/look4sat/data/ILocalSource.kt @@ -21,24 +21,21 @@ import com.rtbishop.look4sat.domain.model.SatEntry import com.rtbishop.look4sat.domain.model.SatItem import com.rtbishop.look4sat.domain.model.Transmitter import com.rtbishop.look4sat.domain.predict.Satellite -import kotlinx.coroutines.flow.Flow import java.io.InputStream interface ILocalSource { - fun getSatelliteItems(): Flow> + suspend fun getAllSatellites(): List - suspend fun getFileStream(uri: String): InputStream? - - suspend fun getSelectedSatellites(): List + suspend fun getSelectedSatellites(catnums: List): List suspend fun getTransmitters(catnum: Int): List - suspend fun updateEntries(entries: List) + suspend fun getFileStream(uri: String): InputStream? - suspend fun updateEntriesSelection(catnums: List) + suspend fun updateEntries(entries: List) suspend fun updateTransmitters(transmitters: List) - suspend fun clearData() + suspend fun clearAllData() } diff --git a/core/src/main/java/com/rtbishop/look4sat/data/ISettingsHandler.kt b/core/src/main/java/com/rtbishop/look4sat/data/ISettingsHandler.kt index 5d5c3590..5b403449 100644 --- a/core/src/main/java/com/rtbishop/look4sat/data/ISettingsHandler.kt +++ b/core/src/main/java/com/rtbishop/look4sat/data/ISettingsHandler.kt @@ -59,6 +59,10 @@ interface ISettingsHandler { fun loadModesSelection(): List + fun saveSatelliteSelection(catnums: List) + + fun loadSatelliteSelection(): List + fun getRotatorEnabled(): Boolean fun setRotatorEnabled(value: Boolean) diff --git a/core/src/main/java/com/rtbishop/look4sat/domain/IDataRepository.kt b/core/src/main/java/com/rtbishop/look4sat/domain/IDataRepository.kt index 280bb3f8..5bfbd963 100644 --- a/core/src/main/java/com/rtbishop/look4sat/domain/IDataRepository.kt +++ b/core/src/main/java/com/rtbishop/look4sat/domain/IDataRepository.kt @@ -21,26 +21,25 @@ import com.rtbishop.look4sat.domain.model.DataState import com.rtbishop.look4sat.domain.model.SatItem import com.rtbishop.look4sat.domain.model.Transmitter import com.rtbishop.look4sat.domain.predict.Satellite -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow interface IDataRepository { - val dataUpdateState: StateFlow> + val updateState: StateFlow> - fun setDataUpdateHandled() - - fun updateDataFromFile(uri: String) - - fun updateDataFromWeb(sources: List) - - fun clearData() - - fun getSatelliteItems(): Flow> + suspend fun getAllSatellites(): List suspend fun getSelectedSatellites(): List suspend fun getTransmitters(catnum: Int): List - fun updateSelection(catnums: List) + fun updateFromFile(uri: String) + + fun updateFromWeb(sources: List) + + fun updatesSelection(catnums: List) + + fun setUpdateStateHandled() + + fun clearAllData() }