mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 19:17:22 +00:00
Added PolarViewModel, removed SharedViewModel
This commit is contained in:
1 parent
4edf316b5e
commit
e0f900366a
15 files changed
+72
-79
No files matched your search
@@ -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"),
|
||||
|
||||
+7
-3
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -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
|
||||
|
||||
|
||||
+8
-19
@@ -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() }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
|
||||
Reference in new issue
Block a user