Added PolarViewModel, removed SharedViewModel

This commit is contained in:
Arty Bishop committed 2021-03-20 17:32:26 +00:00
1 parent 4edf316b5e
commit e0f900366a
15 files changed
+72 -79

No files matched your search

+2 -2
View File
@@ -7,12 +7,12 @@
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".Look4SatApp"
android:name=".ui.Look4SatApplication"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<activity
android:name=".ui.MainActivity"
android:name=".ui.Look4SatActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.Splash">
<intent-filter>
@@ -135,7 +135,7 @@ class PrefsRepo @Inject constructor(val preferences: SharedPreferences, moshi: M
preferences.edit { putString(keySources, sourcesJson) }
}
private fun loadDefaultSources(): List<TleSource> {
fun loadDefaultSources(): List<TleSource> {
return listOf(
TleSource("https://celestrak.com/NORAD/elements/active.txt"),
TleSource("https://amsat.org/tle/current/nasabare.txt"),
@@ -22,13 +22,13 @@ import androidx.appcompat.app.AppCompatActivity
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.data.repository.PrefsRepo
import com.rtbishop.look4sat.databinding.ActivityMainBinding
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
class Look4SatActivity : AppCompatActivity() {
@Inject
lateinit var prefsRepo: PrefsRepo
@@ -40,7 +40,11 @@ class MainActivity : AppCompatActivity() {
setContentView(root)
val navHost = supportFragmentManager.findFragmentById(R.id.nav_host) as NavHostFragment
navBottom.setupWithNavController(navHost.navController)
if (prefsRepo.isFirstLaunch()) navHost.navController.navigate(R.id.nav_dialog_splash)
if (prefsRepo.isFirstLaunch()) {
prefsRepo.setFirstLaunchDone()
navHost.navController.navigate(R.id.nav_dialog_splash)
}
}
}
}
@@ -15,14 +15,16 @@
* 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
package com.rtbishop.look4sat.ui
import android.app.Application
import com.rtbishop.look4sat.BuildConfig
import dagger.hilt.android.HiltAndroidApp
import timber.log.Timber
@HiltAndroidApp
class Look4SatApp : Application() {
class Look4SatApplication : Application() {
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
@@ -100,7 +100,12 @@ class EntriesFragment : Fragment(R.layout.fragment_entries), EntriesAdapter.Entr
private fun observeSourcesResult() {
getNavResult<List<String>>(R.id.nav_entries, "sources") { result ->
viewModel.importSatDataFromSources(result.map { TleSource(it) })
val sources = result.map { TleSource(it) }
if (sources.isNullOrEmpty()) {
viewModel.importSatDataFromSources()
} else {
viewModel.importSatDataFromSources(sources)
}
}
}
@@ -59,13 +59,13 @@ class EntriesViewModel @Inject constructor(
}
}
fun importSatDataFromSources(sources: List<TleSource> = prefsRepo.loadTleSources()) {
fun importSatDataFromSources(sources: List<TleSource> = prefsRepo.loadDefaultSources()) {
viewModelScope.launch {
satDataState.emit(Result.InProgress)
val updateMillis = measureTimeMillis {
try {
satelliteRepo.importSatDataFromWeb(sources)
prefsRepo.saveTleSources(sources)
satelliteRepo.importSatDataFromWeb(sources)
} catch (exception: Exception) {
satDataState.emit(Result.Error(exception))
}
@@ -24,16 +24,14 @@ import android.os.Bundle
import android.view.View
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import com.github.amsacode.predict4java.Position
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.data.model.Result
import com.rtbishop.look4sat.data.model.SatPass
import com.rtbishop.look4sat.data.model.SelectedSat
import com.rtbishop.look4sat.databinding.FragmentMapBinding
import com.rtbishop.look4sat.ui.SharedViewModel
import com.rtbishop.look4sat.data.repository.PrefsRepo
import com.rtbishop.look4sat.databinding.FragmentMapBinding
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.FlowPreview
import org.osmdroid.config.Configuration
@@ -56,7 +54,6 @@ class MapFragment : Fragment(R.layout.fragment_map) {
lateinit var prefsRepo: PrefsRepo
private lateinit var binding: FragmentMapBinding
private val mapViewModel: MapViewModel by viewModels()
private val sharedViewModel: SharedViewModel by activityViewModels()
private val minLat = MapView.getTileSystem().minLatitude
private val maxLat = MapView.getTileSystem().maxLatitude
@@ -85,7 +82,7 @@ class MapFragment : Fragment(R.layout.fragment_map) {
private fun setupObservers() {
mapViewModel.getGSP().observe(viewLifecycleOwner, { setupPosOverlay(it) })
sharedViewModel.passes.observe(viewLifecycleOwner, {
mapViewModel.passes.observe(viewLifecycleOwner, {
if (it is Result.Success && it.data.isNotEmpty()) {
mapViewModel.setPasses(it.data)
binding.fabPrev.setOnClickListener { mapViewModel.scrollSelection(true) }
@@ -19,14 +19,12 @@ package com.rtbishop.look4sat.ui.mapScreen
import android.graphics.Color
import android.graphics.Paint
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.*
import com.github.amsacode.predict4java.Position
import com.github.amsacode.predict4java.SatPos
import com.rtbishop.look4sat.data.model.SatPass
import com.rtbishop.look4sat.data.model.SelectedSat
import com.rtbishop.look4sat.data.repository.PassesRepo
import com.rtbishop.look4sat.data.repository.PrefsRepo
import com.rtbishop.look4sat.utility.QthConverter
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -48,9 +46,10 @@ import kotlin.math.sqrt
@HiltViewModel
class MapViewModel @Inject constructor(
private val prefsRepo: PrefsRepo,
passesRepo: PassesRepo,
private val qthConverter: QthConverter
) : ViewModel() {
private val dateNow = Date()
private val trackPaint = Paint().apply {
strokeWidth = 2f
@@ -77,6 +76,8 @@ class MapViewModel @Inject constructor(
private val _satMarkers = MutableLiveData<Map<SatPass, Position>>()
fun getSatMarkers(): LiveData<Map<SatPass, Position>> = _satMarkers
val passes = passesRepo.passes.asLiveData()
fun setPasses(passesList: List<SatPass>) {
filteredPasses = passesList.distinctBy { it.tle }
selectedPass = filteredPasses[0]
@@ -25,16 +25,15 @@ import android.hardware.SensorManager
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.SimpleItemAnimator
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.data.model.Result
import com.rtbishop.look4sat.data.model.SatPass
import com.rtbishop.look4sat.databinding.FragmentPolarBinding
import com.rtbishop.look4sat.data.repository.PrefsRepo
import com.rtbishop.look4sat.ui.SharedViewModel
import com.rtbishop.look4sat.databinding.FragmentPolarBinding
import com.rtbishop.look4sat.utility.RecyclerDivider
import com.rtbishop.look4sat.utility.formatForTimer
import dagger.hilt.android.AndroidEntryPoint
@@ -54,7 +53,7 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
private lateinit var binding: FragmentPolarBinding
private lateinit var satPass: SatPass
private lateinit var sensorManager: SensorManager
private val viewModel: SharedViewModel by activityViewModels()
private val viewModel: PolarViewModel by viewModels()
private var magneticDeclination = 0f
private var polarView: PolarView? = null
@@ -15,37 +15,26 @@
* 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.ui
package com.rtbishop.look4sat.ui.polarScreen
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.liveData
import com.rtbishop.look4sat.data.model.Result
import com.rtbishop.look4sat.data.model.SatPass
import com.rtbishop.look4sat.data.repository.PassesRepo
import com.rtbishop.look4sat.data.repository.PrefsRepo
import com.rtbishop.look4sat.data.repository.SatelliteRepo
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import javax.inject.Inject
@FlowPreview
@HiltViewModel
class SharedViewModel @Inject constructor(
prefsRepo: PrefsRepo,
private val satelliteRepo: SatelliteRepo,
class PolarViewModel @Inject constructor(
private val prefsRepo: PrefsRepo,
passesRepo: PassesRepo,
private val satelliteRepo: SatelliteRepo
) : ViewModel() {
private val _passes = MutableStateFlow<Result<MutableList<SatPass>>>(Result.InProgress)
val passes: LiveData<Result<MutableList<SatPass>>> = _passes.asLiveData()
init {
if (prefsRepo.isFirstLaunch()) {
prefsRepo.setFirstLaunchDone()
}
}
val passes = passesRepo.passes.asLiveData()
fun getAppTimer() = liveData {
while (true) {
@@ -55,4 +44,4 @@ class SharedViewModel @Inject constructor(
}
fun getTransmittersForSat(satId: Int) = satelliteRepo.getSatTransmitters(satId).asLiveData()
}
}
@@ -24,25 +24,21 @@ import androidx.recyclerview.widget.RecyclerView
import com.rtbishop.look4sat.data.model.TleSource
import com.rtbishop.look4sat.databinding.ItemTleSourceBinding
class SourcesAdapter : RecyclerView.Adapter<SourcesAdapter.TleSourceHolder>() {
private val sources = mutableListOf<TleSource>()
class SourcesAdapter(private val sources: MutableList<TleSource> = mutableListOf()) :
RecyclerView.Adapter<SourcesAdapter.TleSourceHolder>() {
fun getSources(): List<TleSource> {
return sources.filter { it.url != String() && it.url != " " && it.url.contains("https://") }
return sources.filter { it.url.contains("https://") }
}
fun setSources(list: List<TleSource>) {
sources.clear()
sources.addAll(list)
}
fun addSource() {
val emptySource = TleSource()
if (!sources.contains(emptySource)) {
sources.add(emptySource)
notifyItemInserted(itemCount - 1)
}
sources.add(TleSource())
notifyItemInserted(itemCount - 1)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TleSourceHolder {
@@ -49,18 +49,18 @@ class SourcesDialog : AppCompatDialogFragment() {
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT
)
tleSourcesRecycler.apply {
sourcesRecycler.apply {
adapter = sourcesAdapter
layoutManager = LinearLayoutManager(requireContext())
}
tleSourceBtnAdd.setOnClickListener {
sourceBtnAdd.setOnClickListener {
sourcesAdapter.addSource()
}
tleSourcesBtnPos.setOnClickListener {
sourcesBtnPos.setOnClickListener {
setNavResult("sources", sourcesAdapter.getSources().map { it.url })
dismiss()
}
tleSourcesBtnNeg.setOnClickListener { dismiss() }
sourcesBtnNeg.setOnClickListener { dismiss() }
}
}
}
@@ -39,7 +39,7 @@ class SplashDialog : AppCompatDialogFragment() {
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT
)
splashButton.setOnClickListener { dismiss() }
splashOkButton.setOnClickListener { dismiss() }
}
}
}
+17 -17
View File
@@ -8,41 +8,41 @@
android:padding="4dp">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/tleSourcesTitle"
android:id="@+id/sourcesTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/sources_title"
android:textSize="16sp"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="@+id/tleSourcesRecycler"
app:layout_constraintStart_toStartOf="@+id/sourcesRecycler"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/tleSourcesWarning"
android:id="@+id/sourcesWarning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:gravity="center"
android:text="@string/sources_https"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="@+id/tleSourcesRecycler"
app:layout_constraintTop_toBottomOf="@+id/tleSourcesTitle" />
app:layout_constraintStart_toStartOf="@+id/sourcesRecycler"
app:layout_constraintTop_toBottomOf="@+id/sourcesTitle" />
<ImageButton
android:id="@+id/tleSourceBtnAdd"
android:id="@+id/sourceBtnAdd"
android:layout_width="48dp"
android:layout_height="48dp"
android:backgroundTint="@color/greySurface"
android:contentDescription="@string/placeholder"
android:src="@drawable/ic_add"
app:layout_constraintBottom_toBottomOf="@+id/tleSourcesWarning"
app:layout_constraintBottom_toBottomOf="@+id/sourcesWarning"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toEndOf="@+id/tleSourcesRecycler"
app:layout_constraintTop_toTopOf="@+id/tleSourcesTitle" />
app:layout_constraintEnd_toEndOf="@+id/sourcesRecycler"
app:layout_constraintTop_toTopOf="@+id/sourcesTitle" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/tleSourcesRecycler"
android:id="@+id/sourcesRecycler"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
@@ -50,24 +50,24 @@
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tleSourcesWarning">
app:layout_constraintTop_toBottomOf="@+id/sourcesWarning">
</androidx.recyclerview.widget.RecyclerView>
<com.google.android.material.button.MaterialButton
android:id="@+id/tleSourcesBtnNeg"
android:id="@+id/sourcesBtnNeg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/greySurface"
android:text="@string/btn_cancel"
android:textAllCaps="false"
android:textColor="@color/themeLight"
app:layout_constraintBaseline_toBaselineOf="@+id/tleSourcesBtnPos"
app:layout_constraintBaseline_toBaselineOf="@+id/sourcesBtnPos"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="@+id/tleSourcesRecycler" />
app:layout_constraintStart_toStartOf="@+id/sourcesRecycler" />
<com.google.android.material.button.MaterialButton
android:id="@+id/tleSourcesBtnPos"
android:id="@+id/sourcesBtnPos"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
@@ -77,7 +77,7 @@
android:textAllCaps="false"
android:textColor="@color/themeLight"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/tleSourcesRecycler"
app:layout_constraintTop_toBottomOf="@+id/tleSourcesRecycler" />
app:layout_constraintEnd_toEndOf="@+id/sourcesRecycler"
app:layout_constraintTop_toBottomOf="@+id/sourcesRecycler" />
</androidx.constraintlayout.widget.ConstraintLayout>
+2 -2
View File
@@ -31,7 +31,7 @@
android:background="@drawable/rounded_corner"
android:contentDescription="@string/placeholder"
android:padding="8dp"
app:layout_constraintBottom_toTopOf="@+id/splashButton"
app:layout_constraintBottom_toTopOf="@+id/splashOkButton"
app:layout_constraintDimensionRatio="w,1:1"
app:layout_constraintEnd_toStartOf="@+id/splashTleMsg"
app:layout_constraintHorizontal_bias="0.5"
@@ -69,7 +69,7 @@
app:layout_constraintTop_toTopOf="@+id/splashTleIcon" />
<com.google.android.material.button.MaterialButton
android:id="@+id/splashButton"
android:id="@+id/splashOkButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"