From 74cbad51277a75b5be94bf449da0449fa886694e Mon Sep 17 00:00:00 2001 From: Arty Bishop Date: Tue, 22 Feb 2022 13:12:03 +0000 Subject: [PATCH] Interfaces and classes refactoring and code cleanup --- .../1.json | 0 app/src/main/AndroidManifest.xml | 2 +- .../rtbishop/look4sat/framework/DataMapper.kt | 47 -------- .../look4sat/framework/LocationHandler.kt | 16 +-- .../look4sat/framework/SettingsHandler.kt | 14 ++- .../SatEntriesDao.kt => data/EntriesDao.kt} | 10 +- .../look4sat/framework/data/Provider.kt | 25 +++++ .../SatRadiosDao.kt => data/RadiosDao.kt} | 16 ++- .../look4sat/framework/data/Storage.kt | 86 +++++++++++++++ .../Look4SatDb.kt => data/StorageDb.kt} | 8 +- .../look4sat/framework/local/LocalSource.kt | 101 ------------------ .../look4sat/framework/remote/RemoteSource.kt | 15 --- .../rtbishop/look4sat/injection/CoreModule.kt | 32 +++--- .../look4sat/presentation/Extensions.kt | 57 ---------- .../look4sat/presentation/MainActivity.kt | 27 ++++- ...k4SatApplication.kt => MainApplication.kt} | 2 +- .../look4sat/presentation/MainViewModel.kt | 30 ------ .../entriesScreen/EntriesFragment.kt | 2 +- .../entriesScreen/EntriesViewModel.kt | 19 ++-- .../presentation/entriesScreen/ModesDialog.kt | 4 +- .../presentation/mapScreen/MapFragment.kt | 36 +++---- .../presentation/mapScreen/MapViewModel.kt | 74 ++++++------- .../presentation/passesScreen/FilterDialog.kt | 4 +- .../passesScreen/PassesFragment.kt | 13 ++- .../passesScreen/PassesViewModel.kt | 16 +-- .../presentation/radarScreen/RadarFragment.kt | 45 ++++---- .../radarScreen/RadarViewModel.kt | 32 +++--- .../settingsScreen/LocationDialog.kt | 4 +- .../settingsScreen/LocatorDialog.kt | 4 +- .../settingsScreen/SettingsFragment.kt | 10 +- .../settingsScreen/SettingsViewModel.kt | 15 +-- .../settingsScreen/SourcesDialog.kt | 6 +- app/src/main/res/layout/fragment_radar.xml | 21 ++-- app/src/main/res/layout/item_mode.xml | 2 +- app/src/main/res/values-ru/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + .../look4sat/{domain => data}/DataParser.kt | 2 +- .../data/{IRemoteSource.kt => IProvider.kt} | 6 +- .../data/{ILocalSource.kt => IStorage.kt} | 21 +--- .../data/{DataRepository.kt => Repository.kt} | 70 ++++++------ .../{IDataRepository.kt => IRepository.kt} | 20 ++-- .../ISettings.kt} | 4 +- .../com/rtbishop/look4sat/DataParserTest.kt | 2 +- 43 files changed, 403 insertions(+), 521 deletions(-) rename app/schemas/{com.rtbishop.look4sat.framework.local.Look4SatDb => com.rtbishop.look4sat.framework.data.StorageDb}/1.json (100%) delete mode 100644 app/src/main/java/com/rtbishop/look4sat/framework/DataMapper.kt rename app/src/main/java/com/rtbishop/look4sat/framework/{local/SatEntriesDao.kt => data/EntriesDao.kt} (84%) create mode 100644 app/src/main/java/com/rtbishop/look4sat/framework/data/Provider.kt rename app/src/main/java/com/rtbishop/look4sat/framework/{local/SatRadiosDao.kt => data/RadiosDao.kt} (75%) create mode 100644 app/src/main/java/com/rtbishop/look4sat/framework/data/Storage.kt rename app/src/main/java/com/rtbishop/look4sat/framework/{local/Look4SatDb.kt => data/StorageDb.kt} (85%) delete mode 100644 app/src/main/java/com/rtbishop/look4sat/framework/local/LocalSource.kt delete mode 100644 app/src/main/java/com/rtbishop/look4sat/framework/remote/RemoteSource.kt delete mode 100644 app/src/main/java/com/rtbishop/look4sat/presentation/Extensions.kt rename app/src/main/java/com/rtbishop/look4sat/presentation/{Look4SatApplication.kt => MainApplication.kt} (95%) delete mode 100644 app/src/main/java/com/rtbishop/look4sat/presentation/MainViewModel.kt rename core/src/main/java/com/rtbishop/look4sat/{domain => data}/DataParser.kt (99%) rename core/src/main/java/com/rtbishop/look4sat/data/{IRemoteSource.kt => IProvider.kt} (86%) rename core/src/main/java/com/rtbishop/look4sat/data/{ILocalSource.kt => IStorage.kt} (71%) rename core/src/main/java/com/rtbishop/look4sat/data/{DataRepository.kt => Repository.kt} (66%) rename core/src/main/java/com/rtbishop/look4sat/domain/{IDataRepository.kt => IRepository.kt} (78%) rename core/src/main/java/com/rtbishop/look4sat/{data/ISettingsHandler.kt => domain/ISettings.kt} (97%) diff --git a/app/schemas/com.rtbishop.look4sat.framework.local.Look4SatDb/1.json b/app/schemas/com.rtbishop.look4sat.framework.data.StorageDb/1.json similarity index 100% rename from app/schemas/com.rtbishop.look4sat.framework.local.Look4SatDb/1.json rename to app/schemas/com.rtbishop.look4sat.framework.data.StorageDb/1.json diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a1a8feeb..870b38e9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,7 +7,7 @@ . - */ -package com.rtbishop.look4sat.framework - -import com.rtbishop.look4sat.domain.model.SatEntry as DomainEntry -import com.rtbishop.look4sat.domain.model.SatItem as DomainItem -import com.rtbishop.look4sat.domain.model.SatRadio as DomainRadio -import com.rtbishop.look4sat.framework.model.SatEntry as FrameworkEntry -import com.rtbishop.look4sat.framework.model.SatItem as FrameworkItem -import com.rtbishop.look4sat.framework.model.SatRadio as FrameworkRadio - -fun DomainEntry.toFramework() = FrameworkEntry(this.data, this.comment) - -fun DomainRadio.toFramework() = FrameworkRadio( - this.uuid, this.info, this.isAlive, this.downlink, this.uplink, - this.mode, this.isInverted, this.catnum, this.comment -) - -fun FrameworkItem.toDomain() = DomainItem(this.catnum, this.name, this.modes, false) - -fun FrameworkRadio.toDomain() = DomainRadio( - this.uuid, this.info, this.isAlive, this.downlink, this.uplink, - this.mode, this.isInverted, this.catnum, this.comment -) - -fun List.toFrameworkEntries() = this.map { it.toFramework() } - -fun List.toFrameworkRadios() = this.map { it.toFramework() } - -fun List.toDomainItems() = this.map { it.toDomain() } - -fun List.toDomainRadios() = this.map { it.toDomain() } diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/LocationHandler.kt b/app/src/main/java/com/rtbishop/look4sat/framework/LocationHandler.kt index 8ffdd954..3ec80fa7 100644 --- a/app/src/main/java/com/rtbishop/look4sat/framework/LocationHandler.kt +++ b/app/src/main/java/com/rtbishop/look4sat/framework/LocationHandler.kt @@ -26,8 +26,8 @@ import android.location.LocationManager import android.os.Bundle import androidx.core.content.ContextCompat import com.rtbishop.look4sat.R -import com.rtbishop.look4sat.data.ISettingsHandler import com.rtbishop.look4sat.domain.ILocationHandler +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.domain.QthConverter import com.rtbishop.look4sat.domain.model.DataState import com.rtbishop.look4sat.domain.predict.GeoPos @@ -41,7 +41,7 @@ import javax.inject.Singleton @Singleton class LocationHandler @Inject constructor( @ApplicationContext private val context: Context, - private val settingsHandler: ISettingsHandler, + private val settings: ISettings, ) : LocationListener, ILocationHandler { private val manager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager @@ -51,8 +51,8 @@ class LocationHandler @Inject constructor( private val locationCoarse = Manifest.permission.ACCESS_COARSE_LOCATION private val locationFine = Manifest.permission.ACCESS_FINE_LOCATION private val _stationPosition = MutableStateFlow>(DataState.Handled) - private var currentLocator = settingsHandler.loadStationLocator() - private var currentPosition = settingsHandler.loadStationPosition() + private var currentLocator = settings.loadStationLocator() + private var currentPosition = settings.loadStationPosition() override val stationPosition: StateFlow> = _stationPosition @@ -68,8 +68,8 @@ class LocationHandler @Inject constructor( QthConverter.positionToQth(newLat, newLon)?.let { locator -> currentLocator = locator currentPosition = GeoPos(newLat, newLon) - settingsHandler.saveStationLocator(locator) - settingsHandler.saveStationPosition(currentPosition) + settings.saveStationLocator(locator) + settings.saveStationPosition(currentPosition) _stationPosition.value = DataState.Success(currentPosition) } } else { @@ -113,8 +113,8 @@ class LocationHandler @Inject constructor( if (position != null) { currentLocator = locator currentPosition = position - settingsHandler.saveStationLocator(locator) - settingsHandler.saveStationPosition(currentPosition) + settings.saveStationLocator(locator) + settings.saveStationPosition(currentPosition) _stationPosition.value = DataState.Success(currentPosition) } else { _stationPosition.value = DataState.Error(context.getString(R.string.pref_pos_qth_error)) 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 4ffea66a..28a8f231 100644 --- a/app/src/main/java/com/rtbishop/look4sat/framework/SettingsHandler.kt +++ b/app/src/main/java/com/rtbishop/look4sat/framework/SettingsHandler.kt @@ -19,15 +19,13 @@ package com.rtbishop.look4sat.framework import android.content.SharedPreferences import androidx.core.content.edit -import com.rtbishop.look4sat.data.ISettingsHandler +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.domain.predict.GeoPos -import com.rtbishop.look4sat.presentation.getDouble -import com.rtbishop.look4sat.presentation.putDouble import javax.inject.Inject import javax.inject.Singleton @Singleton -class SettingsHandler @Inject constructor(private val prefs: SharedPreferences) : ISettingsHandler { +class SettingsHandler @Inject constructor(private val prefs: SharedPreferences) : ISettings { companion object { const val keyDataSources = "dataSources" @@ -158,4 +156,12 @@ class SettingsHandler @Inject constructor(private val prefs: SharedPreferences) override fun saveDataSources(sources: List) { if (sources.isNotEmpty()) prefs.edit { putStringSet(keyDataSources, sources.toSet()) } } + + private fun SharedPreferences.getDouble(key: String, default: Double): Double { + return Double.fromBits(getLong(key, default.toRawBits())) + } + + private fun SharedPreferences.Editor.putDouble(key: String, double: Double) { + putLong(key, double.toRawBits()) + } } diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/local/SatEntriesDao.kt b/app/src/main/java/com/rtbishop/look4sat/framework/data/EntriesDao.kt similarity index 84% rename from app/src/main/java/com/rtbishop/look4sat/framework/local/SatEntriesDao.kt rename to app/src/main/java/com/rtbishop/look4sat/framework/data/EntriesDao.kt index 5380d995..e323aa01 100644 --- a/app/src/main/java/com/rtbishop/look4sat/framework/local/SatEntriesDao.kt +++ b/app/src/main/java/com/rtbishop/look4sat/framework/data/EntriesDao.kt @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.rtbishop.look4sat.framework.local +package com.rtbishop.look4sat.framework.data import androidx.room.* import com.rtbishop.look4sat.framework.model.SatEntry @@ -23,18 +23,18 @@ import com.rtbishop.look4sat.framework.model.SatItem import kotlinx.coroutines.flow.Flow @Dao -interface SatEntriesDao { +interface EntriesDao { @Query("SELECT COUNT(*) FROM entries") - fun getEntriesNumber(): Flow + fun getEntriesTotal(): Flow @Transaction @Query("SELECT catnum, name FROM entries ORDER BY name ASC") suspend fun getEntriesWithModes(): List @Transaction - @Query("SELECT * FROM entries WHERE catnum IN (:catnums)") - suspend fun getSelectedEntries(catnums: List): List + @Query("SELECT * FROM entries WHERE catnum IN (:selectedIds)") + suspend fun getEntriesWithIds(selectedIds: List): List @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertEntries(entries: List) diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/data/Provider.kt b/app/src/main/java/com/rtbishop/look4sat/framework/data/Provider.kt new file mode 100644 index 00000000..2532ab53 --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/framework/data/Provider.kt @@ -0,0 +1,25 @@ +package com.rtbishop.look4sat.framework.data + +import android.content.ContentResolver +import android.net.Uri +import com.rtbishop.look4sat.data.IProvider +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.withContext +import java.io.InputStream +import java.net.URL + +class Provider( + private val contentResolver: ContentResolver, + private val ioDispatcher: CoroutineDispatcher +) : IProvider { + + @Suppress("BlockingMethodInNonBlockingContext") + override suspend fun getLocalFileStream(uri: String): InputStream? { + return withContext(ioDispatcher) { contentResolver.openInputStream(Uri.parse(uri)) } + } + + @Suppress("BlockingMethodInNonBlockingContext") + override suspend fun getRemoteFileStream(url: String): InputStream? { + return withContext(ioDispatcher) { URL(url).openStream() } + } +} diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/local/SatRadiosDao.kt b/app/src/main/java/com/rtbishop/look4sat/framework/data/RadiosDao.kt similarity index 75% rename from app/src/main/java/com/rtbishop/look4sat/framework/local/SatRadiosDao.kt rename to app/src/main/java/com/rtbishop/look4sat/framework/data/RadiosDao.kt index 1f21416e..ff939695 100644 --- a/app/src/main/java/com/rtbishop/look4sat/framework/local/SatRadiosDao.kt +++ b/app/src/main/java/com/rtbishop/look4sat/framework/data/RadiosDao.kt @@ -15,23 +15,21 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.rtbishop.look4sat.framework.local +package com.rtbishop.look4sat.framework.data -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query +import androidx.room.* import com.rtbishop.look4sat.framework.model.SatRadio import kotlinx.coroutines.flow.Flow @Dao -interface SatRadiosDao { +interface RadiosDao { @Query("SELECT COUNT(*) FROM radios") - fun getRadiosNumber(): Flow + fun getRadiosTotal(): Flow - @Query("SELECT * FROM radios WHERE catnum = :catnum AND isAlive = 1") - suspend fun getRadios(catnum: Int): List + @Transaction + @Query("SELECT * FROM radios WHERE catnum = :id AND isAlive = 1") + suspend fun getRadiosWithId(id: Int): List @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertRadios(radios: List) diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/data/Storage.kt b/app/src/main/java/com/rtbishop/look4sat/framework/data/Storage.kt new file mode 100644 index 00000000..5fad5611 --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/framework/data/Storage.kt @@ -0,0 +1,86 @@ +/* + * Look4Sat. Amateur radio satellite tracker and pass predictor. + * Copyright (C) 2019-2021 Arty Bishop (bishop.arty@gmail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.rtbishop.look4sat.framework.data + +import com.rtbishop.look4sat.data.IStorage +import com.rtbishop.look4sat.domain.predict.Satellite +import com.rtbishop.look4sat.domain.model.SatEntry as DomainEntry +import com.rtbishop.look4sat.domain.model.SatItem as DomainItem +import com.rtbishop.look4sat.domain.model.SatRadio as DomainRadio +import com.rtbishop.look4sat.framework.model.SatEntry as FrameworkEntry +import com.rtbishop.look4sat.framework.model.SatItem as FrameworkItem +import com.rtbishop.look4sat.framework.model.SatRadio as FrameworkRadio + +class Storage(private val entriesDao: EntriesDao, private val radiosDao: RadiosDao) : IStorage { + + override fun getEntriesTotal() = entriesDao.getEntriesTotal() + + override fun getRadiosTotal() = radiosDao.getRadiosTotal() + + override suspend fun getEntriesWithModes(): List { + return entriesDao.getEntriesWithModes().toDomainItems() + } + + override suspend fun getEntriesWithIds(ids: List): List { + val selectedSatellites = mutableListOf() + ids.chunked(999).forEach { idsPart -> + val entries = entriesDao.getEntriesWithIds(idsPart) + selectedSatellites.addAll(entries.map { entry -> entry.data.createSat() }) + } + return selectedSatellites + } + + override suspend fun getRadiosWithId(id: Int): List { + return radiosDao.getRadiosWithId(id).toDomainRadios() + } + + override suspend fun insertEntries(entries: List) { + entriesDao.insertEntries(entries.toFrameworkEntries()) + } + + override suspend fun insertRadios(radios: List) { + radiosDao.insertRadios(radios.toFrameworkRadios()) + } + + override suspend fun clearAllData() { + entriesDao.deleteEntries() + radiosDao.deleteRadios() + } + + private fun DomainEntry.toFramework() = FrameworkEntry(this.data, this.comment) + + private fun DomainRadio.toFramework() = FrameworkRadio( + this.uuid, this.info, this.isAlive, this.downlink, this.uplink, + this.mode, this.isInverted, this.catnum, this.comment + ) + + private fun FrameworkItem.toDomain() = DomainItem(this.catnum, this.name, this.modes, false) + + private fun FrameworkRadio.toDomain() = DomainRadio( + this.uuid, this.info, this.isAlive, this.downlink, this.uplink, + this.mode, this.isInverted, this.catnum, this.comment + ) + + private fun List.toFrameworkEntries() = this.map { entry -> entry.toFramework() } + + private fun List.toFrameworkRadios() = this.map { radio -> radio.toFramework() } + + private fun List.toDomainItems() = this.map { item -> item.toDomain() } + + private fun List.toDomainRadios() = this.map { radio -> radio.toDomain() } +} diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/local/Look4SatDb.kt b/app/src/main/java/com/rtbishop/look4sat/framework/data/StorageDb.kt similarity index 85% rename from app/src/main/java/com/rtbishop/look4sat/framework/local/Look4SatDb.kt rename to app/src/main/java/com/rtbishop/look4sat/framework/data/StorageDb.kt index 8a6c4db5..a479b2e2 100644 --- a/app/src/main/java/com/rtbishop/look4sat/framework/local/Look4SatDb.kt +++ b/app/src/main/java/com/rtbishop/look4sat/framework/data/StorageDb.kt @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.rtbishop.look4sat.framework.local +package com.rtbishop.look4sat.framework.data import androidx.room.Database import androidx.room.RoomDatabase @@ -23,9 +23,9 @@ import com.rtbishop.look4sat.framework.model.SatEntry import com.rtbishop.look4sat.framework.model.SatRadio @Database(entities = [SatEntry::class, SatRadio::class], version = 1, exportSchema = true) -abstract class Look4SatDb : RoomDatabase() { +abstract class StorageDb : RoomDatabase() { - abstract fun entriesDao(): SatEntriesDao + abstract fun entriesDao(): EntriesDao - abstract fun radiosDao(): SatRadiosDao + abstract fun radiosDao(): RadiosDao } 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 deleted file mode 100644 index d5348298..00000000 --- a/app/src/main/java/com/rtbishop/look4sat/framework/local/LocalSource.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Look4Sat. Amateur radio satellite tracker and pass predictor. - * Copyright (C) 2019-2021 Arty Bishop (bishop.arty@gmail.com) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.rtbishop.look4sat.framework.local - -import android.content.ContentResolver -import android.net.Uri -import com.rtbishop.look4sat.data.ILocalSource -import com.rtbishop.look4sat.data.ISettingsHandler -import com.rtbishop.look4sat.domain.model.SatEntry -import com.rtbishop.look4sat.domain.model.SatItem -import com.rtbishop.look4sat.domain.model.SatRadio -import com.rtbishop.look4sat.domain.predict.Satellite -import com.rtbishop.look4sat.framework.toDomainItems -import com.rtbishop.look4sat.framework.toDomainRadios -import com.rtbishop.look4sat.framework.toFrameworkEntries -import com.rtbishop.look4sat.framework.toFrameworkRadios -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.withContext -import java.io.InputStream - -class LocalSource( - private val entriesDao: SatEntriesDao, - private val radiosDao: SatRadiosDao, - private val settings: ISettingsHandler, - private val resolver: ContentResolver, - private val ioDispatcher: CoroutineDispatcher -) : ILocalSource { - - override fun getEntriesNumber() = entriesDao.getEntriesNumber() - - override fun getRadiosNumber() = radiosDao.getRadiosNumber() - - override suspend fun getEntriesWithModes(): List { - val selectedCatnums = getEntriesSelection() - val entriesWithModes = entriesDao.getEntriesWithModes().toDomainItems() - entriesWithModes.forEach { entry -> entry.isSelected = entry.catnum in selectedCatnums } - return entriesWithModes - } - - override suspend fun getSelectedEntries(): List { - val selectedSatellites = mutableListOf() - getEntriesSelection().chunked(999).forEach { catnums -> - val entries = entriesDao.getSelectedEntries(catnums) - selectedSatellites.addAll(entries.map { entry -> entry.data.createSat() }) - } - return selectedSatellites - } - - override suspend fun getRadios(catnum: Int): List { - return radiosDao.getRadios(catnum).toDomainRadios() - } - - @Suppress("BlockingMethodInNonBlockingContext") - override suspend fun getFileStream(uri: String): InputStream? { - return withContext(ioDispatcher) { resolver.openInputStream(Uri.parse(uri)) } - } - - override suspend fun insertEntries(entries: List) { - entriesDao.insertEntries(entries.toFrameworkEntries()) - } - - override suspend fun insertRadios(radios: List) { - radiosDao.insertRadios(radios.toFrameworkRadios()) - } - - override suspend fun clearAllData() { - entriesDao.deleteEntries() - radiosDao.deleteRadios() - } - - override suspend fun getDataSources(): List { - return withContext(ioDispatcher) { settings.loadDataSources() } - } - - override suspend fun setDataSources(sources: List) { - withContext(ioDispatcher) { settings.saveDataSources(sources) } - } - - override suspend fun getEntriesSelection(): List { - return withContext(ioDispatcher) { settings.loadEntriesSelection() } - } - - override suspend fun setEntriesSelection(catnums: List) { - withContext(ioDispatcher) { settings.saveEntriesSelection(catnums) } - } -} diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/remote/RemoteSource.kt b/app/src/main/java/com/rtbishop/look4sat/framework/remote/RemoteSource.kt deleted file mode 100644 index c1b4e2a7..00000000 --- a/app/src/main/java/com/rtbishop/look4sat/framework/remote/RemoteSource.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.rtbishop.look4sat.framework.remote - -import com.rtbishop.look4sat.data.IRemoteSource -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.withContext -import java.io.InputStream -import java.net.URL - -class RemoteSource(private val ioDispatcher: CoroutineDispatcher) : IRemoteSource { - - @Suppress("BlockingMethodInNonBlockingContext") - override suspend fun getFileStream(url: String): InputStream? { - return withContext(ioDispatcher) { URL(url).openStream() } - } -} diff --git a/app/src/main/java/com/rtbishop/look4sat/injection/CoreModule.kt b/app/src/main/java/com/rtbishop/look4sat/injection/CoreModule.kt index 38b4c438..7937e308 100644 --- a/app/src/main/java/com/rtbishop/look4sat/injection/CoreModule.kt +++ b/app/src/main/java/com/rtbishop/look4sat/injection/CoreModule.kt @@ -20,18 +20,18 @@ package com.rtbishop.look4sat.injection import android.content.Context import android.content.SharedPreferences import androidx.room.Room -import com.rtbishop.look4sat.data.DataRepository -import com.rtbishop.look4sat.data.ISettingsHandler -import com.rtbishop.look4sat.domain.DataParser +import com.rtbishop.look4sat.data.DataParser +import com.rtbishop.look4sat.data.Repository import com.rtbishop.look4sat.domain.DataReporter -import com.rtbishop.look4sat.domain.IDataRepository import com.rtbishop.look4sat.domain.ILocationHandler +import com.rtbishop.look4sat.domain.IRepository +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.domain.predict.Predictor import com.rtbishop.look4sat.framework.LocationHandler import com.rtbishop.look4sat.framework.SettingsHandler -import com.rtbishop.look4sat.framework.local.LocalSource -import com.rtbishop.look4sat.framework.local.Look4SatDb -import com.rtbishop.look4sat.framework.remote.RemoteSource +import com.rtbishop.look4sat.framework.data.Provider +import com.rtbishop.look4sat.framework.data.Storage +import com.rtbishop.look4sat.framework.data.StorageDb import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -49,24 +49,22 @@ object CoreModule { @Provides @Singleton fun provideSatelliteRepo( - settings: ISettingsHandler, @ApplicationContext context: Context, @IoDispatcher ioDispatcher: CoroutineDispatcher, @DefaultDispatcher defaultDispatcher: CoroutineDispatcher - ): IDataRepository { - val db = Room.databaseBuilder(context, Look4SatDb::class.java, "Look4SatDb") + ): IRepository { + val db = Room.databaseBuilder(context, StorageDb::class.java, "Look4SatDb") .fallbackToDestructiveMigration().build() val dataParser = DataParser(defaultDispatcher) - val resolver = context.contentResolver - val local = LocalSource(db.entriesDao(), db.radiosDao(), settings, resolver, ioDispatcher) - val remote = RemoteSource(ioDispatcher) + val localSource = Storage(db.entriesDao(), db.radiosDao()) + val remoteSource = Provider(context.contentResolver, ioDispatcher) val repositoryScope = CoroutineScope(SupervisorJob()) - return DataRepository(dataParser, local, remote, repositoryScope) + return Repository(dataParser, localSource, remoteSource, repositoryScope) } @Provides @Singleton - fun provideSettingsHandler(sharedPreferences: SharedPreferences): ISettingsHandler { + fun provideSettingsHandler(sharedPreferences: SharedPreferences): ISettings { return SettingsHandler(sharedPreferences) } @@ -74,9 +72,9 @@ object CoreModule { @Singleton fun provideLocationHandler( @ApplicationContext context: Context, - settingsHandler: ISettingsHandler + settings: ISettings ): ILocationHandler { - return LocationHandler(context, settingsHandler) + return LocationHandler(context, settings) } @Provides diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/Extensions.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/Extensions.kt deleted file mode 100644 index b1613a5e..00000000 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/Extensions.kt +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Look4Sat. Amateur radio satellite tracker and pass predictor. - * Copyright (C) 2019-2021 Arty Bishop (bishop.arty@gmail.com) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.rtbishop.look4sat.presentation - -import android.content.Context -import android.content.SharedPreferences -import android.widget.Toast -import androidx.annotation.IdRes -import androidx.fragment.app.Fragment -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver -import androidx.navigation.fragment.findNavController - -fun Context.toast(text: String, duration: Int = Toast.LENGTH_SHORT) { - Toast.makeText(this, text, duration).apply { show() } -} - -fun SharedPreferences.getDouble(key: String, default: Double): Double { - return Double.fromBits(getLong(key, default.toRawBits())) -} - -fun SharedPreferences.Editor.putDouble(key: String, double: Double) { - putLong(key, double.toRawBits()) -} - -fun Fragment.getNavResult(@IdRes id: Int, key: String, onResult: (result: T) -> Unit) { - val backStackEntry = findNavController().getBackStackEntry(id) - val observer = LifecycleEventObserver { _, event -> - if (event == Lifecycle.Event.ON_RESUME && backStackEntry.savedStateHandle.contains(key)) { - backStackEntry.savedStateHandle.get(key)?.let(onResult) - backStackEntry.savedStateHandle.remove(key) - } - } - backStackEntry.lifecycle.addObserver(observer) - viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event -> - if (event == Lifecycle.Event.ON_DESTROY) backStackEntry.lifecycle.removeObserver(observer) - }) -} - -fun Fragment.setNavResult(key: String, value: T) { - findNavController().previousBackStackEntry?.savedStateHandle?.set(key, value) -} diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/MainActivity.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/MainActivity.kt index 80066242..42d005d6 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/MainActivity.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/MainActivity.kt @@ -20,23 +20,42 @@ package com.rtbishop.look4sat.presentation import android.annotation.SuppressLint import android.content.pm.ActivityInfo import android.os.Bundle -import androidx.activity.viewModels +import androidx.annotation.IdRes import androidx.appcompat.app.AppCompatActivity import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen +import androidx.fragment.app.Fragment +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver +import androidx.navigation.fragment.findNavController import com.rtbishop.look4sat.databinding.ActivityMainBinding import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class MainActivity : AppCompatActivity() { - private val mainViewModel: MainViewModel by viewModels() - @SuppressLint("SourceLockedOrientationActivity") override fun onCreate(savedInstanceState: Bundle?) { requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT installSplashScreen() super.onCreate(savedInstanceState) setContentView(ActivityMainBinding.inflate(layoutInflater).root) - mainViewModel.calculatePasses() } } + +fun Fragment.getNavResult(@IdRes id: Int, key: String, onResult: (result: T) -> Unit) { + val backStackEntry = findNavController().getBackStackEntry(id) + val observer = LifecycleEventObserver { _, event -> + if (event == Lifecycle.Event.ON_RESUME && backStackEntry.savedStateHandle.contains(key)) { + backStackEntry.savedStateHandle.get(key)?.let(onResult) + backStackEntry.savedStateHandle.remove(key) + } + } + backStackEntry.lifecycle.addObserver(observer) + viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event -> + if (event == Lifecycle.Event.ON_DESTROY) backStackEntry.lifecycle.removeObserver(observer) + }) +} + +fun Fragment.setNavResult(key: String, value: T) { + findNavController().previousBackStackEntry?.savedStateHandle?.set(key, value) +} diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/Look4SatApplication.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/MainApplication.kt similarity index 95% rename from app/src/main/java/com/rtbishop/look4sat/presentation/Look4SatApplication.kt rename to app/src/main/java/com/rtbishop/look4sat/presentation/MainApplication.kt index ae51dce4..4fe1d8e4 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/Look4SatApplication.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/MainApplication.kt @@ -21,4 +21,4 @@ import android.app.Application import dagger.hilt.android.HiltAndroidApp @HiltAndroidApp -class Look4SatApplication : Application() +class MainApplication : Application() diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/MainViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/MainViewModel.kt deleted file mode 100644 index 59d96fe6..00000000 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/MainViewModel.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.rtbishop.look4sat.presentation - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.rtbishop.look4sat.data.ISettingsHandler -import com.rtbishop.look4sat.domain.IDataRepository -import com.rtbishop.look4sat.domain.predict.Predictor -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.launch -import javax.inject.Inject - -@HiltViewModel -class MainViewModel @Inject constructor( - private val predictor: Predictor, - private val preferences: ISettingsHandler, - private val dataRepository: IDataRepository -) : ViewModel() { - - fun calculatePasses( - hoursAhead: Int = preferences.getHoursAhead(), - minElevation: Double = preferences.getMinElevation(), - timeRef: Long = System.currentTimeMillis() - ) { - viewModelScope.launch { - val satellites = dataRepository.getSelectedEntries() - val stationPos = preferences.loadStationPosition() - predictor.forceCalculation(satellites, stationPos, timeRef, hoursAhead, minElevation) - } - } -} diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragment.kt index fc543e83..c465c737 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragment.kt @@ -39,8 +39,8 @@ import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class EntriesFragment : Fragment(R.layout.fragment_entries) { - private lateinit var binding: FragmentEntriesBinding private val viewModel: EntriesViewModel by viewModels() + private lateinit var binding: FragmentEntriesBinding override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) 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 7285b5f8..fe3ca302 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 @@ -18,8 +18,8 @@ package com.rtbishop.look4sat.presentation.entriesScreen import androidx.lifecycle.* -import com.rtbishop.look4sat.data.ISettingsHandler -import com.rtbishop.look4sat.domain.IDataRepository +import com.rtbishop.look4sat.domain.IRepository +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.domain.model.DataState import com.rtbishop.look4sat.domain.model.SatItem import dagger.hilt.android.lifecycle.HiltViewModel @@ -28,13 +28,13 @@ import javax.inject.Inject @HiltViewModel class EntriesViewModel @Inject constructor( - private val preferences: ISettingsHandler, - private val repository: IDataRepository + private val repository: IRepository, + private val settings: ISettings ) : ViewModel(), EntriesAdapter.EntriesClickListener { - private val transModes = MutableLiveData(preferences.loadModesSelection()) + private val transModes = MutableLiveData(settings.loadModesSelection()) private val currentQuery = MutableLiveData(String()) - private val itemsFromRepo = liveData { emit(repository.getEntriesWithModes()) } as MutableLiveData + private val itemsFromRepo = liveData { emit(loadEntriesWithSelection()) } as MutableLiveData private val itemsWithModes = transModes.switchMap { modes -> itemsFromRepo.map { items -> filterByModes(items, modes) } } @@ -51,7 +51,7 @@ class EntriesViewModel @Inject constructor( fun saveSelectedModes(modes: List) { transModes.value = modes - preferences.saveModesSelection(modes) + settings.saveModesSelection(modes) } fun setQuery(query: String) { @@ -74,6 +74,11 @@ class EntriesViewModel @Inject constructor( } } + private suspend fun loadEntriesWithSelection(): List { + val selectedIds = settings.loadEntriesSelection() + return repository.getEntriesWithModes().onEach { it.isSelected = it.catnum in selectedIds } + } + private fun filterByModes(items: List, modes: List): List { if (modes.isEmpty()) return items return items.filter { item -> item.modes.any { mode -> mode in modes } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/ModesDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/ModesDialog.kt index 436b3440..7f234fdc 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/ModesDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/ModesDialog.kt @@ -9,8 +9,8 @@ import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.SimpleItemAnimator import com.rtbishop.look4sat.R -import com.rtbishop.look4sat.data.ISettingsHandler import com.rtbishop.look4sat.databinding.DialogModesBinding +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.presentation.setNavResult import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @@ -19,7 +19,7 @@ import javax.inject.Inject class ModesDialog : AppCompatDialogFragment(), ModesAdapter.ModesClickListener { @Inject - lateinit var preferences: ISettingsHandler + lateinit var preferences: ISettings private lateinit var binding: DialogModesBinding private val allModes = listOf( "AFSK", "AFSK S-Net", "AFSK SALSAT", "AHRPT", "AM", "APT", "BPSK", "BPSK PMT-A3", diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapFragment.kt index e1b3e9ca..33c6b47c 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapFragment.kt @@ -17,7 +17,7 @@ */ package com.rtbishop.look4sat.presentation.mapScreen -import android.content.SharedPreferences +import android.content.Context import android.graphics.Color import android.graphics.ColorMatrix import android.graphics.ColorMatrixColorFilter @@ -43,17 +43,12 @@ import org.osmdroid.views.overlay.FolderOverlay import org.osmdroid.views.overlay.Marker import org.osmdroid.views.overlay.Polygon import org.osmdroid.views.overlay.Polyline -import javax.inject.Inject @AndroidEntryPoint class MapFragment : Fragment(R.layout.fragment_map) { - @Inject - lateinit var sharedPreferences: SharedPreferences - private lateinit var binding: FragmentMapBinding - - private val args: MapFragmentArgs by navArgs() private val viewModel: MapViewModel by viewModels() + private val navArgs: MapFragmentArgs by navArgs() private val minLat = MapView.getTileSystem().minLatitude private val maxLat = MapView.getTileSystem().maxLatitude private val trackPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { @@ -67,6 +62,7 @@ class MapFragment : Fragment(R.layout.fragment_map) { style = Paint.Style.FILL_AND_STROKE color = Color.parseColor("#26FFE082") } + private lateinit var binding: FragmentMapBinding override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -76,7 +72,9 @@ class MapFragment : Fragment(R.layout.fragment_map) { } private fun setupComponents() { - Configuration.getInstance().load(requireContext(), sharedPreferences) + val context = requireContext() + val preferences = context.getSharedPreferences("default", Context.MODE_PRIVATE) + Configuration.getInstance().load(context, preferences) binding.run { mapView.apply { setMultiTouchControls(true) @@ -99,15 +97,15 @@ class MapFragment : Fragment(R.layout.fragment_map) { } private fun setupObservers() { - viewModel.selectDefaultSatellite(args.catNum) - viewModel.stationPosLiveData.observe(viewLifecycleOwner) { renderStationPos(it) } - viewModel.satPositions.observe(viewLifecycleOwner) { renderSatPositions(it) } - viewModel.satTrack.observe(viewLifecycleOwner) { renderSatTrack(it) } - viewModel.satFootprint.observe(viewLifecycleOwner) { renderSatFootprint(it) } - viewModel.mapData.observe(viewLifecycleOwner) { renderSatData(it) } + viewModel.selectDefaultSatellite(navArgs.catNum) + viewModel.stationPos.observe(viewLifecycleOwner) { handleStationPos(it) } + viewModel.positions.observe(viewLifecycleOwner) { handlePositions(it) } + viewModel.track.observe(viewLifecycleOwner) { handleTrack(it) } + viewModel.footprint.observe(viewLifecycleOwner) { handleFootprint(it) } + viewModel.mapData.observe(viewLifecycleOwner) { handleMapData(it) } } - private fun renderStationPos(stationPos: GeoPos) { + private fun handleStationPos(stationPos: GeoPos) { binding.apply { Marker(mapView).apply { setInfoWindow(null) @@ -120,7 +118,7 @@ class MapFragment : Fragment(R.layout.fragment_map) { } } - private fun renderSatPositions(posMap: Map) { + private fun handlePositions(posMap: Map) { binding.apply { val markers = FolderOverlay() posMap.entries.forEach { @@ -149,7 +147,7 @@ class MapFragment : Fragment(R.layout.fragment_map) { } } - private fun renderSatTrack(satTrack: List>) { + private fun handleTrack(satTrack: List>) { val trackOverlay = FolderOverlay() satTrack.forEach { track -> val trackPoints = track.map { GeoPoint(it.latitude, it.longitude) } @@ -166,7 +164,7 @@ class MapFragment : Fragment(R.layout.fragment_map) { binding.mapView.overlays[1] = trackOverlay } - private fun renderSatFootprint(satFootprint: List) { + private fun handleFootprint(satFootprint: List) { val footprintPoints = satFootprint.map { GeoPoint(it.latitude, it.longitude) } val footprintOverlay = Polygon().apply { fillPaint.set(footprintPaint) @@ -180,7 +178,7 @@ class MapFragment : Fragment(R.layout.fragment_map) { binding.mapView.overlays[2] = footprintOverlay } - private fun renderSatData(mapData: MapData) { + private fun handleMapData(mapData: MapData) { binding.apply { mapDataName.text = String.format(getString(R.string.pat_osm_idName), mapData.catNum, mapData.name) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapViewModel.kt index 2804b18b..e5b282ed 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapViewModel.kt @@ -18,8 +18,8 @@ package com.rtbishop.look4sat.presentation.mapScreen import androidx.lifecycle.* -import com.rtbishop.look4sat.data.ISettingsHandler -import com.rtbishop.look4sat.domain.IDataRepository +import com.rtbishop.look4sat.domain.IRepository +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.domain.QthConverter import com.rtbishop.look4sat.domain.predict.GeoPos import com.rtbishop.look4sat.domain.predict.Predictor @@ -33,52 +33,54 @@ import kotlin.math.min @HiltViewModel class MapViewModel @Inject constructor( - private val dataRepository: IDataRepository, private val predictor: Predictor, - preferences: ISettingsHandler, + private val repository: IRepository, + private val settings: ISettings, ) : ViewModel() { - private val stationPos = preferences.loadStationPosition() + private val stationPosition = settings.loadStationPosition() + private var allSatellites = listOf() private var dataUpdateJob: Job? = null - private var allSatList = listOf() - private lateinit var selectedSat: Satellite + private var dataUpdateRate = 2000L + private lateinit var selectedSatellite: Satellite - val stationPosLiveData = liveData { - val osmLat = clipLat(stationPos.latitude) - val osmLon = clipLon(stationPos.longitude) + val stationPos = liveData { + val osmLat = clipLat(stationPosition.latitude) + val osmLon = clipLon(stationPosition.longitude) emit(GeoPos(osmLat, osmLon)) } - private val _satTrack = MutableLiveData>>() - val satTrack: LiveData>> = _satTrack + private val _track = MutableLiveData>>() + val track: LiveData>> = _track - private val _satFootprint = MutableLiveData>() - val satFootprint: LiveData> = _satFootprint + private val _footprint = MutableLiveData>() + val footprint: LiveData> = _footprint - private val _satData = MutableLiveData() - val mapData: LiveData = this._satData + private val _mapData = MutableLiveData() + val mapData: LiveData = this._mapData - private val _satPositions = MutableLiveData>() - val satPositions: LiveData> = _satPositions + private val _positions = MutableLiveData>() + val positions: LiveData> = _positions fun scrollSelection(decrement: Boolean) { - if (allSatList.isNotEmpty()) { - val index = allSatList.indexOf(selectedSat) + if (allSatellites.isNotEmpty()) { + val index = allSatellites.indexOf(selectedSatellite) if (decrement) { - if (index > 0) selectSatellite(allSatList[index - 1]) - else selectSatellite(allSatList[allSatList.size - 1]) + if (index > 0) selectSatellite(allSatellites[index - 1]) + else selectSatellite(allSatellites[allSatellites.size - 1]) } else { - if (index < allSatList.size - 1) selectSatellite(allSatList[index + 1]) - else selectSatellite(allSatList[0]) + if (index < allSatellites.size - 1) selectSatellite(allSatellites[index + 1]) + else selectSatellite(allSatellites[0]) } } } fun selectDefaultSatellite(catnum: Int) { viewModelScope.launch { - dataRepository.getSelectedEntries().also { satellites -> + val selectedIds = settings.loadEntriesSelection() + repository.getEntriesWithIds(selectedIds).also { satellites -> if (satellites.isNotEmpty()) { - allSatList = satellites + allSatellites = satellites if (catnum == -1) { selectSatellite(satellites.first()) } else { @@ -89,18 +91,18 @@ class MapViewModel @Inject constructor( } } - fun selectSatellite(satellite: Satellite, updateFreq: Long = 2000) { - selectedSat = satellite + fun selectSatellite(satellite: Satellite, updateFreq: Long = dataUpdateRate) { + selectedSatellite = satellite viewModelScope.launch { dataUpdateJob?.cancelAndJoin() dataUpdateJob = launch { val dateNow = Date() - getSatTrack(selectedSat, stationPos, dateNow) + getSatTrack(selectedSatellite, stationPosition, dateNow) while (isActive) { dateNow.time = System.currentTimeMillis() - getPositions(allSatList, stationPos, dateNow) - getSatFootprint(selectedSat, stationPos, dateNow) - getSatData(selectedSat, stationPos, dateNow) + getPositions(allSatellites, stationPosition, dateNow) + getSatFootprint(selectedSatellite, stationPosition, dateNow) + getSatData(selectedSatellite, stationPosition, dateNow) delay(updateFreq) } } @@ -133,7 +135,7 @@ class MapViewModel @Inject constructor( currentTrack.add(currentPosition) } satTracks.add(currentTrack) - _satTrack.postValue(satTracks) + _track.postValue(satTracks) } private suspend fun getPositions(satellites: List, pos: GeoPos, date: Date) { @@ -144,7 +146,7 @@ class MapViewModel @Inject constructor( val osmLon = clipLon(Math.toDegrees(satPos.longitude)) positions[satellite] = GeoPos(osmLat, osmLon) } - _satPositions.postValue(positions) + _positions.postValue(positions) } private suspend fun getSatFootprint(satellite: Satellite, pos: GeoPos, date: Date) { @@ -154,7 +156,7 @@ class MapViewModel @Inject constructor( val osmLon = clipLon(rangePos.longitude) GeoPos(osmLat, osmLon) } - _satFootprint.postValue(satFootprint) + _footprint.postValue(satFootprint) } private suspend fun getSatData(satellite: Satellite, pos: GeoPos, date: Date) { @@ -167,7 +169,7 @@ class MapViewModel @Inject constructor( satellite, satellite.data.catnum, satellite.data.name, satPos.distance, satPos.altitude, satPos.getOrbitalVelocity(), qthLoc, osmPos ) - _satData.postValue(satData) + _mapData.postValue(satData) } private fun clipLat(latitude: Double): Double { diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/FilterDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/FilterDialog.kt index a1fbb848..891e93a8 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/FilterDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/FilterDialog.kt @@ -7,8 +7,8 @@ import android.view.ViewGroup import android.view.WindowManager import androidx.appcompat.app.AppCompatDialogFragment import com.rtbishop.look4sat.R -import com.rtbishop.look4sat.data.ISettingsHandler import com.rtbishop.look4sat.databinding.DialogFilterBinding +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.presentation.setNavResult import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @@ -17,7 +17,7 @@ import javax.inject.Inject class FilterDialog : AppCompatDialogFragment() { @Inject - lateinit var preferences: ISettingsHandler + lateinit var preferences: ISettings override fun onCreateView(inflater: LayoutInflater, group: ViewGroup?, state: Bundle?): View? { return inflater.inflate(R.layout.dialog_filter, group, false) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesFragment.kt index 8bcc67b6..ca8dfda4 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesFragment.kt @@ -18,9 +18,11 @@ package com.rtbishop.look4sat.presentation.passesScreen import android.animation.ValueAnimator +import android.content.Context import android.os.Bundle import android.view.View import android.view.animation.LinearInterpolator +import android.widget.Toast import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController @@ -34,7 +36,6 @@ import com.rtbishop.look4sat.domain.model.DataState import com.rtbishop.look4sat.domain.predict.SatPass import com.rtbishop.look4sat.domain.toTimerString import com.rtbishop.look4sat.presentation.getNavResult -import com.rtbishop.look4sat.presentation.toast import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -83,8 +84,8 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC viewModel.passes.observe(viewLifecycleOwner) { passesResult -> handleNewPasses(passesResult, adapter) } - viewModel.entries.observe(viewLifecycleOwner) { number -> - handleEntriesNumber(number) + viewModel.entriesTotal.observe(viewLifecycleOwner) { number -> + handleEntriesTotal(number) } getNavResult>(R.id.nav_passes, "prefs") { prefs -> viewModel.calculatePasses(prefs.first, prefs.second) @@ -103,7 +104,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC } } - private fun handleEntriesNumber(number: Int) { + private fun handleEntriesTotal(number: Int) { if (number > 0) { binding.passesFab.setOnClickListener { navigateToEntries() } } else { @@ -190,4 +191,8 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC findNavController().navigate(action) } } + + private fun Context.toast(text: String, duration: Int = Toast.LENGTH_SHORT) { + Toast.makeText(this, text, duration).apply { show() } + } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesViewModel.kt index 90ebdfd4..66bd0be2 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesViewModel.kt @@ -18,8 +18,8 @@ package com.rtbishop.look4sat.presentation.passesScreen import androidx.lifecycle.* -import com.rtbishop.look4sat.data.ISettingsHandler -import com.rtbishop.look4sat.domain.IDataRepository +import com.rtbishop.look4sat.domain.IRepository +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.domain.model.DataState import com.rtbishop.look4sat.domain.predict.Predictor import com.rtbishop.look4sat.domain.predict.SatPass @@ -30,14 +30,14 @@ import javax.inject.Inject @HiltViewModel class PassesViewModel @Inject constructor( private val predictor: Predictor, - private val settings: ISettingsHandler, - private val repository: IDataRepository + private val repository: IRepository, + private val settings: ISettings ) : ViewModel() { private var passesProcessing: Job? = null private val _passes = MutableLiveData>>(DataState.Loading) val passes: LiveData>> = _passes - val entries: LiveData = repository.getEntriesNumber().asLiveData() + val entriesTotal: LiveData = repository.getEntriesTotal().asLiveData() init { viewModelScope.launch { @@ -53,6 +53,7 @@ class PassesViewModel @Inject constructor( } } } + calculatePasses() } fun shouldUseUTC() = settings.getUseUTC() @@ -66,11 +67,12 @@ class PassesViewModel @Inject constructor( viewModelScope.launch { _passes.postValue(DataState.Loading) passesProcessing?.cancelAndJoin() - selection?.let { items -> repository.setEntriesSelection(items) } + selection?.let { items -> settings.saveEntriesSelection(items) } settings.setHoursAhead(hoursAhead) settings.setMinElevation(minElevation) - val satellites = repository.getSelectedEntries() val stationPos = settings.loadStationPosition() + val selectedIds = settings.loadEntriesSelection() + val satellites = repository.getEntriesWithIds(selectedIds) predictor.forceCalculation(satellites, stationPos, timeRef, hoursAhead, minElevation) } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/radarScreen/RadarFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/radarScreen/RadarFragment.kt index 59493b22..69f488a7 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/radarScreen/RadarFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/radarScreen/RadarFragment.kt @@ -27,31 +27,27 @@ import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.SimpleItemAnimator import com.rtbishop.look4sat.R -import com.rtbishop.look4sat.data.ISettingsHandler import com.rtbishop.look4sat.databinding.FragmentRadarBinding import com.rtbishop.look4sat.domain.predict.SatPass import com.rtbishop.look4sat.domain.predict.SatPos import com.rtbishop.look4sat.domain.toTimerString import dagger.hilt.android.AndroidEntryPoint -import javax.inject.Inject @AndroidEntryPoint class RadarFragment : Fragment(R.layout.fragment_radar) { - @Inject - lateinit var preferences: ISettingsHandler - private lateinit var binding: FragmentRadarBinding - private val args: RadarFragmentArgs by navArgs() private val viewModel: RadarViewModel by viewModels() - private var radarView: RadarView? = null + private val navArgs: RadarFragmentArgs by navArgs() + private lateinit var binding: FragmentRadarBinding + private lateinit var radarView: RadarView override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding = FragmentRadarBinding.bind(view) - setupViews() + setupComponents() } - private fun setupViews() { + private fun setupComponents() { val context = requireContext() val adapter = RadioAdapter() val layoutManager = LinearLayoutManager(context) @@ -69,15 +65,15 @@ class RadarFragment : Fragment(R.layout.fragment_radar) { } private fun setupObservers(radioAdapter: RadioAdapter) { - viewModel.getPass(args.catNum, args.aosTime).observe(viewLifecycleOwner) { pass -> + viewModel.getPass(navArgs.catNum, navArgs.aosTime).observe(viewLifecycleOwner) { pass -> radarView = RadarView(requireContext()).apply { - setShowAim(preferences.getUseCompass()) - setScanning(preferences.getShowSweep()) + setShowAim(viewModel.getUseCompass()) + setScanning(viewModel.getShowSweep()) } binding.radarCard.addView(radarView) viewModel.radarData.observe(viewLifecycleOwner) { passData -> - radarView?.setPosition(passData.satPos) - radarView?.setPositions(passData.satTrack) + radarView.setPosition(passData.satPos) + radarView.setPositions(passData.satTrack) setPassText(pass, passData.satPos) } viewModel.transmitters.observe(viewLifecycleOwner) { list -> @@ -87,16 +83,15 @@ class RadarFragment : Fragment(R.layout.fragment_radar) { } else { binding.radarRecyclerMsg.text = getString(R.string.trans_no_data) } - radarView?.invalidate() + radarView.invalidate() } - viewModel.orientation.observe(viewLifecycleOwner) { orientation -> - radarView?.setOrientation( - orientation.first, - orientation.second, - orientation.third - ) + viewModel.orientation.observe(viewLifecycleOwner) { value -> + radarView.setOrientation(value.first, value.second, value.third) } + binding.radarBack.setOnClickListener { findNavController().navigateUp() } binding.radarMap.setOnClickListener { navigateToMap(pass.catNum) } + binding.radarBtnNotify.isEnabled = false + binding.radarBtnSettings.setOnClickListener { navigateToSettings() } } } @@ -106,11 +101,12 @@ class RadarFragment : Fragment(R.layout.fragment_radar) { val radarElev = getString(R.string.radar_el_value) val radarAlt = getString(R.string.radar_alt_value) val radarDist = getString(R.string.radar_dist_value) + val radarId = getString(R.string.radar_sat_id) binding.radarAzValue.text = String.format(radarAzim, Math.toDegrees(satPos.azimuth)) binding.radarElValue.text = String.format(radarElev, Math.toDegrees(satPos.elevation)) binding.radarAltValue.text = String.format(radarAlt, satPos.altitude) binding.radarDstValue.text = String.format(radarDist, satPos.distance) -// binding.radarName.text = satPass.name + binding.radarSatId.text = String.format(radarId, satPass.catNum) if (!satPass.isDeepSpace) { if (timeNow < satPass.aosTime) { @@ -134,6 +130,11 @@ class RadarFragment : Fragment(R.layout.fragment_radar) { findNavController().navigate(direction) } + private fun navigateToSettings() { + val direction = RadarFragmentDirections.actionGlobalSettingsFragment() + findNavController().navigate(direction) + } + override fun onResume() { super.onResume() viewModel.enableSensor() diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/radarScreen/RadarViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/radarScreen/RadarViewModel.kt index 6042bfc0..50344583 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/radarScreen/RadarViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/radarScreen/RadarViewModel.kt @@ -19,9 +19,9 @@ package com.rtbishop.look4sat.presentation.radarScreen import android.hardware.GeomagneticField import androidx.lifecycle.* -import com.rtbishop.look4sat.data.ISettingsHandler import com.rtbishop.look4sat.domain.DataReporter -import com.rtbishop.look4sat.domain.IDataRepository +import com.rtbishop.look4sat.domain.IRepository +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.domain.model.SatRadio import com.rtbishop.look4sat.domain.predict.GeoPos import com.rtbishop.look4sat.domain.predict.Predictor @@ -39,13 +39,13 @@ import javax.inject.Inject @HiltViewModel class RadarViewModel @Inject constructor( private val orientationHandler: OrientationHandler, - private val preferences: ISettingsHandler, + private val reporter: DataReporter, private val predictor: Predictor, - private val dataRepository: IDataRepository, - private val dataReporter: DataReporter + private val repository: IRepository, + private val settings: ISettings ) : ViewModel(), OrientationHandler.OrientationListener { - private val stationPos = preferences.loadStationPosition() + private val stationPos = settings.loadStationPosition() private val _passData = MutableLiveData() private val _transmitters = MutableLiveData>() private val _orientation = MutableLiveData>() @@ -55,7 +55,7 @@ class RadarViewModel @Inject constructor( fun getPass(catNum: Int, aosTime: Long) = liveData { predictor.calculatedPasses.collect { passes -> - val pass = passes.find { it.catNum == catNum && it.aosTime == aosTime } + val pass = passes.find { pass -> pass.catNum == catNum && pass.aosTime == aosTime } pass?.let { satPass -> emit(satPass) sendPassData(satPass) @@ -65,13 +65,17 @@ class RadarViewModel @Inject constructor( } fun enableSensor() { - if (preferences.getUseCompass()) orientationHandler.startListening(this) + if (settings.getUseCompass()) orientationHandler.startListening(this) } fun disableSensor() { - if (preferences.getUseCompass()) orientationHandler.stopListening() + if (settings.getUseCompass()) orientationHandler.stopListening() } + fun getUseCompass(): Boolean = settings.getUseCompass() + + fun getShowSweep(): Boolean = settings.getShowSweep() + override fun onOrientationChanged(azimuth: Float, pitch: Float, roll: Float) { _orientation.value = Triple(azimuth + getMagDeclination(stationPos), pitch, roll) } @@ -92,12 +96,12 @@ class RadarViewModel @Inject constructor( } while (isActive) { val satPos = predictor.getSatPos(satPass.satellite, stationPos, Date().time) - if (preferences.getRotatorEnabled()) { - val server = preferences.getRotatorServer() - val port = preferences.getRotatorPort().toInt() + if (settings.getRotatorEnabled()) { + val server = settings.getRotatorServer() + val port = settings.getRotatorPort().toInt() val azimuth = Math.toDegrees(satPos.azimuth).round(1) val elevation = Math.toDegrees(satPos.elevation).round(1) - dataReporter.reportRotation(server, port, azimuth, elevation) + reporter.reportRotation(server, port, azimuth, elevation) } _passData.postValue(RadarData(satPos, satTrack)) delay(1000) @@ -107,7 +111,7 @@ class RadarViewModel @Inject constructor( private fun processTransmitters(pass: SatPass) { viewModelScope.launch { - val transmitters = dataRepository.getRadios(pass.catNum) + val transmitters = repository.getRadiosWithId(pass.catNum) while (isActive) { val time = System.currentTimeMillis() val list = predictor.processRadios(pass.satellite, stationPos, transmitters, time) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/LocationDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/LocationDialog.kt index 4bee695b..c2d23287 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/LocationDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/LocationDialog.kt @@ -7,8 +7,8 @@ import android.view.ViewGroup import android.view.WindowManager import androidx.appcompat.app.AppCompatDialogFragment import com.rtbishop.look4sat.R -import com.rtbishop.look4sat.data.ISettingsHandler import com.rtbishop.look4sat.databinding.DialogLocationBinding +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.presentation.setNavResult import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @@ -17,7 +17,7 @@ import javax.inject.Inject class LocationDialog : AppCompatDialogFragment() { @Inject - lateinit var preferences: ISettingsHandler + lateinit var preferences: ISettings override fun onCreateView(inflater: LayoutInflater, group: ViewGroup?, state: Bundle?): View? { return inflater.inflate(R.layout.dialog_location, group, false) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/LocatorDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/LocatorDialog.kt index 5808913c..110c7c27 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/LocatorDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/LocatorDialog.kt @@ -7,8 +7,8 @@ import android.view.ViewGroup import android.view.WindowManager import androidx.appcompat.app.AppCompatDialogFragment import com.rtbishop.look4sat.R -import com.rtbishop.look4sat.data.ISettingsHandler import com.rtbishop.look4sat.databinding.DialogLocatorBinding +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.presentation.setNavResult import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @@ -17,7 +17,7 @@ import javax.inject.Inject class LocatorDialog : AppCompatDialogFragment() { @Inject - lateinit var preferences: ISettingsHandler + lateinit var preferences: ISettings override fun onCreateView(inflater: LayoutInflater, group: ViewGroup?, state: Bundle?): View? { return inflater.inflate(R.layout.dialog_locator, group, false) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SettingsFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SettingsFragment.kt index 46aa43ac..51841d37 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SettingsFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SettingsFragment.kt @@ -44,7 +44,6 @@ import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class SettingsFragment : Fragment(R.layout.fragment_settings) { - private lateinit var binding: FragmentSettingsBinding private val viewModel: SettingsViewModel by viewModels() private val locationFine = Manifest.permission.ACCESS_FINE_LOCATION private val locationCoarse = Manifest.permission.ACCESS_COARSE_LOCATION @@ -60,15 +59,16 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) { private val contentRequest = registerForActivityResult(contentContract) { uri -> uri?.let { viewModel.updateDataFromFile(uri.toString()) } } + private lateinit var binding: FragmentSettingsBinding override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding = FragmentSettingsBinding.bind(view) - setupViews() + setupComponents() setupObservers() } - private fun setupViews() { + private fun setupComponents() { binding.settingsScroll.apply { setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, y, _, newY -> if (y > newY) binding.settingsFab.hide() else binding.settingsFab.show() @@ -134,11 +134,11 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) { findNavController().navigate(action) } binding.settingsData.dataBtnClear.setOnClickListener { viewModel.clearData() } - viewModel.entries.observe(viewLifecycleOwner) { number -> + viewModel.entriesTotal.observe(viewLifecycleOwner) { number -> val entriesFormat = getString(R.string.fmt_entries) binding.settingsData.dataEntries.text = String.format(entriesFormat, number) } - viewModel.radios.observe(viewLifecycleOwner) { number -> + viewModel.radiosTotal.observe(viewLifecycleOwner) { number -> val radiosFormat = getString(R.string.fmt_radios) binding.settingsData.dataRadios.text = String.format(radiosFormat, number) } 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 2bf5a26c..2d203b39 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 @@ -2,9 +2,9 @@ package com.rtbishop.look4sat.presentation.settingsScreen import androidx.lifecycle.ViewModel import androidx.lifecycle.asLiveData -import com.rtbishop.look4sat.data.ISettingsHandler -import com.rtbishop.look4sat.domain.IDataRepository import com.rtbishop.look4sat.domain.ILocationHandler +import com.rtbishop.look4sat.domain.IRepository +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.domain.model.DataState import com.rtbishop.look4sat.domain.predict.GeoPos import dagger.hilt.android.lifecycle.HiltViewModel @@ -13,19 +13,20 @@ import javax.inject.Inject @HiltViewModel class SettingsViewModel @Inject constructor( - private val settings: ISettingsHandler, - private val repository: IDataRepository, - private val locationHandler: ILocationHandler + private val locationHandler: ILocationHandler, + private val repository: IRepository, + private val settings: ISettings ) : ViewModel() { - val entries = repository.getEntriesNumber().asLiveData() - val radios = repository.getRadiosNumber().asLiveData() + val entriesTotal = repository.getEntriesTotal().asLiveData() + val radiosTotal = repository.getRadiosTotal().asLiveData() fun updateDataFromFile(uri: String) { repository.updateFromFile(uri) } fun updateDataFromWeb(sources: List) { + settings.saveDataSources(sources) repository.updateFromWeb(sources) } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SourcesDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SourcesDialog.kt index 0e97d63d..98f2faf2 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SourcesDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SourcesDialog.kt @@ -27,7 +27,7 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import com.rtbishop.look4sat.R import com.rtbishop.look4sat.databinding.DialogSourcesBinding -import com.rtbishop.look4sat.domain.IDataRepository +import com.rtbishop.look4sat.domain.ISettings import com.rtbishop.look4sat.framework.model.DataSource import com.rtbishop.look4sat.presentation.setNavResult import dagger.hilt.android.AndroidEntryPoint @@ -37,7 +37,7 @@ import javax.inject.Inject class SourcesDialog : AppCompatDialogFragment(), SourcesAdapter.SourcesClickListener { @Inject - lateinit var repository: IDataRepository + lateinit var settings: ISettings private lateinit var binding: DialogSourcesBinding private lateinit var sourcesAdapter: SourcesAdapter @@ -54,7 +54,7 @@ class SourcesDialog : AppCompatDialogFragment(), SourcesAdapter.SourcesClickList WindowManager.LayoutParams.WRAP_CONTENT ) lifecycleScope.launchWhenResumed { - val sources = repository.getDataSources().map { url -> DataSource(url) } + val sources = settings.loadDataSources().map { url -> DataSource(url) } val layoutManager = LinearLayoutManager(requireContext()) sourcesAdapter = SourcesAdapter(this@SourcesDialog).apply { submitList(sources) } binding.run { diff --git a/app/src/main/res/layout/fragment_radar.xml b/app/src/main/res/layout/fragment_radar.xml index fd4f8bf5..3f9581be 100644 --- a/app/src/main/res/layout/fragment_radar.xml +++ b/app/src/main/res/layout/fragment_radar.xml @@ -174,20 +174,21 @@