Simplified packages and classes structure
This commit is contained in:
1 parent
208c587ddf
commit
f6fcd21404
34 files changed
+412
-564
No files matched your search
@@ -33,13 +33,13 @@ class MainApplication : Application() {
|
||||
}
|
||||
|
||||
private fun checkAutoUpdate() {
|
||||
val settingsRepository = container.settingsRepository
|
||||
if (settingsRepository.isUpdateEnabled()) {
|
||||
val timeDelta = System.currentTimeMillis() - settingsRepository.getLastUpdateTime()
|
||||
val settingsRepo = container.settingsRepo
|
||||
if (settingsRepo.isUpdateEnabled()) {
|
||||
val timeDelta = System.currentTimeMillis() - settingsRepo.getLastUpdateTime()
|
||||
if (timeDelta > 172800000) { // 48 hours in ms
|
||||
val sdf = SimpleDateFormat("d MMM yyyy - HH:mm:ss", Locale.getDefault())
|
||||
println("Started periodic data update on ${sdf.format(Date())}")
|
||||
container.dataRepository.updateFromWeb()
|
||||
container.databaseRepo.updateFromWeb()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,23 +7,22 @@ import android.hardware.SensorManager
|
||||
import android.location.LocationManager
|
||||
import androidx.room.Room
|
||||
import com.rtbishop.look4sat.data.DataParser
|
||||
import com.rtbishop.look4sat.data.DataRepository
|
||||
import com.rtbishop.look4sat.data.SatelliteRepository
|
||||
import com.rtbishop.look4sat.data.SelectionRepository
|
||||
import com.rtbishop.look4sat.domain.IDataRepository
|
||||
import com.rtbishop.look4sat.domain.ISatelliteRepository
|
||||
import com.rtbishop.look4sat.domain.ISensorRepository
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepository
|
||||
import com.rtbishop.look4sat.data.DatabaseRepo
|
||||
import com.rtbishop.look4sat.data.SatelliteRepo
|
||||
import com.rtbishop.look4sat.data.SelectionRepo
|
||||
import com.rtbishop.look4sat.domain.IDatabaseRepo
|
||||
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
||||
import com.rtbishop.look4sat.domain.ISelectionRepo
|
||||
import com.rtbishop.look4sat.domain.ISensorsRepo
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepo
|
||||
import com.rtbishop.look4sat.framework.BluetoothReporter
|
||||
import com.rtbishop.look4sat.framework.NetworkReporter
|
||||
import com.rtbishop.look4sat.framework.SensorRepository
|
||||
import com.rtbishop.look4sat.framework.SettingsRepository
|
||||
import com.rtbishop.look4sat.framework.SensorsRepo
|
||||
import com.rtbishop.look4sat.framework.SettingsRepo
|
||||
import com.rtbishop.look4sat.framework.data.DataSource
|
||||
import com.rtbishop.look4sat.framework.data.LocalStorage
|
||||
import com.rtbishop.look4sat.framework.data.MIGRATION_1_2
|
||||
import com.rtbishop.look4sat.framework.data.MainDatabase
|
||||
import com.rtbishop.look4sat.framework.data.local.EntriesStorage
|
||||
import com.rtbishop.look4sat.framework.data.local.RadiosStorage
|
||||
import com.rtbishop.look4sat.framework.data.remote.FileSource
|
||||
import com.rtbishop.look4sat.framework.data.remote.NetworkSource
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
@@ -31,52 +30,48 @@ import org.osmdroid.config.Configuration
|
||||
|
||||
class MainContainer(private val context: Context) {
|
||||
|
||||
val bluetoothReporter = provideBluetoothReporter()
|
||||
val networkReporter = provideNetworkReporter()
|
||||
val settingsRepository = provideSettingsRepository()
|
||||
val dataRepository = provideDataRepository(settingsRepository)
|
||||
val sensorRepository = provideSensorRepository()
|
||||
val satelliteRepository = provideSatelliteRepository()
|
||||
private val database = Room.databaseBuilder(context, MainDatabase::class.java, "Look4SatDb")
|
||||
.addMigrations(MIGRATION_1_2).fallbackToDestructiveMigration().build()
|
||||
private val localStorage = LocalStorage(database.storageDao())
|
||||
val settingsRepo = provideSettingsRepo()
|
||||
val databaseRepo = provideDatabaseRepo(settingsRepo)
|
||||
val sensorsRepo = provideSensorRepo()
|
||||
val satelliteRepo = provideSatelliteRepo()
|
||||
|
||||
private fun provideBluetoothReporter(): BluetoothReporter {
|
||||
val manager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||
return BluetoothReporter(manager, CoroutineScope(Dispatchers.IO))
|
||||
fun provideBluetoothReporter(): BluetoothReporter {
|
||||
val btManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||
return BluetoothReporter(btManager, CoroutineScope(Dispatchers.IO))
|
||||
}
|
||||
|
||||
private fun provideNetworkReporter(): NetworkReporter {
|
||||
fun provideNetworkReporter(): NetworkReporter {
|
||||
return NetworkReporter(CoroutineScope(Dispatchers.IO))
|
||||
}
|
||||
|
||||
private fun provideDataRepository(settings: ISettingsRepository): IDataRepository {
|
||||
val db = Room.databaseBuilder(context, MainDatabase::class.java, "Look4SatDb")
|
||||
.addMigrations(MIGRATION_1_2).fallbackToDestructiveMigration().build()
|
||||
val parser = DataParser(Dispatchers.Default)
|
||||
val fileSource = FileSource(context.contentResolver, Dispatchers.IO)
|
||||
val entries = EntriesStorage(db.entriesDao())
|
||||
val radios = RadiosStorage(db.radiosDao())
|
||||
val remoteSource = NetworkSource(Dispatchers.IO)
|
||||
private fun provideDatabaseRepo(settingsRepo: ISettingsRepo): IDatabaseRepo {
|
||||
val dataParser = DataParser(Dispatchers.Default)
|
||||
val dataSource = DataSource(context.contentResolver, Dispatchers.IO)
|
||||
val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
||||
return DataRepository(parser, fileSource, entries, radios, remoteSource, scope, settings)
|
||||
return DatabaseRepo(dataParser, localStorage, dataSource, scope, settingsRepo)
|
||||
}
|
||||
|
||||
fun provideSelectionRepository(): SelectionRepository {
|
||||
return SelectionRepository(Dispatchers.Default, dataRepository, settingsRepository)
|
||||
fun provideSelectionRepo(): ISelectionRepo {
|
||||
return SelectionRepo(Dispatchers.Default, localStorage, settingsRepo)
|
||||
}
|
||||
|
||||
private fun provideSensorRepository(): ISensorRepository {
|
||||
val manager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||
val sensor = manager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)
|
||||
return SensorRepository(manager, sensor)
|
||||
private fun provideSensorRepo(): ISensorsRepo {
|
||||
val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)
|
||||
return SensorsRepo(sensorManager, sensor)
|
||||
}
|
||||
|
||||
private fun provideSatelliteRepository(): ISatelliteRepository {
|
||||
return SatelliteRepository(Dispatchers.Default)
|
||||
private fun provideSatelliteRepo(): ISatelliteRepo {
|
||||
return SatelliteRepo(Dispatchers.Default, localStorage)
|
||||
}
|
||||
|
||||
private fun provideSettingsRepository(): ISettingsRepository {
|
||||
val manager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
private fun provideSettingsRepo(): ISettingsRepo {
|
||||
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
val preferences = context.getSharedPreferences("default", Context.MODE_PRIVATE)
|
||||
Configuration.getInstance().load(context, preferences)
|
||||
return SettingsRepository(manager, preferences)
|
||||
return SettingsRepo(locationManager, preferences)
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -21,14 +21,14 @@ import android.hardware.Sensor
|
||||
import android.hardware.SensorEvent
|
||||
import android.hardware.SensorEventListener
|
||||
import android.hardware.SensorManager
|
||||
import com.rtbishop.look4sat.domain.ISensorRepository
|
||||
import com.rtbishop.look4sat.domain.ISensorsRepo
|
||||
import com.rtbishop.look4sat.domain.RAD2DEG
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlin.math.round
|
||||
|
||||
class SensorRepository(private val manager: SensorManager, private val sensor: Sensor?) :
|
||||
SensorEventListener, ISensorRepository {
|
||||
class SensorsRepo(private val sensorManager: SensorManager, private val sensor: Sensor?) :
|
||||
SensorEventListener, ISensorsRepo {
|
||||
|
||||
private val rotationMatrix = FloatArray(9)
|
||||
private val orientationValues = FloatArray(3)
|
||||
@@ -38,10 +38,10 @@ class SensorRepository(private val manager: SensorManager, private val sensor: S
|
||||
override val orientation: StateFlow<Pair<Float, Float>> = _orientation
|
||||
|
||||
override fun enableSensor() {
|
||||
sensor?.let { manager.registerListener(this, it, 16000) }
|
||||
sensor?.let { sensorManager.registerListener(this, it, 16000) }
|
||||
}
|
||||
|
||||
override fun disableSensor() = manager.unregisterListener(this)
|
||||
override fun disableSensor() = sensorManager.unregisterListener(this)
|
||||
|
||||
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
|
||||
sensorAccuracy = accuracy
|
||||
+3
-3
@@ -23,7 +23,7 @@ import android.location.LocationManager
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.location.LocationManagerCompat
|
||||
import androidx.core.os.CancellationSignal
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepository
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepo
|
||||
import com.rtbishop.look4sat.model.GeoPos
|
||||
import com.rtbishop.look4sat.utility.QthConverter
|
||||
import com.rtbishop.look4sat.utility.round
|
||||
@@ -31,9 +31,9 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
class SettingsRepository(
|
||||
class SettingsRepo(
|
||||
private val manager: LocationManager, private val preferences: SharedPreferences
|
||||
) : ISettingsRepository {
|
||||
) : ISettingsRepo {
|
||||
|
||||
private val keyModes = "satModes"
|
||||
private val keyCompass = "compass"
|
||||
+12
-8
@@ -15,21 +15,25 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rtbishop.look4sat.framework.data.remote
|
||||
package com.rtbishop.look4sat.framework.data
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.net.Uri
|
||||
import com.rtbishop.look4sat.data.IFileSource
|
||||
import com.rtbishop.look4sat.data.IDataSource
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.InputStream
|
||||
import java.net.URL
|
||||
|
||||
class FileSource(
|
||||
private val contentResolver: ContentResolver,
|
||||
private val coroutineDispatcher: CoroutineDispatcher
|
||||
) : IFileSource {
|
||||
class DataSource(
|
||||
private val resolver: ContentResolver, private val dispatcher: CoroutineDispatcher
|
||||
) : IDataSource {
|
||||
|
||||
override suspend fun getDataStream(uri: String): InputStream? {
|
||||
return withContext(coroutineDispatcher) { contentResolver.openInputStream(Uri.parse(uri)) }
|
||||
override suspend fun getFileStream(uri: String): InputStream? {
|
||||
return withContext(dispatcher) { resolver.openInputStream(Uri.parse(uri)) }
|
||||
}
|
||||
|
||||
override suspend fun getNetworkStream(url: String): InputStream? {
|
||||
return withContext(dispatcher) { URL(url).openStream() }
|
||||
}
|
||||
}
|
||||
+45
-9
@@ -15,38 +15,42 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rtbishop.look4sat.framework.data.local
|
||||
package com.rtbishop.look4sat.framework.data
|
||||
|
||||
import com.rtbishop.look4sat.data.IEntriesStorage
|
||||
import com.rtbishop.look4sat.data.ILocalStorage
|
||||
import com.rtbishop.look4sat.domain.Satellite
|
||||
import com.rtbishop.look4sat.framework.data.dao.EntriesDao
|
||||
import com.rtbishop.look4sat.model.SatRadio
|
||||
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
|
||||
import com.rtbishop.look4sat.model.SatEntry as DomainEntry
|
||||
import com.rtbishop.look4sat.model.SatItem as DomainItem
|
||||
import com.rtbishop.look4sat.model.SatRadio as DomainRadio
|
||||
|
||||
class EntriesStorage(private val entriesDao: EntriesDao) : IEntriesStorage {
|
||||
class LocalStorage(private val storageDao: StorageDao) : ILocalStorage {
|
||||
|
||||
override fun getEntriesTotal() = entriesDao.getEntriesTotal()
|
||||
//region # Entries region
|
||||
|
||||
override fun getEntriesTotal() = storageDao.getEntriesTotal()
|
||||
|
||||
override suspend fun getEntriesList(): List<DomainItem> {
|
||||
return entriesDao.getEntriesList().toDomainItems()
|
||||
return storageDao.getEntriesList().toDomainItems()
|
||||
}
|
||||
|
||||
override suspend fun getEntriesWithIds(ids: List<Int>): List<Satellite> {
|
||||
val selectedSatellites = mutableListOf<Satellite>()
|
||||
ids.chunked(999).forEach { idsPart ->
|
||||
val entries = entriesDao.getEntriesWithIds(idsPart)
|
||||
val entries = storageDao.getEntriesWithIds(idsPart)
|
||||
selectedSatellites.addAll(entries.map { entry -> entry.data.getSatellite() })
|
||||
}
|
||||
return selectedSatellites
|
||||
}
|
||||
|
||||
override suspend fun insertEntries(entries: List<DomainEntry>) {
|
||||
entriesDao.insertEntries(entries.toFrameworkEntries())
|
||||
storageDao.insertEntries(entries.toFrameworkEntries())
|
||||
}
|
||||
|
||||
override suspend fun deleteEntries() = entriesDao.deleteEntries()
|
||||
override suspend fun deleteEntries() = storageDao.deleteEntries()
|
||||
|
||||
private fun DomainEntry.toFramework() = FrameworkEntry(this.data, this.comment)
|
||||
|
||||
@@ -55,4 +59,36 @@ class EntriesStorage(private val entriesDao: EntriesDao) : IEntriesStorage {
|
||||
private fun List<DomainEntry>.toFrameworkEntries() = this.map { entry -> entry.toFramework() }
|
||||
|
||||
private fun List<FrameworkItem>.toDomainItems() = this.map { item -> item.toDomain() }
|
||||
|
||||
//endregion
|
||||
|
||||
//region # Radios region
|
||||
|
||||
override fun getRadiosTotal() = storageDao.getRadiosTotal()
|
||||
|
||||
override suspend fun getRadiosWithId(id: Int): List<SatRadio> {
|
||||
return storageDao.getRadiosWithId(id).toDomainRadios()
|
||||
}
|
||||
|
||||
override suspend fun insertRadios(radios: List<SatRadio>) {
|
||||
storageDao.insertRadios(radios.toFrameworkRadios())
|
||||
}
|
||||
|
||||
override suspend fun deleteRadios() = storageDao.deleteRadios()
|
||||
|
||||
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 FrameworkRadio.toDomain() = DomainRadio(
|
||||
this.uuid, this.info, this.isAlive, this.downlink, this.uplink,
|
||||
this.mode, this.isInverted, this.catnum, this.comment
|
||||
)
|
||||
|
||||
private fun List<DomainRadio>.toFrameworkRadios() = this.map { radio -> radio.toFramework() }
|
||||
|
||||
private fun List<FrameworkRadio>.toDomainRadios() = this.map { radio -> radio.toDomain() }
|
||||
|
||||
//endregion
|
||||
}
|
||||
@@ -21,17 +21,13 @@ import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.rtbishop.look4sat.framework.data.dao.EntriesDao
|
||||
import com.rtbishop.look4sat.framework.data.dao.RadiosDao
|
||||
import com.rtbishop.look4sat.framework.model.SatEntry
|
||||
import com.rtbishop.look4sat.framework.model.SatRadio
|
||||
|
||||
@Database(entities = [SatEntry::class, SatRadio::class], version = 2)
|
||||
abstract class MainDatabase : RoomDatabase() {
|
||||
|
||||
abstract fun entriesDao(): EntriesDao
|
||||
|
||||
abstract fun radiosDao(): RadiosDao
|
||||
abstract fun storageDao(): StorageDao
|
||||
}
|
||||
|
||||
val MIGRATION_1_2 = object : Migration(1, 2) {
|
||||
|
||||
+19
-5
@@ -15,22 +15,23 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rtbishop.look4sat.framework.data.dao
|
||||
package com.rtbishop.look4sat.framework.data
|
||||
|
||||
import androidx.room.*
|
||||
import com.rtbishop.look4sat.framework.model.SatEntry
|
||||
import com.rtbishop.look4sat.framework.model.SatItem
|
||||
import com.rtbishop.look4sat.framework.model.SatRadio
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface EntriesDao {
|
||||
interface StorageDao {
|
||||
|
||||
@Query("SELECT COUNT(*) FROM entries")
|
||||
fun getEntriesTotal(): Flow<Int>
|
||||
|
||||
// @Transaction
|
||||
@Query("SELECT catnum, name FROM entries ORDER BY name ASC")
|
||||
suspend fun getEntriesList(): List<SatItem>
|
||||
//@Transaction
|
||||
@Query("SELECT catnum, name FROM entries ORDER BY name ASC")
|
||||
suspend fun getEntriesList(): List<SatItem>
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT * FROM entries WHERE catnum IN (:selectedIds)")
|
||||
@@ -41,4 +42,17 @@ suspend fun getEntriesList(): List<SatItem>
|
||||
|
||||
@Query("DELETE FROM entries")
|
||||
suspend fun deleteEntries()
|
||||
|
||||
@Query("SELECT COUNT(*) FROM radios")
|
||||
fun getRadiosTotal(): Flow<Int>
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT * FROM radios WHERE catnum = :id AND isAlive = 1")
|
||||
suspend fun getRadiosWithId(id: Int): List<SatRadio>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertRadios(radios: List<SatRadio>)
|
||||
|
||||
@Query("DELETE FROM radios")
|
||||
suspend fun deleteRadios()
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Look4Sat. Amateur radio satellite tracker and pass predictor.
|
||||
* Copyright (C) 2019-2022 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rtbishop.look4sat.framework.data.dao
|
||||
|
||||
import androidx.room.*
|
||||
import com.rtbishop.look4sat.framework.model.SatRadio
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface RadiosDao {
|
||||
|
||||
@Query("SELECT COUNT(*) FROM radios")
|
||||
fun getRadiosTotal(): Flow<Int>
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT * FROM radios WHERE catnum = :id AND isAlive = 1")
|
||||
suspend fun getRadiosWithId(id: Int): List<SatRadio>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertRadios(radios: List<SatRadio>)
|
||||
|
||||
@Query("DELETE FROM radios")
|
||||
suspend fun deleteRadios()
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Look4Sat. Amateur radio satellite tracker and pass predictor.
|
||||
* Copyright (C) 2019-2022 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rtbishop.look4sat.framework.data.local
|
||||
|
||||
import com.rtbishop.look4sat.data.IRadiosStorage
|
||||
import com.rtbishop.look4sat.framework.data.dao.RadiosDao
|
||||
import com.rtbishop.look4sat.framework.model.SatRadio as FrameworkRadio
|
||||
import com.rtbishop.look4sat.model.SatRadio as DomainRadio
|
||||
|
||||
class RadiosStorage(private val radiosDao: RadiosDao) : IRadiosStorage {
|
||||
|
||||
override fun getRadiosTotal() = radiosDao.getRadiosTotal()
|
||||
|
||||
override suspend fun getRadiosWithId(id: Int): List<DomainRadio> {
|
||||
return radiosDao.getRadiosWithId(id).toDomainRadios()
|
||||
}
|
||||
|
||||
override suspend fun insertRadios(radios: List<DomainRadio>) {
|
||||
radiosDao.insertRadios(radios.toFrameworkRadios())
|
||||
}
|
||||
|
||||
override suspend fun deleteRadios() = radiosDao.deleteRadios()
|
||||
|
||||
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 FrameworkRadio.toDomain() = DomainRadio(
|
||||
this.uuid, this.info, this.isAlive, this.downlink, this.uplink,
|
||||
this.mode, this.isInverted, this.catnum, this.comment
|
||||
)
|
||||
|
||||
private fun List<DomainRadio>.toFrameworkRadios() = this.map { radio -> radio.toFramework() }
|
||||
|
||||
private fun List<FrameworkRadio>.toDomainRadios() = this.map { radio -> radio.toDomain() }
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Look4Sat. Amateur radio satellite tracker and pass predictor.
|
||||
* Copyright (C) 2019-2022 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rtbishop.look4sat.framework.data.remote
|
||||
|
||||
import com.rtbishop.look4sat.data.INetworkSource
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.InputStream
|
||||
import java.net.URL
|
||||
|
||||
class NetworkSource(private val coroutineDispatcher: CoroutineDispatcher) : INetworkSource {
|
||||
|
||||
override suspend fun getDataStream(url: String): InputStream? {
|
||||
return withContext(coroutineDispatcher) { URL(url).openStream() }
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.Interaction
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@@ -25,8 +24,6 @@ import androidx.compose.ui.composed
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
|
||||
@Composable
|
||||
fun CardButton(onClick: () -> Unit, text: String, modifier: Modifier = Modifier) {
|
||||
@@ -66,9 +63,3 @@ fun gotoUrl(context: Context, url: String) {
|
||||
fun Modifier.onClick(onClick: () -> Unit): Modifier = composed {
|
||||
clickable(remember { MutableInteractionSource() }, null) { onClick() }
|
||||
}
|
||||
|
||||
class NoRippleInteractionSource : MutableInteractionSource {
|
||||
override val interactions: Flow<Interaction> = emptyFlow()
|
||||
override suspend fun emit(interaction: Interaction) {}
|
||||
override fun tryEmit(interaction: Interaction) = true
|
||||
}
|
||||
@@ -45,8 +45,8 @@ fun EntriesScreen(navToPasses: () -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
val unselectAll = { viewModel.updateSelection(false) }
|
||||
val selectAll = { viewModel.updateSelection(true) }
|
||||
val unselectAll = { viewModel.setSelection(false) }
|
||||
val selectAll = { viewModel.setSelection(true) }
|
||||
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
TopBar(setQuery = { newQuery: String -> viewModel.setQuery(newQuery) }, saveSelection = {
|
||||
viewModel.saveSelection()
|
||||
@@ -58,7 +58,7 @@ fun EntriesScreen(navToPasses: () -> Unit) {
|
||||
CardLoadingIndicator()
|
||||
} else {
|
||||
EntriesCard(uiState.itemsList) { list, value ->
|
||||
viewModel.updateSelection(list, value)
|
||||
viewModel.setSelection(list, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.rtbishop.look4sat.presentation.entries
|
||||
|
||||
import com.rtbishop.look4sat.model.SatItem
|
||||
|
||||
data class EntriesScreenState(
|
||||
data class EntriesUiState(
|
||||
val isLoading: Boolean,
|
||||
val itemsList: List<SatItem>,
|
||||
val currentType: String,
|
||||
@@ -24,13 +24,13 @@ import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import com.rtbishop.look4sat.MainApplication
|
||||
import com.rtbishop.look4sat.data.SelectionRepository
|
||||
import com.rtbishop.look4sat.domain.ISelectionRepo
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class EntriesViewModel(private val selectionRepo: SelectionRepository) : ViewModel() {
|
||||
class EntriesViewModel(private val selectionRepo: ISelectionRepo) : ViewModel() {
|
||||
|
||||
private val defaultUiState = EntriesScreenState(
|
||||
private val defaultUiState = EntriesUiState(
|
||||
isLoading = true,
|
||||
itemsList = emptyList(),
|
||||
currentType = selectionRepo.getCurrentType(),
|
||||
@@ -54,12 +54,12 @@ class EntriesViewModel(private val selectionRepo: SelectionRepository) : ViewMod
|
||||
|
||||
fun setQuery(query: String) = viewModelScope.launch { selectionRepo.setQuery(query) }
|
||||
|
||||
fun updateSelection(selectAll: Boolean) = viewModelScope.launch {
|
||||
selectionRepo.updateSelection(selectAll)
|
||||
fun setSelection(selectAll: Boolean) = viewModelScope.launch {
|
||||
selectionRepo.setSelection(selectAll)
|
||||
}
|
||||
|
||||
fun updateSelection(catNums: List<Int>, isSelected: Boolean) = viewModelScope.launch {
|
||||
selectionRepo.updateSelection(catNums, isSelected)
|
||||
fun setSelection(ids: List<Int>, isTicked: Boolean) = viewModelScope.launch {
|
||||
selectionRepo.setSelection(ids, isTicked)
|
||||
}
|
||||
|
||||
fun saveSelection() = viewModelScope.launch { selectionRepo.saveSelection() }
|
||||
@@ -69,7 +69,7 @@ class EntriesViewModel(private val selectionRepo: SelectionRepository) : ViewMod
|
||||
val applicationKey = ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY
|
||||
initializer {
|
||||
val container = (this[applicationKey] as MainApplication).container
|
||||
EntriesViewModel(container.provideSelectionRepository())
|
||||
EntriesViewModel(container.provideSelectionRepo())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ private val labelRect = Rect()
|
||||
fun MapScreen() {
|
||||
val viewModel = viewModel(MapViewModel::class.java, factory = MapViewModel.Factory)
|
||||
viewModel.selectDefaultSatellite(-1)
|
||||
val stationPos = viewModel.stationPos.collectAsState(initial = null)
|
||||
val stationPos = viewModel.stationPosition.collectAsState(initial = null)
|
||||
val positions = viewModel.positions.collectAsState(initial = null)
|
||||
val satTrack = viewModel.track.collectAsState(initial = null)
|
||||
val footprint = viewModel.footprint.collectAsState(initial = null)
|
||||
|
||||
@@ -23,9 +23,8 @@ import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import com.rtbishop.look4sat.MainApplication
|
||||
import com.rtbishop.look4sat.domain.IDataRepository
|
||||
import com.rtbishop.look4sat.domain.ISatelliteRepository
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepository
|
||||
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepo
|
||||
import com.rtbishop.look4sat.domain.Satellite
|
||||
import com.rtbishop.look4sat.model.GeoPos
|
||||
import com.rtbishop.look4sat.model.SatPos
|
||||
@@ -46,22 +45,19 @@ import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class MapViewModel(
|
||||
private val dataRepository: IDataRepository,
|
||||
private val satelliteRepository: ISatelliteRepository,
|
||||
private val settingsRepository: ISettingsRepository
|
||||
private val satelliteRepo: ISatelliteRepo, private val settingsRepo: ISettingsRepo
|
||||
) : ViewModel() {
|
||||
|
||||
private val stationPosNew = settingsRepository.stationPosition.value
|
||||
private val stationPosition = GeoPos(stationPosNew.latitude, stationPosNew.longitude)
|
||||
private var allPasses = satelliteRepository.getPasses()
|
||||
private val stationPos = settingsRepo.stationPosition.value
|
||||
private var allPasses = satelliteRepo.getPasses()
|
||||
private var allSatellites = listOf<Satellite>()
|
||||
private var dataUpdateJob: Job? = null
|
||||
private var dataUpdateRate = 1000L
|
||||
private var selectedSatellite: Satellite? = null
|
||||
|
||||
val stationPos = flow {
|
||||
val osmLat = clipLat(stationPosition.latitude)
|
||||
val osmLon = clipLon(stationPosition.longitude)
|
||||
val stationPosition = flow {
|
||||
val osmLat = clipLat(stationPos.latitude)
|
||||
val osmLon = clipLon(stationPos.longitude)
|
||||
emit(GeoPos(osmLat, osmLon))
|
||||
}
|
||||
|
||||
@@ -92,8 +88,8 @@ class MapViewModel(
|
||||
|
||||
fun selectDefaultSatellite(catnum: Int) {
|
||||
viewModelScope.launch {
|
||||
val selectedIds = settingsRepository.satelliteSelection.value
|
||||
dataRepository.getEntriesWithIds(selectedIds).also { satellites ->
|
||||
val selectedIds = settingsRepo.satelliteSelection.value
|
||||
satelliteRepo.getEntriesWithIds(selectedIds).also { satellites ->
|
||||
if (satellites.isNotEmpty()) {
|
||||
allSatellites = satellites
|
||||
if (catnum == -1) {
|
||||
@@ -113,12 +109,12 @@ class MapViewModel(
|
||||
dataUpdateJob?.cancelAndJoin()
|
||||
dataUpdateJob = launch {
|
||||
val dateNow = Date()
|
||||
getSatTrack(satellite, stationPosition, dateNow)
|
||||
getSatTrack(satellite, stationPos, dateNow)
|
||||
while (isActive) {
|
||||
dateNow.time = System.currentTimeMillis()
|
||||
getPositions(allSatellites, stationPosition, dateNow)
|
||||
getSatFootprint(satellite, stationPosition, dateNow)
|
||||
getSatData(satellite, stationPosition, dateNow)
|
||||
getPositions(allSatellites, stationPos, dateNow)
|
||||
getSatFootprint(satellite, stationPos, dateNow)
|
||||
getSatData(satellite, stationPos, dateNow)
|
||||
delay(updateFreq)
|
||||
}
|
||||
}
|
||||
@@ -130,7 +126,7 @@ class MapViewModel(
|
||||
val currentTrack = mutableListOf<GeoPos>()
|
||||
val endDate = Date(date.time + (satellite.data.orbitalPeriod * 2.4 * 60000L).toLong())
|
||||
var oldLongitude = 0.0
|
||||
satelliteRepository.getTrack(satellite, pos, date.time, endDate.time).forEach { satPos ->
|
||||
satelliteRepo.getTrack(satellite, pos, date.time, endDate.time).forEach { satPos ->
|
||||
val osmLat = clipLat(satPos.latitude.toDegrees())
|
||||
val osmLon = clipLon(satPos.longitude.toDegrees())
|
||||
val currentPosition = GeoPos(osmLat, osmLon)
|
||||
@@ -157,7 +153,7 @@ class MapViewModel(
|
||||
private suspend fun getPositions(satellites: List<Satellite>, pos: GeoPos, date: Date) {
|
||||
val positions = mutableMapOf<Satellite, GeoPos>()
|
||||
satellites.forEach { satellite ->
|
||||
val satPos = satelliteRepository.getPosition(satellite, pos, date.time)
|
||||
val satPos = satelliteRepo.getPosition(satellite, pos, date.time)
|
||||
val osmLat = clipLat(satPos.latitude.toDegrees())
|
||||
val osmLon = clipLon(satPos.longitude.toDegrees())
|
||||
positions[satellite] = GeoPos(osmLat, osmLon)
|
||||
@@ -166,7 +162,7 @@ class MapViewModel(
|
||||
}
|
||||
|
||||
private suspend fun getSatFootprint(satellite: Satellite, pos: GeoPos, date: Date) {
|
||||
val satPos = satelliteRepository.getPosition(satellite, pos, date.time)
|
||||
val satPos = satelliteRepo.getPosition(satellite, pos, date.time)
|
||||
_footprint.emit(satPos)
|
||||
}
|
||||
|
||||
@@ -184,7 +180,7 @@ class MapViewModel(
|
||||
}
|
||||
}
|
||||
}
|
||||
val satPos = satelliteRepository.getPosition(sat, pos, date.time)
|
||||
val satPos = satelliteRepo.getPosition(sat, pos, date.time)
|
||||
val azimuth = satPos.azimuth.toDegrees()
|
||||
val elevation = satPos.elevation.toDegrees()
|
||||
val osmLat = clipLat(satPos.latitude.toDegrees())
|
||||
@@ -232,11 +228,7 @@ class MapViewModel(
|
||||
val applicationKey = ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY
|
||||
initializer {
|
||||
val container = (this[applicationKey] as MainApplication).container
|
||||
MapViewModel(
|
||||
container.dataRepository,
|
||||
container.satelliteRepository,
|
||||
container.settingsRepository
|
||||
)
|
||||
MapViewModel(container.satelliteRepo, container.settingsRepo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,8 @@ import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import com.rtbishop.look4sat.MainApplication
|
||||
import com.rtbishop.look4sat.domain.IDataRepository
|
||||
import com.rtbishop.look4sat.domain.ISatelliteRepository
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepository
|
||||
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepo
|
||||
import com.rtbishop.look4sat.model.DataState
|
||||
import com.rtbishop.look4sat.model.SatPass
|
||||
import com.rtbishop.look4sat.utility.toTimerString
|
||||
@@ -38,9 +37,7 @@ import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class PassesViewModel(
|
||||
private val dataRepository: IDataRepository,
|
||||
private val satelliteRepository: ISatelliteRepository,
|
||||
private val settingsRepository: ISettingsRepository
|
||||
private val satelliteRepo: ISatelliteRepo, private val settingsRepo: ISettingsRepo
|
||||
) : ViewModel() {
|
||||
|
||||
private val _passes = MutableStateFlow<DataState<List<SatPass>>>(DataState.Loading)
|
||||
@@ -50,18 +47,18 @@ class PassesViewModel(
|
||||
val passes: StateFlow<DataState<List<SatPass>>> = _passes
|
||||
val timerText: StateFlow<Triple<String, String, String>?> = _timerText
|
||||
|
||||
fun getHoursAhead() = settingsRepository.getHoursAhead()
|
||||
fun getHoursAhead() = settingsRepo.getHoursAhead()
|
||||
|
||||
fun getMinElevation() = settingsRepository.getMinElevation()
|
||||
fun getMinElevation() = settingsRepo.getMinElevation()
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
satelliteRepository.calculatedPasses.collect { passes ->
|
||||
satelliteRepo.calculatedPasses.collect { passes ->
|
||||
passesProcessing?.cancelAndJoin()
|
||||
passesProcessing = viewModelScope.launch {
|
||||
while (isActive) {
|
||||
val timeNow = System.currentTimeMillis()
|
||||
val newPasses = satelliteRepository.processPasses(passes, timeNow)
|
||||
val newPasses = satelliteRepo.processPasses(passes, timeNow)
|
||||
|
||||
if (newPasses.isNotEmpty()) {
|
||||
try {
|
||||
@@ -88,20 +85,15 @@ class PassesViewModel(
|
||||
}
|
||||
}
|
||||
viewModelScope.launch {
|
||||
settingsRepository.satelliteSelection.collect { calculatePasses() }
|
||||
}
|
||||
viewModelScope.launch {
|
||||
dataRepository.updateState.collect { updateState ->
|
||||
if (updateState is DataState.Success) calculatePasses()
|
||||
}
|
||||
settingsRepo.satelliteSelection.collect { calculatePasses() }
|
||||
}
|
||||
}
|
||||
|
||||
fun shouldUseUTC() = settingsRepository.isUtcEnabled()
|
||||
fun shouldUseUTC() = settingsRepo.isUtcEnabled()
|
||||
|
||||
fun calculatePasses(
|
||||
hoursAhead: Int = 1,
|
||||
minElevation: Double = settingsRepository.getMinElevation(),
|
||||
minElevation: Double = settingsRepo.getMinElevation(),
|
||||
timeRef: Long = System.currentTimeMillis()
|
||||
) {
|
||||
viewModelScope.launch {
|
||||
@@ -109,12 +101,12 @@ class PassesViewModel(
|
||||
// _timerText.postValue(timerDefaultText)
|
||||
passesProcessing?.cancelAndJoin()
|
||||
// selection?.let { items -> settingsRepository.saveEntriesSelection(items) }
|
||||
settingsRepository.setHoursAhead(hoursAhead)
|
||||
settingsRepository.setMinElevation(minElevation)
|
||||
val stationPos = settingsRepository.stationPosition.value
|
||||
val selectedIds = settingsRepository.satelliteSelection.value
|
||||
val satellites = dataRepository.getEntriesWithIds(selectedIds)
|
||||
satelliteRepository.calculatePasses(
|
||||
settingsRepo.setHoursAhead(hoursAhead)
|
||||
settingsRepo.setMinElevation(minElevation)
|
||||
val stationPos = settingsRepo.stationPosition.value
|
||||
val selectedIds = settingsRepo.satelliteSelection.value
|
||||
val satellites = satelliteRepo.getEntriesWithIds(selectedIds)
|
||||
satelliteRepo.calculatePasses(
|
||||
satellites, stationPos, timeRef, hoursAhead, minElevation
|
||||
)
|
||||
}
|
||||
@@ -125,11 +117,7 @@ class PassesViewModel(
|
||||
val applicationKey = ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY
|
||||
initializer {
|
||||
val container = (this[applicationKey] as MainApplication).container
|
||||
PassesViewModel(
|
||||
container.dataRepository,
|
||||
container.satelliteRepository,
|
||||
container.settingsRepository
|
||||
)
|
||||
PassesViewModel(container.satelliteRepo, container.settingsRepo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,10 +28,9 @@ import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import com.rtbishop.look4sat.MainApplication
|
||||
import com.rtbishop.look4sat.domain.IDataRepository
|
||||
import com.rtbishop.look4sat.domain.ISatelliteRepository
|
||||
import com.rtbishop.look4sat.domain.ISensorRepository
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepository
|
||||
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
||||
import com.rtbishop.look4sat.domain.ISensorsRepo
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepo
|
||||
import com.rtbishop.look4sat.domain.Satellite
|
||||
import com.rtbishop.look4sat.framework.BluetoothReporter
|
||||
import com.rtbishop.look4sat.framework.NetworkReporter
|
||||
@@ -47,26 +46,25 @@ import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class RadarViewModel(
|
||||
private val savedStateHandle: SavedStateHandle,
|
||||
private val bluetoothReporter: BluetoothReporter,
|
||||
private val networkReporter: NetworkReporter,
|
||||
private val savedStateHandle: SavedStateHandle,
|
||||
private val dataRepository: IDataRepository,
|
||||
private val satelliteRepository: ISatelliteRepository,
|
||||
private val sensorRepository: ISensorRepository,
|
||||
private val settingsRepository: ISettingsRepository
|
||||
private val satelliteRepo: ISatelliteRepo,
|
||||
private val settingsRepo: ISettingsRepo,
|
||||
private val sensorsRepo: ISensorsRepo
|
||||
) : ViewModel() {
|
||||
|
||||
private val stationPos = settingsRepository.stationPosition.value
|
||||
private val stationPos = settingsRepo.stationPosition.value
|
||||
private val magDeclination = getMagDeclination(stationPos)
|
||||
val transmitters = mutableStateOf<List<SatRadio>>(emptyList())
|
||||
val radarData = mutableStateOf<RadarData?>(null)
|
||||
val orientation = mutableStateOf(sensorRepository.orientation.value)
|
||||
val orientation = mutableStateOf(sensorsRepo.orientation.value)
|
||||
|
||||
init {
|
||||
if (settingsRepository.isSensorEnabled()) {
|
||||
if (settingsRepo.isSensorEnabled()) {
|
||||
viewModelScope.launch {
|
||||
sensorRepository.enableSensor()
|
||||
sensorRepository.orientation.collect { data ->
|
||||
sensorsRepo.enableSensor()
|
||||
sensorsRepo.orientation.collect { data ->
|
||||
orientation.value = Pair(data.first + magDeclination, data.second)
|
||||
}
|
||||
}
|
||||
@@ -74,24 +72,24 @@ class RadarViewModel(
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
sensorRepository.disableSensor()
|
||||
sensorsRepo.disableSensor()
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
fun getPass() = flow {
|
||||
val catNum = savedStateHandle.get<Int>("catNum") ?: 0
|
||||
val aosTime = savedStateHandle.get<Long>("aosTime") ?: 0L
|
||||
satelliteRepository.calculatedPasses.collect { passes ->
|
||||
satelliteRepo.calculatedPasses.collect { passes ->
|
||||
val pass = passes.find { pass -> pass.catNum == catNum && pass.aosTime == aosTime }
|
||||
val currentPass = pass ?: passes.firstOrNull()
|
||||
currentPass?.let { satPass ->
|
||||
emit(satPass)
|
||||
val transmitters = dataRepository.getRadiosWithId(satPass.catNum)
|
||||
val transmitters = satelliteRepo.getRadiosWithId(satPass.catNum)
|
||||
viewModelScope.launch {
|
||||
while (isActive) {
|
||||
val timeNow = System.currentTimeMillis()
|
||||
val satPos =
|
||||
satelliteRepository.getPosition(satPass.satellite, stationPos, timeNow)
|
||||
satelliteRepo.getPosition(satPass.satellite, stationPos, timeNow)
|
||||
sendPassData(satPass, satPos, satPass.satellite)
|
||||
sendPassDataBT(satPos)
|
||||
processRadios(transmitters, satPass.satellite, timeNow)
|
||||
@@ -102,27 +100,27 @@ class RadarViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
fun getUseCompass(): Boolean = settingsRepository.isSensorEnabled()
|
||||
fun getUseCompass(): Boolean = settingsRepo.isSensorEnabled()
|
||||
|
||||
fun getShowSweep(): Boolean = settingsRepository.isSweepEnabled()
|
||||
fun getShowSweep(): Boolean = settingsRepo.isSweepEnabled()
|
||||
|
||||
private fun getMagDeclination(geoPos: GeoPos, time: Long = System.currentTimeMillis()): Float {
|
||||
val latitude = geoPos.latitude.toFloat()
|
||||
val longitude = geoPos.longitude.toFloat()
|
||||
return GeomagneticField(latitude, longitude, 0f, time).declination
|
||||
return GeomagneticField(latitude, longitude, geoPos.altitude.toFloat(), time).declination
|
||||
}
|
||||
|
||||
private fun sendPassData(satPass: SatPass, satPos: SatPos, satellite: Satellite) {
|
||||
viewModelScope.launch {
|
||||
var track: List<SatPos> = emptyList()
|
||||
if (!satPass.isDeepSpace) {
|
||||
track = satelliteRepository.getTrack(
|
||||
track = satelliteRepo.getTrack(
|
||||
satellite, stationPos, satPass.aosTime, satPass.losTime
|
||||
)
|
||||
}
|
||||
if (settingsRepository.getRotatorEnabled()) {
|
||||
val server = settingsRepository.getRotatorServer()
|
||||
val port = settingsRepository.getRotatorPort().toInt()
|
||||
if (settingsRepo.getRotatorEnabled()) {
|
||||
val server = settingsRepo.getRotatorServer()
|
||||
val port = settingsRepo.getRotatorPort().toInt()
|
||||
val azimuth = satPos.azimuth.toDegrees().round(1)
|
||||
val elevation = satPos.elevation.toDegrees().round(1)
|
||||
networkReporter.reportRotation(server, port, azimuth, elevation)
|
||||
@@ -133,10 +131,10 @@ class RadarViewModel(
|
||||
|
||||
private fun sendPassDataBT(satPos: SatPos) {
|
||||
viewModelScope.launch {
|
||||
if (settingsRepository.getBTEnabled()) {
|
||||
val btDevice = settingsRepository.getBTDeviceAddr()
|
||||
if (settingsRepo.getBTEnabled()) {
|
||||
val btDevice = settingsRepo.getBTDeviceAddr()
|
||||
if (bluetoothReporter.isConnected()) {
|
||||
val format = settingsRepository.getBTFormat()
|
||||
val format = settingsRepo.getBTFormat()
|
||||
val azimuth = satPos.azimuth.toDegrees().round(0).toInt()
|
||||
val elevation = satPos.elevation.toDegrees().round(0).toInt()
|
||||
bluetoothReporter.reportRotation(format, azimuth, elevation)
|
||||
@@ -151,7 +149,7 @@ class RadarViewModel(
|
||||
private fun processRadios(radios: List<SatRadio>, satellite: Satellite, time: Long) {
|
||||
viewModelScope.launch {
|
||||
delay(125)
|
||||
val list = satelliteRepository.processRadios(satellite, stationPos, radios, time)
|
||||
val list = satelliteRepo.processRadios(satellite, stationPos, radios, time)
|
||||
transmitters.value = list
|
||||
}
|
||||
}
|
||||
@@ -160,16 +158,14 @@ class RadarViewModel(
|
||||
val Factory: ViewModelProvider.Factory = viewModelFactory {
|
||||
val applicationKey = ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY
|
||||
initializer {
|
||||
val savedStateHandle = createSavedStateHandle()
|
||||
val container = (this[applicationKey] as MainApplication).container
|
||||
RadarViewModel(
|
||||
container.bluetoothReporter,
|
||||
container.networkReporter,
|
||||
savedStateHandle,
|
||||
container.dataRepository,
|
||||
container.satelliteRepository,
|
||||
container.sensorRepository,
|
||||
container.settingsRepository
|
||||
createSavedStateHandle(),
|
||||
container.provideBluetoothReporter(),
|
||||
container.provideNetworkReporter(),
|
||||
container.satelliteRepo,
|
||||
container.settingsRepo,
|
||||
container.sensorsRepo
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
File renamed without changes.
+24
-24
@@ -25,18 +25,18 @@ import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import com.rtbishop.look4sat.MainApplication
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.domain.IDataRepository
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepository
|
||||
import com.rtbishop.look4sat.domain.IDatabaseRepo
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepo
|
||||
import com.rtbishop.look4sat.model.DataState
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class SettingsViewModel(
|
||||
private val dataRepository: IDataRepository, private val settingsRepository: ISettingsRepository
|
||||
private val databaseRepo: IDatabaseRepo, private val settingsRepo: ISettingsRepo
|
||||
) : ViewModel() {
|
||||
|
||||
private val defaultLocationSettings = LocationSettings(false,
|
||||
settingsRepository.stationPosition.value,
|
||||
settingsRepo.stationPosition.value,
|
||||
0,
|
||||
{ setGpsPosition() },
|
||||
{ latitude, longitude -> setGeoPosition(latitude, longitude) },
|
||||
@@ -45,18 +45,18 @@ class SettingsViewModel(
|
||||
val locationSettings = mutableStateOf(defaultLocationSettings)
|
||||
|
||||
private val defaultDataSettings = DataSettings(false,
|
||||
settingsRepository.getLastUpdateTime(),
|
||||
settingsRepo.getLastUpdateTime(),
|
||||
0,
|
||||
0,
|
||||
{ dataRepository.updateFromWeb() },
|
||||
{ dataRepository.updateFromFile(it) },
|
||||
{ dataRepository.clearAllData() })
|
||||
{ databaseRepo.updateFromWeb() },
|
||||
{ databaseRepo.updateFromFile(it) },
|
||||
{ databaseRepo.clearAllData() })
|
||||
val dataSettings = mutableStateOf(defaultDataSettings)
|
||||
|
||||
private val defaultOtherSettings = OtherSettings(settingsRepository.isUtcEnabled(),
|
||||
settingsRepository.isUpdateEnabled(),
|
||||
settingsRepository.isSweepEnabled(),
|
||||
settingsRepository.isSensorEnabled(),
|
||||
private val defaultOtherSettings = OtherSettings(settingsRepo.isUtcEnabled(),
|
||||
settingsRepo.isUpdateEnabled(),
|
||||
settingsRepo.isSweepEnabled(),
|
||||
settingsRepo.isSensorEnabled(),
|
||||
{ setUtc(it) },
|
||||
{ setUpdate(it) },
|
||||
{ setSweep(it) },
|
||||
@@ -65,23 +65,23 @@ class SettingsViewModel(
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
settingsRepository.stationPosition.collect { stationPos ->
|
||||
settingsRepo.stationPosition.collect { stationPos ->
|
||||
locationSettings.value = locationSettings.value.copy(
|
||||
isUpdating = false, stationPos = stationPos
|
||||
)
|
||||
}
|
||||
}
|
||||
viewModelScope.launch {
|
||||
dataRepository.updateState.collect {
|
||||
databaseRepo.updateState.collect {
|
||||
val isUpdating = it is DataState.Loading
|
||||
dataSettings.value = dataSettings.value.copy(
|
||||
isUpdating = isUpdating, lastUpdated = settingsRepository.getLastUpdateTime()
|
||||
isUpdating = isUpdating, lastUpdated = settingsRepo.getLastUpdateTime()
|
||||
)
|
||||
}
|
||||
}
|
||||
viewModelScope.launch {
|
||||
combine(
|
||||
dataRepository.getEntriesTotal(), dataRepository.getRadiosTotal()
|
||||
databaseRepo.getEntriesTotal(), databaseRepo.getRadiosTotal()
|
||||
) { sats, radios ->
|
||||
dataSettings.value = dataSettings.value.copy(satsTotal = sats, radiosTotal = radios)
|
||||
}.collect {}
|
||||
@@ -89,7 +89,7 @@ class SettingsViewModel(
|
||||
}
|
||||
|
||||
private fun setGpsPosition() {
|
||||
if (settingsRepository.setGpsPosition()) {
|
||||
if (settingsRepo.setGpsPosition()) {
|
||||
val messageResId = R.string.location_success
|
||||
locationSettings.value =
|
||||
locationSettings.value.copy(isUpdating = true, messageResId = messageResId)
|
||||
@@ -100,7 +100,7 @@ class SettingsViewModel(
|
||||
}
|
||||
|
||||
private fun setGeoPosition(latitude: Double, longitude: Double) {
|
||||
if (settingsRepository.setGeoPosition(latitude, longitude)) {
|
||||
if (settingsRepo.setGeoPosition(latitude, longitude)) {
|
||||
val messageResId = R.string.location_success
|
||||
locationSettings.value = locationSettings.value.copy(messageResId = messageResId)
|
||||
} else {
|
||||
@@ -110,7 +110,7 @@ class SettingsViewModel(
|
||||
}
|
||||
|
||||
private fun setQthPosition(locator: String) {
|
||||
if (settingsRepository.setQthPosition(locator)) {
|
||||
if (settingsRepo.setQthPosition(locator)) {
|
||||
val messageResId = R.string.location_success
|
||||
locationSettings.value = locationSettings.value.copy(messageResId = messageResId)
|
||||
} else {
|
||||
@@ -124,22 +124,22 @@ class SettingsViewModel(
|
||||
}
|
||||
|
||||
private fun setUtc(value: Boolean) {
|
||||
settingsRepository.setUtcState(value)
|
||||
settingsRepo.setUtcState(value)
|
||||
otherSettings.value = otherSettings.value.copy(getUtc = value)
|
||||
}
|
||||
|
||||
private fun setUpdate(value: Boolean) {
|
||||
settingsRepository.setUpdateState(value)
|
||||
settingsRepo.setUpdateState(value)
|
||||
otherSettings.value = otherSettings.value.copy(getUpdate = value)
|
||||
}
|
||||
|
||||
private fun setSweep(value: Boolean) {
|
||||
settingsRepository.setSweepState(value)
|
||||
settingsRepo.setSweepState(value)
|
||||
otherSettings.value = otherSettings.value.copy(getSweep = value)
|
||||
}
|
||||
|
||||
private fun setSensor(value: Boolean) {
|
||||
settingsRepository.setSensorState(value)
|
||||
settingsRepo.setSensorState(value)
|
||||
otherSettings.value = otherSettings.value.copy(getSensor = value)
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ class SettingsViewModel(
|
||||
val applicationKey = ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY
|
||||
initializer {
|
||||
val container = (this[applicationKey] as MainApplication).container
|
||||
SettingsViewModel(container.dataRepository, container.settingsRepository)
|
||||
SettingsViewModel(container.databaseRepo, container.settingsRepo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user