From 0110de810463635d6e209a327a1b67f60621cc73 Mon Sep 17 00:00:00 2001 From: Arty Bishop Date: Thu, 6 May 2021 13:14:50 +0100 Subject: [PATCH] Repositories refactoring and merge --- .../rtbishop/look4sat/di/DataSourceModule.kt | 19 ++- .../rtbishop/look4sat/di/InteractorsModule.kt | 12 +- .../framework/DefaultLocationSource.kt | 62 ------- .../look4sat/framework/PreferencesProvider.kt | 155 ++++++++++++++++++ .../look4sat/framework/PrefsManager.kt | 124 -------------- .../look4sat/framework/db/RoomDataSource.kt | 2 +- .../look4sat/framework/model/TleSource.kt | 20 --- .../look4sat/presentation/Look4SatActivity.kt | 8 +- .../entriesScreen/EntriesFragment.kt | 27 +-- .../entriesScreen/EntriesViewModel.kt | 45 ++--- .../presentation/mapScreen/MapViewModel.kt | 13 +- .../passesScreen/PassesViewModel.kt | 8 +- .../polarScreen/PolarViewModel.kt | 22 ++- .../presentation/prefsScreen/PrefsFragment.kt | 22 +-- .../sourcesDialog/SourcesAdapter.kt | 70 -------- .../sourcesDialog/SourcesDialog.kt | 66 -------- .../rtbishop/look4sat/utility/Extensions.kt | 27 --- app/src/main/res/navigation/nav_graph.xml | 11 -- .../rtbishop/look4sat/data/LocalDataSource.kt | 4 +- .../rtbishop/look4sat/data/LocationRepo.kt | 35 ---- .../rtbishop/look4sat/data/LocationSource.kt | 14 -- .../com/rtbishop/look4sat/data}/PassesRepo.kt | 23 +-- .../look4sat/data/PreferenceSource.kt | 38 +++++ .../rtbishop/look4sat/data/SatelliteRepo.kt | 24 +-- ...mittersForSat.kt => GetSatTransmitters.kt} | 4 +- .../look4sat/interactors/ImportDataFromWeb.kt | 10 -- ...FromStream.kt => UpdateEntriesFromFile.kt} | 4 +- .../interactors/UpdateEntriesFromWeb.kt | 17 ++ 28 files changed, 309 insertions(+), 577 deletions(-) delete mode 100644 app/src/main/java/com/rtbishop/look4sat/framework/DefaultLocationSource.kt create mode 100644 app/src/main/java/com/rtbishop/look4sat/framework/PreferencesProvider.kt delete mode 100644 app/src/main/java/com/rtbishop/look4sat/framework/PrefsManager.kt delete mode 100644 app/src/main/java/com/rtbishop/look4sat/framework/model/TleSource.kt delete mode 100644 app/src/main/java/com/rtbishop/look4sat/presentation/sourcesDialog/SourcesAdapter.kt delete mode 100644 app/src/main/java/com/rtbishop/look4sat/presentation/sourcesDialog/SourcesDialog.kt delete mode 100644 core/src/main/java/com/rtbishop/look4sat/data/LocationRepo.kt delete mode 100644 core/src/main/java/com/rtbishop/look4sat/data/LocationSource.kt rename {app/src/main/java/com/rtbishop/look4sat/utility => core/src/main/java/com/rtbishop/look4sat/data}/PassesRepo.kt (76%) create mode 100644 core/src/main/java/com/rtbishop/look4sat/data/PreferenceSource.kt rename core/src/main/java/com/rtbishop/look4sat/interactors/{GetTransmittersForSat.kt => GetSatTransmitters.kt} (65%) delete mode 100644 core/src/main/java/com/rtbishop/look4sat/interactors/ImportDataFromWeb.kt rename core/src/main/java/com/rtbishop/look4sat/interactors/{ImportDataFromStream.kt => UpdateEntriesFromFile.kt} (59%) create mode 100644 core/src/main/java/com/rtbishop/look4sat/interactors/UpdateEntriesFromWeb.kt diff --git a/app/src/main/java/com/rtbishop/look4sat/di/DataSourceModule.kt b/app/src/main/java/com/rtbishop/look4sat/di/DataSourceModule.kt index 5519414e..afbdda57 100644 --- a/app/src/main/java/com/rtbishop/look4sat/di/DataSourceModule.kt +++ b/app/src/main/java/com/rtbishop/look4sat/di/DataSourceModule.kt @@ -23,7 +23,7 @@ import android.location.LocationManager import androidx.room.Room import com.rtbishop.look4sat.data.* import com.rtbishop.look4sat.domain.predict4kotlin.QthConverter -import com.rtbishop.look4sat.framework.DefaultLocationSource +import com.rtbishop.look4sat.framework.PreferencesProvider import com.rtbishop.look4sat.framework.api.NetworkDataSource import com.rtbishop.look4sat.framework.api.SatelliteService import com.rtbishop.look4sat.framework.db.RoomConverters @@ -52,20 +52,21 @@ object DataSourceModule { @Provides @Singleton - fun provideLocationSource( + fun providePreferenceSource( + qthConverter: QthConverter, locationManager: LocationManager, preferences: SharedPreferences - ): LocationSource { - return DefaultLocationSource(locationManager, preferences) + ): PreferenceSource { + return PreferencesProvider(qthConverter, locationManager, preferences) } @Provides @Singleton - fun provideLocationRepo( - locationSource: LocationSource, - qthConverter: QthConverter - ): LocationRepo { - return LocationRepo(locationSource, qthConverter) + fun providePassesRepo( + preferenceSource: PreferenceSource, + @DefaultDispatcher defaultDispatcher: CoroutineDispatcher + ): PassesRepo { + return PassesRepo(preferenceSource, defaultDispatcher) } @Provides diff --git a/app/src/main/java/com/rtbishop/look4sat/di/InteractorsModule.kt b/app/src/main/java/com/rtbishop/look4sat/di/InteractorsModule.kt index 51a56d64..4bf0cd31 100644 --- a/app/src/main/java/com/rtbishop/look4sat/di/InteractorsModule.kt +++ b/app/src/main/java/com/rtbishop/look4sat/di/InteractorsModule.kt @@ -39,18 +39,18 @@ object InteractorsModule { } @Provides - fun provideGetTransmittersForSatUseCase(satelliteRepo: SatelliteRepo): GetTransmittersForSat { - return GetTransmittersForSat(satelliteRepo) + fun provideGetSatTransmittersUseCase(satelliteRepo: SatelliteRepo): GetSatTransmitters { + return GetSatTransmitters(satelliteRepo) } @Provides - fun provideImportDataFromStreamUseCase(satelliteRepo: SatelliteRepo): ImportDataFromStream { - return ImportDataFromStream(satelliteRepo) + fun provideUpdateEntriesFromFileUseCase(satelliteRepo: SatelliteRepo): UpdateEntriesFromFile { + return UpdateEntriesFromFile(satelliteRepo) } @Provides - fun provideImportDataFromWebUseCase(satelliteRepo: SatelliteRepo): ImportDataFromWeb { - return ImportDataFromWeb(satelliteRepo) + fun provideUpdateEntriesFromWebUseCase(satelliteRepo: SatelliteRepo): UpdateEntriesFromWeb { + return UpdateEntriesFromWeb(satelliteRepo) } @Provides diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/DefaultLocationSource.kt b/app/src/main/java/com/rtbishop/look4sat/framework/DefaultLocationSource.kt deleted file mode 100644 index e0b5b59a..00000000 --- a/app/src/main/java/com/rtbishop/look4sat/framework/DefaultLocationSource.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.rtbishop.look4sat.framework - -import android.content.SharedPreferences -import android.hardware.GeomagneticField -import android.location.LocationManager -import androidx.core.content.edit -import com.rtbishop.look4sat.data.LocationSource -import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition -import com.rtbishop.look4sat.utility.round -import javax.inject.Inject - -class DefaultLocationSource @Inject constructor( - private val locationManager: LocationManager, - private val preferences: SharedPreferences -) : LocationSource { - - companion object { - const val keyLatitude = "stationLat" - const val keyLongitude = "stationLon" - const val keyAltitude = "stationAlt" - const val keyPositionGPS = "setPositionGPS" - const val keyPositionQTH = "setPositionQTH" - } - - override fun getLastKnownLocation(): StationPosition? { - return try { - val location = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER) - if (location == null) null - else { - val latitude = location.latitude.round(4) - val longitude = location.longitude.round(4) - val altitude = location.altitude.round(1) - return StationPosition(latitude, longitude, altitude) - } - } catch (exception: SecurityException) { - null - } - } - - override fun getMagDeclination(position: StationPosition): Float { - val lat = position.latitude.toFloat() - val lon = position.longitude.toFloat() - val alt = position.altitude.toFloat() - return GeomagneticField(lat, lon, alt, System.currentTimeMillis()).declination - } - - override fun loadStationPosition(): StationPosition { - val defaultSP = "0.0" - val latitude = preferences.getString(keyLatitude, null) ?: defaultSP - val longitude = preferences.getString(keyLongitude, null) ?: defaultSP - val altitude = preferences.getString(keyAltitude, null) ?: defaultSP - return StationPosition(latitude.toDouble(), longitude.toDouble(), altitude.toDouble()) - } - - override fun saveStationPosition(position: StationPosition) { - preferences.edit { - putString(keyLatitude, position.latitude.toString()) - putString(keyLongitude, position.longitude.toString()) - putString(keyAltitude, position.altitude.toString()) - } - } -} diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/PreferencesProvider.kt b/app/src/main/java/com/rtbishop/look4sat/framework/PreferencesProvider.kt new file mode 100644 index 00000000..9e57bddb --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/framework/PreferencesProvider.kt @@ -0,0 +1,155 @@ +/* + * 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 + +import android.content.SharedPreferences +import android.hardware.GeomagneticField +import android.location.LocationManager +import androidx.core.content.edit +import com.rtbishop.look4sat.data.PreferenceSource +import com.rtbishop.look4sat.domain.predict4kotlin.QthConverter +import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition +import com.rtbishop.look4sat.utility.round +import javax.inject.Inject + +class PreferencesProvider @Inject constructor( + private val qthConverter: QthConverter, + private val locationManager: LocationManager, + private val preferences: SharedPreferences +) : PreferenceSource { + + companion object { + const val keyModes = "satModes" + const val keyCompass = "compass" + const val keyTextLabels = "shouldUseTextLabels" + const val keyTimeUTC = "timeUTC" + const val keyHoursAhead = "hoursAhead" + const val keyMinElevation = "minElevation" + const val keyIsFirstLaunch = "shouldShowSplash" + const val keyRotator = "isRotatorEnabled" + const val keyRotatorAddress = "rotatorAddress" + const val keyRotatorPort = "rotatorPort" + const val keyLatitude = "stationLat" + const val keyLongitude = "stationLon" + const val keyAltitude = "stationAlt" + const val keyPositionGPS = "setPositionGPS" + const val keyPositionQTH = "setPositionQTH" + } + + override fun positionToQTH(lat: Double, lon: Double): String? { + return qthConverter.positionToQTH(lat, lon) + } + + override fun loadStationPosition(): StationPosition { + val defaultSP = "0.0" + val latitude = preferences.getString(keyLatitude, null) ?: defaultSP + val longitude = preferences.getString(keyLongitude, null) ?: defaultSP + val altitude = preferences.getString(keyAltitude, null) ?: defaultSP + return StationPosition(latitude.toDouble(), longitude.toDouble(), altitude.toDouble()) + } + + override fun saveStationPosition(position: StationPosition) { + preferences.edit { + putString(keyLatitude, position.latitude.toString()) + putString(keyLongitude, position.longitude.toString()) + putString(keyAltitude, position.altitude.toString()) + } + } + + override fun updatePositionFromGPS(): Boolean { + return try { + val location = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER) + if (location == null) false + else { + val latitude = location.latitude.round(4) + val longitude = location.longitude.round(4) + val altitude = location.altitude.round(1) + val stationPosition = StationPosition(latitude, longitude, altitude) + saveStationPosition(stationPosition) + return true + } + } catch (exception: SecurityException) { + false + } + } + + override fun updatePositionFromQTH(qthString: String): Boolean { + val position = qthConverter.qthToPosition(qthString) ?: return false + val stationPosition = StationPosition(position.latitude, position.longitude, 0.0) + saveStationPosition(stationPosition) + return true + } + + override fun getMagDeclination(): Float { + val stationPosition = loadStationPosition() + val lat = stationPosition.latitude.toFloat() + val lon = stationPosition.longitude.toFloat() + val alt = stationPosition.altitude.toFloat() + return GeomagneticField(lat, lon, alt, System.currentTimeMillis()).declination + } + + override fun getHoursAhead(): Int { + return preferences.getInt(keyHoursAhead, 8) + } + + override fun getMinElevation(): Double { + return preferences.getInt(keyMinElevation, 16).toDouble() + } + + override fun shouldUseTextLabels(): Boolean { + return preferences.getBoolean(keyTextLabels, false) + } + + override fun shouldUseUTC(): Boolean { + return preferences.getBoolean(keyTimeUTC, false) + } + + override fun shouldUseCompass(): Boolean { + return preferences.getBoolean(keyCompass, true) + } + + override fun isFirstLaunch(): Boolean { + return preferences.getBoolean(keyIsFirstLaunch, true) + } + + override fun setFirstLaunchDone() { + preferences.edit { putBoolean(keyIsFirstLaunch, false) } + } + + override fun saveModesSelection(modes: List) { + val modesSet = modes.toSet() + preferences.edit { + putStringSet(keyModes, modesSet) + } + } + + override fun loadModesSelection(): List { + preferences.getStringSet(keyModes, setOf())?.let { modesSet -> + return modesSet.toList().sorted() + } + return emptyList() + } + + override fun getRotatorServer(): Pair? { + return if (preferences.getBoolean(keyRotator, false)) { + val address = preferences.getString(keyRotatorAddress, null) ?: "127.0.0.1" + val port = preferences.getString(keyRotatorPort, null) ?: "4096" + Pair(address, port.toInt()) + } else null + } +} diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/PrefsManager.kt b/app/src/main/java/com/rtbishop/look4sat/framework/PrefsManager.kt deleted file mode 100644 index 1e8a06af..00000000 --- a/app/src/main/java/com/rtbishop/look4sat/framework/PrefsManager.kt +++ /dev/null @@ -1,124 +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 - -import android.content.SharedPreferences -import androidx.core.content.edit -import com.rtbishop.look4sat.framework.model.TleSource -import com.squareup.moshi.Moshi -import com.squareup.moshi.Types -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class PrefsManager @Inject constructor(private val preferences: SharedPreferences, moshi: Moshi) { - - private val sourcesType = Types.newParameterizedType(List::class.java, TleSource::class.java) - private val sourcesAdapter = moshi.adapter>(sourcesType) - - companion object { - const val keySources = "sourcesListJson" - const val keyModes = "satModes" - const val keyCompass = "compass" - const val keyTextLabels = "shouldUseTextLabels" - const val keyTimeUTC = "timeUTC" - const val keyHoursAhead = "hoursAhead" - const val keyMinElevation = "minElevation" - const val keyIsFirstLaunch = "shouldShowSplash" - const val keyRotator = "isRotatorEnabled" - const val keyRotatorAddress = "rotatorAddress" - const val keyRotatorPort = "rotatorPort" - } - - fun getHoursAhead(): Int { - return preferences.getInt(keyHoursAhead, 8) - } - - fun getMinElevation(): Double { - return preferences.getInt(keyMinElevation, 16).toDouble() - } - - fun shouldUseTextLabels(): Boolean { - return preferences.getBoolean(keyTextLabels, false) - } - - fun shouldUseUTC(): Boolean { - return preferences.getBoolean(keyTimeUTC, false) - } - - fun shouldUseCompass(): Boolean { - return preferences.getBoolean(keyCompass, true) - } - - fun isFirstLaunch(): Boolean { - return preferences.getBoolean(keyIsFirstLaunch, true) - } - - fun setFirstLaunchDone() { - preferences.edit { putBoolean(keyIsFirstLaunch, false) } - } - - fun loadTleSources(): List { - return try { - val sourcesString = preferences.getString(keySources, String()) - if (sourcesString.isNullOrEmpty()) { - loadDefaultSources() - } else { - sourcesAdapter.fromJson(sourcesString) ?: loadDefaultSources() - } - } catch (exception: ClassCastException) { - loadDefaultSources() - } - } - - fun saveTleSources(sources: List) { - val sourcesJson = sourcesAdapter.toJson(sources) - preferences.edit { putString(keySources, sourcesJson) } - } - - fun loadDefaultSources(): List { - return listOf( - TleSource("https://celestrak.com/NORAD/elements/active.txt"), - TleSource("https://amsat.org/tle/current/nasabare.txt"), - TleSource("https://www.prismnet.com/~mmccants/tles/classfd.zip"), - TleSource("https://www.prismnet.com/~mmccants/tles/inttles.zip") - ) - } - - fun saveModesSelection(modes: List) { - val modesSet = modes.toSet() - preferences.edit { - putStringSet(keyModes, modesSet) - } - } - - fun loadModesSelection(): List { - preferences.getStringSet(keyModes, setOf())?.let { modesSet -> - return modesSet.toList().sorted() - } - return emptyList() - } - - fun getRotatorServer(): Pair? { - return if (preferences.getBoolean(keyRotator, false)) { - val address = preferences.getString(keyRotatorAddress, null) ?: "127.0.0.1" - val port = preferences.getString(keyRotatorPort, null) ?: "4096" - Pair(address, port.toInt()) - } else null - } -} diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/db/RoomDataSource.kt b/app/src/main/java/com/rtbishop/look4sat/framework/db/RoomDataSource.kt index 39dee5da..e3beda15 100644 --- a/app/src/main/java/com/rtbishop/look4sat/framework/db/RoomDataSource.kt +++ b/app/src/main/java/com/rtbishop/look4sat/framework/db/RoomDataSource.kt @@ -29,7 +29,7 @@ class RoomDataSource(private val satelliteDao: SatelliteDao) : LocalDataSource { satelliteDao.updateEntriesSelection(catNums, isSelected) } - override fun getTransmittersForSat(catNum: Int): Flow> { + override fun getSatTransmitters(catNum: Int): Flow> { return satelliteDao.getSatTransmitters(catNum) .map { satTransList -> DataMapper.satTransListToDomainTransList(satTransList) } } diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/model/TleSource.kt b/app/src/main/java/com/rtbishop/look4sat/framework/model/TleSource.kt deleted file mode 100644 index 5e4ee23c..00000000 --- a/app/src/main/java/com/rtbishop/look4sat/framework/model/TleSource.kt +++ /dev/null @@ -1,20 +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.model - -class TleSource(var url: String = String()) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/Look4SatActivity.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/Look4SatActivity.kt index 7a7b10ce..50b1e923 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/Look4SatActivity.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/Look4SatActivity.kt @@ -25,7 +25,7 @@ import androidx.navigation.fragment.NavHostFragment import androidx.navigation.ui.setupWithNavController import com.rtbishop.look4sat.R import com.rtbishop.look4sat.databinding.ActivityMainBinding -import com.rtbishop.look4sat.framework.PrefsManager +import com.rtbishop.look4sat.framework.PreferencesProvider import com.rtbishop.look4sat.utility.navigateSafe import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @@ -34,7 +34,7 @@ import javax.inject.Inject class Look4SatActivity : AppCompatActivity() { @Inject - lateinit var prefsManager: PrefsManager + lateinit var preferenceSource: PreferencesProvider @SuppressLint("SourceLockedOrientationActivity") override fun onCreate(savedInstanceState: Bundle?) { @@ -45,8 +45,8 @@ class Look4SatActivity : AppCompatActivity() { setContentView(binding.root) val navHost = supportFragmentManager.findFragmentById(R.id.nav_host) as NavHostFragment binding.navBottom.setupWithNavController(navHost.navController) - if (prefsManager.isFirstLaunch()) { - prefsManager.setFirstLaunchDone() + if (preferenceSource.isFirstLaunch()) { + preferenceSource.setFirstLaunchDone() navHost.navController.navigateSafe(R.id.nav_dialog_splash) } } 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 8f0c6e70..4b68b38e 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 @@ -22,18 +22,14 @@ import android.view.View import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels -import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.SimpleItemAnimator import com.google.android.material.snackbar.Snackbar import com.rtbishop.look4sat.R -import com.rtbishop.look4sat.framework.model.Result import com.rtbishop.look4sat.databinding.FragmentEntriesBinding import com.rtbishop.look4sat.domain.model.SatItem -import com.rtbishop.look4sat.framework.model.TleSource +import com.rtbishop.look4sat.framework.model.Result import com.rtbishop.look4sat.utility.RecyclerDivider -import com.rtbishop.look4sat.utility.getNavResult -import com.rtbishop.look4sat.utility.navigateSafe import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -42,7 +38,7 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) { private val viewModel: EntriesViewModel by viewModels() private val contentContract = ActivityResultContracts.GetContent() private val filePicker = registerForActivityResult(contentContract) { uri -> - uri?.let { viewModel.importSatDataFromFile(uri) } + uri?.let { viewModel.updateEntriesFromFile(uri) } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -62,9 +58,7 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) { (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false addItemDecoration(RecyclerDivider(R.drawable.rec_divider_light)) } - importWeb.setOnClickListener { - findNavController().navigateSafe(R.id.action_entries_to_sources) - } + importWeb.setOnClickListener { viewModel.updateEntriesFromWeb(null) } importFile.setOnClickListener { filePicker.launch("*/*") } selectMode.setOnClickListener { viewModel.createModesDialog(requireContext()).show() } selectAll.setOnClickListener { viewModel.selectCurrentItems() } @@ -73,9 +67,6 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) { viewModel.satData.observe(viewLifecycleOwner, { satData -> handleSatData(satData, binding, entriesAdapter) }) - getNavResult>(R.id.nav_entries, "sources") { navResult -> - handleNavResult(navResult) - } } private fun handleSatData( @@ -97,15 +88,11 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) { is Result.Error -> { binding.entriesProgress.visibility = View.INVISIBLE binding.entriesRecycler.visibility = View.VISIBLE - Snackbar.make(requireView(), R.string.entries_update_error, Snackbar.LENGTH_SHORT) - .setAnchorView(R.id.nav_bottom).show() + val errorMsg = getString(R.string.entries_update_error) + Snackbar.make(requireView(), errorMsg, Snackbar.LENGTH_SHORT).apply { + setAnchorView(R.id.nav_bottom) + }.show() } } } - - private fun handleNavResult(result: List) { - result.map { sourceUrl -> TleSource(sourceUrl) }.let { sources -> - viewModel.importSatDataFromSources(sources) - } - } } 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 c71bc397..84b9f2aa 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 @@ -26,32 +26,29 @@ import androidx.lifecycle.* import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.rtbishop.look4sat.R import com.rtbishop.look4sat.domain.model.SatItem +import com.rtbishop.look4sat.framework.PreferencesProvider import com.rtbishop.look4sat.framework.model.Result -import com.rtbishop.look4sat.framework.model.TleSource import com.rtbishop.look4sat.interactors.GetSatItems -import com.rtbishop.look4sat.interactors.ImportDataFromStream -import com.rtbishop.look4sat.interactors.ImportDataFromWeb +import com.rtbishop.look4sat.interactors.UpdateEntriesFromFile +import com.rtbishop.look4sat.interactors.UpdateEntriesFromWeb import com.rtbishop.look4sat.interactors.UpdateEntriesSelection -import com.rtbishop.look4sat.framework.PrefsManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch -import timber.log.Timber import java.util.* import javax.inject.Inject -import kotlin.system.measureTimeMillis @HiltViewModel class EntriesViewModel @Inject constructor( - private val prefsManager: PrefsManager, + private val preferenceSource: PreferencesProvider, private val resolver: ContentResolver, private val getSatItems: GetSatItems, - private val importDataFromStream: ImportDataFromStream, - private val importDataFromWeb: ImportDataFromWeb, + private val updateEntriesFromFile: UpdateEntriesFromFile, + private val updateEntriesFromWeb: UpdateEntriesFromWeb, private val updateEntriesSelection: UpdateEntriesSelection, ) : ViewModel(), EntriesAdapter.EntriesClickListener, SearchView.OnQueryTextListener { - private val transModes = MutableLiveData(prefsManager.loadModesSelection()) + private val transModes = MutableLiveData(preferenceSource.loadModesSelection()) private val currentQuery = MutableLiveData(String()) private val itemsWithModes = transModes.switchMap { modes -> liveData { getSatItems().collect { emit(filterByModes(it, modes)) } } @@ -65,32 +62,22 @@ class EntriesViewModel @Inject constructor( private var shouldSelectAll = true val satData: LiveData>> = _satData - fun importSatDataFromFile(uri: Uri) { + fun updateEntriesFromFile(uri: Uri) { viewModelScope.launch { _satData.value = Result.InProgress runCatching { - resolver.openInputStream(uri)?.use { stream -> - importDataFromStream(stream) - } + resolver.openInputStream(uri)?.use { stream -> updateEntriesFromFile(stream) } }.onFailure { _satData.value = Result.Error(it) } } } - fun importSatDataFromSources(sources: List) { + fun updateEntriesFromWeb(sources: List?) { viewModelScope.launch { _satData.value = Result.InProgress - val satSources = if (sources.isNotEmpty()) sources - else prefsManager.loadDefaultSources() - val updateMillis = measureTimeMillis { - try { - prefsManager.saveTleSources(satSources) - importDataFromWeb(satSources.map { it.url }) - } catch (exception: Exception) { - _satData.value = Result.Error(exception) - Timber.d(exception) - } - } - Timber.d("Update from WEB took $updateMillis ms") + runCatching { + if (sources == null) updateEntriesFromWeb() + else updateEntriesFromWeb(sources) + }.onFailure { _satData.value = Result.Error(it) } } } @@ -111,7 +98,7 @@ class EntriesViewModel @Inject constructor( "PSK", "PSK31", "PSK63", "QPSK", "QPSK31", "QPSK63", "SSTV", "USB", "WSJT" ) val savedModes = BooleanArray(modes.size) - val selectedModes = prefsManager.loadModesSelection().toMutableList() + val selectedModes = preferenceSource.loadModesSelection().toMutableList() selectedModes.forEach { savedModes[modes.indexOf(it)] = true } val dialogBuilder = MaterialAlertDialogBuilder(context).apply { setTitle(context.getString(R.string.modes_title)) @@ -123,7 +110,7 @@ class EntriesViewModel @Inject constructor( } setPositiveButton(context.getString(android.R.string.ok)) { _, _ -> transModes.value = selectedModes - prefsManager.saveModesSelection(selectedModes) + preferenceSource.saveModesSelection(selectedModes) } setNeutralButton(context.getString(android.R.string.cancel)) { dialog, _ -> dialog.dismiss() 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 cdec0fbb..b3da0947 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,14 +18,13 @@ package com.rtbishop.look4sat.presentation.mapScreen import androidx.lifecycle.* -import com.rtbishop.look4sat.data.LocationRepo +import com.rtbishop.look4sat.data.PreferenceSource import com.rtbishop.look4sat.di.DefaultDispatcher import com.rtbishop.look4sat.domain.predict4kotlin.Position import com.rtbishop.look4sat.domain.predict4kotlin.Satellite import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition import com.rtbishop.look4sat.framework.model.SatData import com.rtbishop.look4sat.interactors.GetSelectedSatellites -import com.rtbishop.look4sat.framework.PrefsManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.* import java.util.* @@ -38,12 +37,11 @@ import kotlin.math.sqrt @HiltViewModel class MapViewModel @Inject constructor( private val getSelectedSatellites: GetSelectedSatellites, - private val prefsManager: PrefsManager, - private val locationRepo: LocationRepo, + private val preferenceSource: PreferenceSource, @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher ) : ViewModel() { - private val gsp = locationRepo.getStationPosition() + private val gsp = preferenceSource.loadStationPosition() private var dataUpdateJob: Job? = null private var allSatList = listOf() private lateinit var selectedSat: Satellite @@ -78,7 +76,7 @@ class MapViewModel @Inject constructor( } fun shouldUseTextLabels(): Boolean { - return prefsManager.shouldUseTextLabels() + return preferenceSource.shouldUseTextLabels() } fun scrollSelection(decrement: Boolean) { @@ -172,7 +170,8 @@ class MapViewModel @Inject constructor( val osmLat = getOsmLat(Math.toDegrees(satPos.latitude)) val osmLon = getOsmLon(Math.toDegrees(satPos.longitude)) val osmPos = Position(osmLat, osmLon) - val qthLoc = locationRepo.positionToQTH(osmPos.latitude, osmPos.longitude) ?: "-- --" + val qthLoc = + preferenceSource.positionToQTH(osmPos.latitude, osmPos.longitude) ?: "-- --" val velocity = getOrbitalVelocity(satPos.altitude) val satData = SatData( sat, sat.tle.catnum, sat.tle.name, satPos.range, 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 b34fe443..6135a603 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 @@ -22,10 +22,10 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.rtbishop.look4sat.framework.model.Result -import com.rtbishop.look4sat.utility.PassesRepo +import com.rtbishop.look4sat.data.PassesRepo import com.rtbishop.look4sat.interactors.GetSelectedSatellites import com.rtbishop.look4sat.domain.predict4kotlin.SatPass -import com.rtbishop.look4sat.framework.PrefsManager +import com.rtbishop.look4sat.framework.PreferencesProvider import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.* import kotlinx.coroutines.flow.collect @@ -35,7 +35,7 @@ import javax.inject.Inject class PassesViewModel @Inject constructor( private val getSelectedSatellites: GetSelectedSatellites, private val passesRepo: PassesRepo, - private val prefsManager: PrefsManager + private val preferenceSource: PreferencesProvider ) : ViewModel() { private val _passes = MutableLiveData>>(Result.InProgress) @@ -64,7 +64,7 @@ class PassesViewModel @Inject constructor( } fun shouldUseUTC(): Boolean { - return prefsManager.shouldUseUTC() + return preferenceSource.shouldUseUTC() } private suspend fun tickPasses(passes: List) = withContext(Dispatchers.Default) { diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/polarScreen/PolarViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/polarScreen/PolarViewModel.kt index 3ff3b2c4..ac3e6700 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/polarScreen/PolarViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/polarScreen/PolarViewModel.kt @@ -18,14 +18,13 @@ package com.rtbishop.look4sat.presentation.polarScreen import androidx.lifecycle.* -import com.rtbishop.look4sat.data.LocationRepo +import com.rtbishop.look4sat.data.PreferenceSource import com.rtbishop.look4sat.di.IoDispatcher import com.rtbishop.look4sat.domain.model.SatTrans import com.rtbishop.look4sat.domain.predict4kotlin.SatPass -import com.rtbishop.look4sat.interactors.GetTransmittersForSat +import com.rtbishop.look4sat.interactors.GetSatTransmitters import com.rtbishop.look4sat.framework.OrientationProvider -import com.rtbishop.look4sat.utility.PassesRepo -import com.rtbishop.look4sat.framework.PrefsManager +import com.rtbishop.look4sat.data.PassesRepo import com.rtbishop.look4sat.utility.round import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.* @@ -37,11 +36,10 @@ import javax.inject.Inject @HiltViewModel class PolarViewModel @Inject constructor( - private val locationRepo: LocationRepo, private val orientationProvider: OrientationProvider, - private val prefsManager: PrefsManager, + private val preferenceSource: PreferenceSource, private val passesRepo: PassesRepo, - private val getTransmittersForSat: GetTransmittersForSat, + private val getSatTransmitters: GetSatTransmitters, @IoDispatcher private val ioDispatcher: CoroutineDispatcher ) : ViewModel(), OrientationProvider.OrientationListener { @@ -62,20 +60,20 @@ class PolarViewModel @Inject constructor( } fun enableSensor() { - if (prefsManager.shouldUseCompass()) orientationProvider.startListening(this) + if (preferenceSource.shouldUseCompass()) orientationProvider.startListening(this) } fun disableSensor() { - if (prefsManager.shouldUseCompass()) orientationProvider.stopListening() + if (preferenceSource.shouldUseCompass()) orientationProvider.stopListening() } override fun onOrientationChanged(azimuth: Float, pitch: Float, roll: Float) { - _orientation.value = Triple(azimuth + locationRepo.getMagDeclination(), pitch, roll) + _orientation.value = Triple(azimuth + preferenceSource.getMagDeclination(), pitch, roll) } private fun initRotatorControl(satPass: SatPass) { viewModelScope.launch { - val rotatorPrefs = prefsManager.getRotatorServer() + val rotatorPrefs = preferenceSource.getRotatorServer() if (rotatorPrefs != null) { runCatching { withContext(ioDispatcher) { @@ -99,7 +97,7 @@ class PolarViewModel @Inject constructor( private fun processTransmitters(satPass: SatPass) { viewModelScope.launch { - getTransmittersForSat(satPass.catNum).collect { transList -> + getSatTransmitters(satPass.catNum).collect { transList -> while (isActive) { val timeNow = Date() val copiedList = transList.map { it.copy() } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/prefsScreen/PrefsFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/prefsScreen/PrefsFragment.kt index d431f1d1..43b7411d 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/prefsScreen/PrefsFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/prefsScreen/PrefsFragment.kt @@ -30,9 +30,8 @@ import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import com.google.android.material.snackbar.Snackbar import com.rtbishop.look4sat.R -import com.rtbishop.look4sat.data.LocationRepo -import com.rtbishop.look4sat.framework.DefaultLocationSource -import com.rtbishop.look4sat.framework.PrefsManager +import com.rtbishop.look4sat.data.PreferenceSource +import com.rtbishop.look4sat.framework.PreferencesProvider import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @@ -40,10 +39,7 @@ import javax.inject.Inject class PrefsFragment : PreferenceFragmentCompat() { @Inject - lateinit var locationRepo: LocationRepo - - @Inject - lateinit var prefsManager: PrefsManager + lateinit var preferenceSource: PreferenceSource private val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> @@ -61,20 +57,20 @@ class PrefsFragment : PreferenceFragmentCompat() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - findPreference(DefaultLocationSource.keyPositionGPS)?.apply { + findPreference(PreferencesProvider.keyPositionGPS)?.apply { setOnPreferenceClickListener { updatePositionFromGPS() return@setOnPreferenceClickListener true } } - findPreference(DefaultLocationSource.keyPositionQTH)?.apply { + findPreference(PreferencesProvider.keyPositionQTH)?.apply { setOnPreferenceChangeListener { _, newValue -> updatePositionFromQth(newValue.toString()) } } - findPreference(PrefsManager.keyRotatorAddress)?.apply { + findPreference(PreferencesProvider.keyRotatorAddress)?.apply { setOnPreferenceChangeListener { _, newValue -> if (Patterns.IP_ADDRESS.matcher(newValue.toString()).matches()) { return@setOnPreferenceChangeListener true @@ -85,7 +81,7 @@ class PrefsFragment : PreferenceFragmentCompat() { } } - findPreference(PrefsManager.keyRotatorPort)?.apply { + findPreference(PreferencesProvider.keyRotatorPort)?.apply { setOnBindEditTextListener { it.inputType = InputType.TYPE_CLASS_NUMBER } setOnPreferenceChangeListener { _, newValue -> val portValue = newValue.toString() @@ -100,7 +96,7 @@ class PrefsFragment : PreferenceFragmentCompat() { } private fun updatePositionFromQth(qthString: String): Boolean { - return if (locationRepo.updatePositionFromQTH(qthString)) { + return if (preferenceSource.updatePositionFromQTH(qthString)) { showSnack(getString(R.string.pref_pos_success)) true } else { @@ -113,7 +109,7 @@ class PrefsFragment : PreferenceFragmentCompat() { val locPermString = Manifest.permission.ACCESS_FINE_LOCATION val locPermResult = ContextCompat.checkSelfPermission(requireContext(), locPermString) if (locPermResult == PackageManager.PERMISSION_GRANTED) { - if (locationRepo.updatePositionFromGPS()) { + if (preferenceSource.updatePositionFromGPS()) { showSnack(getString(R.string.pref_pos_success)) } else showSnack(getString(R.string.pref_pos_gps_null)) } else requestPermissionLauncher.launch(locPermString) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/sourcesDialog/SourcesAdapter.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/sourcesDialog/SourcesAdapter.kt deleted file mode 100644 index 23d5eb44..00000000 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/sourcesDialog/SourcesAdapter.kt +++ /dev/null @@ -1,70 +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.sourcesDialog - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.core.widget.doOnTextChanged -import androidx.recyclerview.widget.RecyclerView -import com.rtbishop.look4sat.databinding.ItemTleSourceBinding -import com.rtbishop.look4sat.framework.model.TleSource - -class SourcesAdapter(private val sources: MutableList = mutableListOf()) : - RecyclerView.Adapter() { - - fun getSources(): List { - return sources.filter { it.url.contains("https://") } - } - - fun setSources(list: List) { - sources.clear() - sources.addAll(list) - } - - fun addSource() { - sources.add(TleSource()) - notifyItemInserted(itemCount - 1) - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TleSourceHolder { - val binding = ItemTleSourceBinding - .inflate(LayoutInflater.from(parent.context), parent, false) - return TleSourceHolder(binding) - } - - override fun onBindViewHolder(holder: TleSourceHolder, position: Int) { - holder.bind(sources[position]) - } - - override fun getItemCount(): Int { - return sources.size - } - - inner class TleSourceHolder(private val binding: ItemTleSourceBinding) : - RecyclerView.ViewHolder(binding.root) { - - fun bind(source: TleSource) { - binding.tleSourceUrl.setText(source.url) - binding.tleSourceUrl.doOnTextChanged { text, _, _, _ -> source.url = text.toString() } - binding.tleSourceInputLayout.setEndIconOnClickListener { - sources.remove(source) - notifyItemRemoved(adapterPosition) - } - } - } -} diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/sourcesDialog/SourcesDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/sourcesDialog/SourcesDialog.kt deleted file mode 100644 index 5bfe5b47..00000000 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/sourcesDialog/SourcesDialog.kt +++ /dev/null @@ -1,66 +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.sourcesDialog - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.view.WindowManager -import androidx.appcompat.app.AppCompatDialogFragment -import androidx.recyclerview.widget.LinearLayoutManager -import com.rtbishop.look4sat.R -import com.rtbishop.look4sat.framework.PrefsManager -import com.rtbishop.look4sat.databinding.DialogSourcesBinding -import com.rtbishop.look4sat.utility.setNavResult -import dagger.hilt.android.AndroidEntryPoint -import javax.inject.Inject - -@AndroidEntryPoint -class SourcesDialog : AppCompatDialogFragment() { - - @Inject - lateinit var prefsManager: PrefsManager - - override fun onCreateView(inflater: LayoutInflater, group: ViewGroup?, state: Bundle?): View? { - return inflater.inflate(R.layout.dialog_sources, group, false) - } - - override fun onViewCreated(view: View, state: Bundle?) { - super.onViewCreated(view, state) - val sourcesAdapter = SourcesAdapter().apply { setSources(prefsManager.loadTleSources()) } - DialogSourcesBinding.bind(view).apply { - dialog?.window?.setLayout( - WindowManager.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.WRAP_CONTENT - ) - sourcesRecycler.apply { - adapter = sourcesAdapter - layoutManager = LinearLayoutManager(requireContext()) - } - sourceBtnAdd.setOnClickListener { - sourcesAdapter.addSource() - } - sourcesBtnPos.setOnClickListener { - setNavResult("sources", sourcesAdapter.getSources().map { it.url }) - dismiss() - } - sourcesBtnNeg.setOnClickListener { dismiss() } - } - } -} diff --git a/app/src/main/java/com/rtbishop/look4sat/utility/Extensions.kt b/app/src/main/java/com/rtbishop/look4sat/utility/Extensions.kt index 92c4e2c2..799ab76c 100644 --- a/app/src/main/java/com/rtbishop/look4sat/utility/Extensions.kt +++ b/app/src/main/java/com/rtbishop/look4sat/utility/Extensions.kt @@ -19,13 +19,9 @@ package com.rtbishop.look4sat.utility import android.os.Bundle import androidx.annotation.IdRes -import androidx.fragment.app.Fragment -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver import androidx.navigation.NavController import androidx.navigation.NavOptions import androidx.navigation.Navigator -import androidx.navigation.fragment.findNavController import java.util.concurrent.TimeUnit fun Long.toTimerString(): String { @@ -53,26 +49,3 @@ fun NavController.navigateSafe( navigate(resId, args, navOptions, navExtras) } } - -fun Fragment.setNavResult(key: String, value: T) { - findNavController().previousBackStackEntry?.savedStateHandle?.set(key, value) -} - -fun Fragment.getNavResult(@IdRes id: Int, key: String, onResult: (result: T) -> Unit) { - val navBackStackEntry = findNavController().getBackStackEntry(id) - val observer = LifecycleEventObserver { _, event -> - if (event == Lifecycle.Event.ON_RESUME - && navBackStackEntry.savedStateHandle.contains(key) - ) { - val result = navBackStackEntry.savedStateHandle.get(key) - result?.let(onResult) - navBackStackEntry.savedStateHandle.remove(key) - } - } - navBackStackEntry.lifecycle.addObserver(observer) - viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event -> - if (event == Lifecycle.Event.ON_DESTROY) { - navBackStackEntry.lifecycle.removeObserver(observer) - } - }) -} diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index 11359bee..d5c281e3 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -16,13 +16,6 @@ app:exitAnim="@anim/nav_default_exit_anim" app:popEnterAnim="@anim/nav_default_pop_enter_anim" app:popExitAnim="@anim/nav_default_pop_exit_anim" /> - - > + fun getSatTransmitters(catNum: Int): Flow> + suspend fun getSelectedSatellites(): List suspend fun updateEntries(entries: List) suspend fun updateEntriesSelection(catNums: List, isSelected: Boolean) - fun getTransmittersForSat(catNum: Int): Flow> - suspend fun updateTransmitters(satelliteTrans: List) } diff --git a/core/src/main/java/com/rtbishop/look4sat/data/LocationRepo.kt b/core/src/main/java/com/rtbishop/look4sat/data/LocationRepo.kt deleted file mode 100644 index 92a6328a..00000000 --- a/core/src/main/java/com/rtbishop/look4sat/data/LocationRepo.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.rtbishop.look4sat.data - -import com.rtbishop.look4sat.domain.predict4kotlin.QthConverter -import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition - -class LocationRepo( - private val locationSource: LocationSource, - private val qthConverter: QthConverter -) { - - fun getStationPosition(): StationPosition { - return locationSource.loadStationPosition() - } - - fun getMagDeclination(): Float { - return locationSource.getMagDeclination(getStationPosition()) - } - - fun positionToQTH(lat: Double, lon: Double): String? { - return qthConverter.positionToQTH(lat, lon) - } - - fun updatePositionFromGPS(): Boolean { - val stationPosition = locationSource.getLastKnownLocation() ?: return false - locationSource.saveStationPosition(stationPosition) - return true - } - - fun updatePositionFromQTH(qthString: String): Boolean { - val position = qthConverter.qthToPosition(qthString) ?: return false - val stationPosition = StationPosition(position.latitude, position.longitude, 0.0) - locationSource.saveStationPosition(stationPosition) - return true - } -} diff --git a/core/src/main/java/com/rtbishop/look4sat/data/LocationSource.kt b/core/src/main/java/com/rtbishop/look4sat/data/LocationSource.kt deleted file mode 100644 index 0e14be6f..00000000 --- a/core/src/main/java/com/rtbishop/look4sat/data/LocationSource.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.rtbishop.look4sat.data - -import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition - -interface LocationSource { - - fun getLastKnownLocation(): StationPosition? - - fun getMagDeclination(position: StationPosition): Float - - fun loadStationPosition(): StationPosition - - fun saveStationPosition(position: StationPosition) -} \ No newline at end of file diff --git a/app/src/main/java/com/rtbishop/look4sat/utility/PassesRepo.kt b/core/src/main/java/com/rtbishop/look4sat/data/PassesRepo.kt similarity index 76% rename from app/src/main/java/com/rtbishop/look4sat/utility/PassesRepo.kt rename to core/src/main/java/com/rtbishop/look4sat/data/PassesRepo.kt index 3dc46f3e..23de9cf7 100644 --- a/app/src/main/java/com/rtbishop/look4sat/utility/PassesRepo.kt +++ b/core/src/main/java/com/rtbishop/look4sat/data/PassesRepo.kt @@ -15,26 +15,19 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.rtbishop.look4sat.utility +package com.rtbishop.look4sat.data -import com.rtbishop.look4sat.data.LocationRepo -import com.rtbishop.look4sat.di.DefaultDispatcher import com.rtbishop.look4sat.domain.predict4kotlin.SatPass import com.rtbishop.look4sat.domain.predict4kotlin.Satellite -import com.rtbishop.look4sat.framework.PrefsManager import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.withContext import java.util.* -import javax.inject.Inject -import javax.inject.Singleton -@Singleton -class PassesRepo @Inject constructor( - private val locationRepo: LocationRepo, - private val prefsManager: PrefsManager, - @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher +class PassesRepo( + private val preferenceSource: PreferenceSource, + private val defaultDispatcher: CoroutineDispatcher ) { private val _passes = MutableSharedFlow>(replay = 1) private var selectedSatellites = emptyList() @@ -64,15 +57,15 @@ class PassesRepo @Inject constructor( } private fun getPasses(satellite: Satellite, refDate: Date): List { - val predictor = satellite.getPredictor(locationRepo.getStationPosition()) - return predictor.getPasses(refDate, prefsManager.getHoursAhead(), true) + val predictor = satellite.getPredictor(preferenceSource.loadStationPosition()) + return predictor.getPasses(refDate, preferenceSource.getHoursAhead(), true) } private fun filterPasses(passes: List, refDate: Date): List { - val timeFuture = Date(refDate.time + (prefsManager.getHoursAhead() * 3600 * 1000)) + val timeFuture = Date(refDate.time + (preferenceSource.getHoursAhead() * 3600 * 1000)) return passes.filter { it.losDate.after(refDate) } .filter { it.aosDate.before(timeFuture) } - .filter { it.maxElevation > prefsManager.getMinElevation() } + .filter { it.maxElevation > preferenceSource.getMinElevation() } .sortedBy { it.aosDate } } } diff --git a/core/src/main/java/com/rtbishop/look4sat/data/PreferenceSource.kt b/core/src/main/java/com/rtbishop/look4sat/data/PreferenceSource.kt new file mode 100644 index 00000000..879cf7db --- /dev/null +++ b/core/src/main/java/com/rtbishop/look4sat/data/PreferenceSource.kt @@ -0,0 +1,38 @@ +package com.rtbishop.look4sat.data + +import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition + +interface PreferenceSource { + + fun positionToQTH(lat: Double, lon: Double): String? + + fun loadStationPosition(): StationPosition + + fun saveStationPosition(position: StationPosition) + + fun updatePositionFromGPS(): Boolean + + fun updatePositionFromQTH(qthString: String): Boolean + + fun getMagDeclination(): Float + + fun getHoursAhead(): Int + + fun getMinElevation(): Double + + fun shouldUseTextLabels(): Boolean + + fun shouldUseUTC(): Boolean + + fun shouldUseCompass(): Boolean + + fun isFirstLaunch(): Boolean + + fun setFirstLaunchDone() + + fun saveModesSelection(modes: List) + + fun loadModesSelection(): List + + fun getRotatorServer(): Pair? +} diff --git a/core/src/main/java/com/rtbishop/look4sat/data/SatelliteRepo.kt b/core/src/main/java/com/rtbishop/look4sat/data/SatelliteRepo.kt index 9ea3e267..bfa95dd0 100644 --- a/core/src/main/java/com/rtbishop/look4sat/data/SatelliteRepo.kt +++ b/core/src/main/java/com/rtbishop/look4sat/data/SatelliteRepo.kt @@ -22,24 +22,23 @@ class SatelliteRepo( return localSource.getSatItems() } - fun getTransmittersForSat(catNum: Int): Flow> { - return localSource.getTransmittersForSat(catNum) + fun getSatTransmitters(catNum: Int): Flow> { + return localSource.getSatTransmitters(catNum) } suspend fun getSelectedSatellites(): List { return localSource.getSelectedSatellites() } - suspend fun importDataFromStream(stream: InputStream) = withContext(ioDispatcher) { - val importedEntries = Satellite.importElements(stream).map { tle -> SatEntry(tle) } - localSource.updateEntries(importedEntries) + suspend fun updateEntriesFromFile(stream: InputStream) = withContext(ioDispatcher) { + localSource.updateEntries(importSatEntries(stream)) } - suspend fun importDataFromWeb(sources: List) { + suspend fun updateEntriesFromWeb(sources: List) { coroutineScope { launch(ioDispatcher) { - val importedEntries = mutableListOf() val streams = mutableListOf() + val entries = mutableListOf() sources.forEach { source -> remoteSource.fetchDataStream(source)?.let { stream -> if (source.contains(".zip", true)) { @@ -50,11 +49,8 @@ class SatelliteRepo( } } } - streams.forEach { stream -> - val entries = Satellite.importElements(stream).map { tle -> SatEntry(tle) } - importedEntries.addAll(entries) - } - localSource.updateEntries(importedEntries) + streams.forEach { stream -> entries.addAll(importSatEntries(stream)) } + localSource.updateEntries(entries) } launch(ioDispatcher) { val transmitters = remoteSource.fetchTransmitters().filter { it.isAlive } @@ -66,4 +62,8 @@ class SatelliteRepo( suspend fun updateEntriesSelection(catNums: List, isSelected: Boolean) { localSource.updateEntriesSelection(catNums, isSelected) } + + private fun importSatEntries(stream: InputStream): List { + return Satellite.importElements(stream).map { tle -> SatEntry(tle) } + } } diff --git a/core/src/main/java/com/rtbishop/look4sat/interactors/GetTransmittersForSat.kt b/core/src/main/java/com/rtbishop/look4sat/interactors/GetSatTransmitters.kt similarity index 65% rename from core/src/main/java/com/rtbishop/look4sat/interactors/GetTransmittersForSat.kt rename to core/src/main/java/com/rtbishop/look4sat/interactors/GetSatTransmitters.kt index 80373fad..79115ea0 100644 --- a/core/src/main/java/com/rtbishop/look4sat/interactors/GetTransmittersForSat.kt +++ b/core/src/main/java/com/rtbishop/look4sat/interactors/GetSatTransmitters.kt @@ -4,9 +4,9 @@ import com.rtbishop.look4sat.data.SatelliteRepo import com.rtbishop.look4sat.domain.model.SatTrans import kotlinx.coroutines.flow.Flow -class GetTransmittersForSat(private val satelliteRepo: SatelliteRepo) { +class GetSatTransmitters(private val satelliteRepo: SatelliteRepo) { operator fun invoke(catNum: Int): Flow> { - return satelliteRepo.getTransmittersForSat(catNum) + return satelliteRepo.getSatTransmitters(catNum) } } diff --git a/core/src/main/java/com/rtbishop/look4sat/interactors/ImportDataFromWeb.kt b/core/src/main/java/com/rtbishop/look4sat/interactors/ImportDataFromWeb.kt deleted file mode 100644 index b61ac5f6..00000000 --- a/core/src/main/java/com/rtbishop/look4sat/interactors/ImportDataFromWeb.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.rtbishop.look4sat.interactors - -import com.rtbishop.look4sat.data.SatelliteRepo - -class ImportDataFromWeb(private val satelliteRepo: SatelliteRepo) { - - suspend operator fun invoke(sources: List) { - satelliteRepo.importDataFromWeb(sources) - } -} diff --git a/core/src/main/java/com/rtbishop/look4sat/interactors/ImportDataFromStream.kt b/core/src/main/java/com/rtbishop/look4sat/interactors/UpdateEntriesFromFile.kt similarity index 59% rename from core/src/main/java/com/rtbishop/look4sat/interactors/ImportDataFromStream.kt rename to core/src/main/java/com/rtbishop/look4sat/interactors/UpdateEntriesFromFile.kt index 19a203f7..47f8413b 100644 --- a/core/src/main/java/com/rtbishop/look4sat/interactors/ImportDataFromStream.kt +++ b/core/src/main/java/com/rtbishop/look4sat/interactors/UpdateEntriesFromFile.kt @@ -3,9 +3,9 @@ package com.rtbishop.look4sat.interactors import com.rtbishop.look4sat.data.SatelliteRepo import java.io.InputStream -class ImportDataFromStream(private val satelliteRepo: SatelliteRepo) { +class UpdateEntriesFromFile(private val satelliteRepo: SatelliteRepo) { suspend operator fun invoke(stream: InputStream) { - satelliteRepo.importDataFromStream(stream) + satelliteRepo.updateEntriesFromFile(stream) } } diff --git a/core/src/main/java/com/rtbishop/look4sat/interactors/UpdateEntriesFromWeb.kt b/core/src/main/java/com/rtbishop/look4sat/interactors/UpdateEntriesFromWeb.kt new file mode 100644 index 00000000..5f94ef30 --- /dev/null +++ b/core/src/main/java/com/rtbishop/look4sat/interactors/UpdateEntriesFromWeb.kt @@ -0,0 +1,17 @@ +package com.rtbishop.look4sat.interactors + +import com.rtbishop.look4sat.data.SatelliteRepo + +class UpdateEntriesFromWeb(private val satelliteRepo: SatelliteRepo) { + + private val defaultSources = listOf( + "https://celestrak.com/NORAD/elements/active.txt", + "https://amsat.org/tle/current/nasabare.txt", + "https://www.prismnet.com/~mmccants/tles/classfd.zip", + "https://www.prismnet.com/~mmccants/tles/inttles.zip" + ) + + suspend operator fun invoke(sources: List = defaultSources) { + satelliteRepo.updateEntriesFromWeb(sources) + } +}