Further refactoring and code cleanup

This commit is contained in:
Arty Bishop committed 2020-10-06 23:24:16 +01:00
1 parent b87f2a6e72
commit 4b050e21f0
72 files changed
+546 -988

No files matched your search

@@ -22,9 +22,9 @@ package com.rtbishop.look4sat.dagger
import android.content.Context
import com.rtbishop.look4sat.dagger.modules.*
import com.rtbishop.look4sat.ui.MainActivity
import com.rtbishop.look4sat.ui.fragments.MapOsmFragment
import com.rtbishop.look4sat.ui.fragments.PassListFragment
import com.rtbishop.look4sat.ui.fragments.PolarViewFragment
import com.rtbishop.look4sat.ui.fragments.MapFragment
import com.rtbishop.look4sat.ui.fragments.PassesFragment
import com.rtbishop.look4sat.ui.fragments.PolarFragment
import dagger.BindsInstance
import dagger.Component
import javax.inject.Singleton
@@ -42,7 +42,7 @@ interface AppComponent {
}
fun inject(mainActivity: MainActivity)
fun inject(passListFragment: PassListFragment)
fun inject(polarViewFragment: PolarViewFragment)
fun inject(mapOsmFragment: MapOsmFragment)
fun inject(passesFragment: PassesFragment)
fun inject(polarFragment: PolarFragment)
fun inject(mapFragment: MapFragment)
}
@@ -19,7 +19,7 @@
package com.rtbishop.look4sat.dagger.modules
import com.rtbishop.look4sat.repo.api.TransmittersApi
import com.rtbishop.look4sat.repo.remote.TransApi
import dagger.Module
import dagger.Provides
import okhttp3.OkHttpClient
@@ -32,17 +32,17 @@ class NetworkModule {
@Singleton
@Provides
fun provideOkHttpClient(): OkHttpClient {
fun provideWebClient(): OkHttpClient {
return OkHttpClient()
}
@Singleton
@Provides
fun provideTransmittersApi(): TransmittersApi {
fun provideTransApi(): TransApi {
return Retrofit.Builder()
.baseUrl("https://db.satnogs.org/api/")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(TransmittersApi::class.java)
.create(TransApi::class.java)
}
}
@@ -21,10 +21,10 @@ package com.rtbishop.look4sat.dagger.modules
import android.content.Context
import androidx.room.Room
import com.rtbishop.look4sat.repo.SatelliteDb
import com.rtbishop.look4sat.repo.dao.EntriesDao
import com.rtbishop.look4sat.repo.dao.SourcesDao
import com.rtbishop.look4sat.repo.dao.TransmittersDao
import com.rtbishop.look4sat.repo.local.EntriesDao
import com.rtbishop.look4sat.repo.local.SatDb
import com.rtbishop.look4sat.repo.local.SourcesDao
import com.rtbishop.look4sat.repo.local.TransDao
import dagger.Module
import dagger.Provides
import javax.inject.Singleton
@@ -34,26 +34,26 @@ class PersistenceModule {
@Singleton
@Provides
fun provideEntriesDao(db: SatelliteDb): EntriesDao {
fun provideEntriesDao(db: SatDb): EntriesDao {
return db.entriesDao()
}
@Singleton
@Provides
fun provideTransmittersDao(db: SatelliteDb): TransmittersDao {
return db.transmittersDao()
fun provideTransDao(db: SatDb): TransDao {
return db.transDao()
}
@Singleton
@Provides
fun providesSourcesDao(db: SatelliteDb): SourcesDao {
fun providesSourcesDao(db: SatDb): SourcesDao {
return db.sourcesDao()
}
@Singleton
@Provides
fun provideSatelliteDb(context: Context): SatelliteDb {
return Room.databaseBuilder(context, SatelliteDb::class.java, "satDb")
fun provideSatDb(context: Context): SatDb {
return Room.databaseBuilder(context, SatDb::class.java, "satDb")
.build()
}
}
@@ -4,10 +4,10 @@ import android.content.ContentResolver
import android.content.Context
import com.rtbishop.look4sat.repo.DefaultRepository
import com.rtbishop.look4sat.repo.Repository
import com.rtbishop.look4sat.repo.api.TransmittersApi
import com.rtbishop.look4sat.repo.dao.EntriesDao
import com.rtbishop.look4sat.repo.dao.SourcesDao
import com.rtbishop.look4sat.repo.dao.TransmittersDao
import com.rtbishop.look4sat.repo.local.EntriesDao
import com.rtbishop.look4sat.repo.local.SourcesDao
import com.rtbishop.look4sat.repo.local.TransDao
import com.rtbishop.look4sat.repo.remote.TransApi
import dagger.Module
import dagger.Provides
import okhttp3.OkHttpClient
@@ -26,19 +26,19 @@ class RepoModule {
@Provides
fun provideDefaultRepository(
resolver: ContentResolver,
transmittersApi: TransmittersApi,
client: OkHttpClient,
transApi: TransApi,
entriesDao: EntriesDao,
transmittersDao: TransmittersDao,
transDao: TransDao,
sourcesDao: SourcesDao
): Repository {
return DefaultRepository(
resolver,
client,
transmittersApi,
transApi,
entriesDao,
sourcesDao,
transmittersDao
transDao
)
}
}
@@ -24,7 +24,7 @@ import androidx.room.PrimaryKey
import com.google.gson.annotations.SerializedName
@Entity(tableName = "transmitters")
data class Transmitter(
data class SatTrans(
@PrimaryKey @SerializedName("uuid") val uuid: String,
@SerializedName("description") val description: String,
@SerializedName("alive") val isAlive: Boolean,
@@ -23,12 +23,12 @@ import android.content.ContentResolver
import android.net.Uri
import com.github.amsacode.predict4java.TLE
import com.rtbishop.look4sat.data.SatEntry
import com.rtbishop.look4sat.data.SatTrans
import com.rtbishop.look4sat.data.TleSource
import com.rtbishop.look4sat.data.Transmitter
import com.rtbishop.look4sat.repo.api.TransmittersApi
import com.rtbishop.look4sat.repo.dao.EntriesDao
import com.rtbishop.look4sat.repo.dao.SourcesDao
import com.rtbishop.look4sat.repo.dao.TransmittersDao
import com.rtbishop.look4sat.repo.local.EntriesDao
import com.rtbishop.look4sat.repo.local.SourcesDao
import com.rtbishop.look4sat.repo.local.TransDao
import com.rtbishop.look4sat.repo.remote.TransApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
@@ -39,10 +39,10 @@ import javax.inject.Inject
class DefaultRepository @Inject constructor(
private val resolver: ContentResolver,
private val client: OkHttpClient,
private val api: TransmittersApi,
private val api: TransApi,
private val entriesDao: EntriesDao,
private val sourcesDao: SourcesDao,
private val transmittersDao: TransmittersDao
private val transDao: TransDao
) : Repository {
override suspend fun updateEntriesFromFile(tleUri: Uri) {
@@ -82,8 +82,8 @@ class DefaultRepository @Inject constructor(
return@withContext streams
}
override suspend fun fetchTransmitters(): List<Transmitter> {
return api.fetchTransmitters()
override suspend fun fetchTransmitters(): List<SatTrans> {
return api.fetchTransList()
}
override suspend fun insertEntries(entries: List<SatEntry>) {
@@ -112,12 +112,12 @@ class DefaultRepository @Inject constructor(
override suspend fun updateTransmitters() {
}
override suspend fun getTransmittersByCatNum(catNum: Int): List<Transmitter> {
return transmittersDao.getTransmittersByCatNum(catNum)
override suspend fun getTransmittersByCatNum(catNum: Int): List<SatTrans> {
return transDao.getTransmittersForCatNum(catNum)
}
override suspend fun clearTransmitters() {
transmittersDao.clearTransmitters()
transDao.clearTransmitters()
}
////////////////////////////////////////////////////////////////////////////////////////////////
@@ -2,8 +2,8 @@ package com.rtbishop.look4sat.repo
import android.net.Uri
import com.rtbishop.look4sat.data.SatEntry
import com.rtbishop.look4sat.data.SatTrans
import com.rtbishop.look4sat.data.TleSource
import com.rtbishop.look4sat.data.Transmitter
import java.io.InputStream
interface Repository {
@@ -16,7 +16,7 @@ interface Repository {
suspend fun fetchTleStreams(urlList: List<TleSource>): List<InputStream>
suspend fun fetchTransmitters(): List<Transmitter>
suspend fun fetchTransmitters(): List<SatTrans>
suspend fun insertEntries(entries: List<SatEntry>)
@@ -32,7 +32,7 @@ interface Repository {
suspend fun updateTransmitters()
suspend fun getTransmittersByCatNum(catNum: Int): List<Transmitter>
suspend fun getTransmittersByCatNum(catNum: Int): List<SatTrans>
suspend fun clearTransmitters()
@@ -17,7 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.rtbishop.look4sat.repo.dao
package com.rtbishop.look4sat.repo.local
import androidx.room.Dao
import androidx.room.Insert
@@ -17,30 +17,27 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.rtbishop.look4sat.repo
package com.rtbishop.look4sat.repo.local
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.rtbishop.look4sat.data.SatEntry
import com.rtbishop.look4sat.data.SatTrans
import com.rtbishop.look4sat.data.TleSource
import com.rtbishop.look4sat.data.Transmitter
import com.rtbishop.look4sat.repo.dao.EntriesDao
import com.rtbishop.look4sat.repo.dao.SourcesDao
import com.rtbishop.look4sat.repo.dao.TransmittersDao
import com.rtbishop.look4sat.utility.Converters
@Database(
entities = [Transmitter::class, SatEntry::class, TleSource::class],
entities = [SatTrans::class, SatEntry::class, TleSource::class],
version = 1,
exportSchema = false
)
@TypeConverters(Converters::class)
abstract class SatelliteDb : RoomDatabase() {
abstract class SatDb : RoomDatabase() {
abstract fun entriesDao(): EntriesDao
abstract fun transmittersDao(): TransmittersDao
abstract fun transDao(): TransDao
abstract fun sourcesDao(): SourcesDao
}
@@ -1,4 +1,4 @@
package com.rtbishop.look4sat.repo.dao
package com.rtbishop.look4sat.repo.local
import androidx.room.Dao
import androidx.room.Insert
@@ -1,19 +1,19 @@
package com.rtbishop.look4sat.repo.dao
package com.rtbishop.look4sat.repo.local
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.rtbishop.look4sat.data.Transmitter
import com.rtbishop.look4sat.data.SatTrans
@Dao
interface TransmittersDao {
interface TransDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertTransmitters(transmitters: List<Transmitter>)
suspend fun insertTransmitters(satTrans: List<SatTrans>)
@Query("SELECT * FROM transmitters WHERE isAlive = 1 and catNum = :catNum")
suspend fun getTransmittersByCatNum(catNum: Int): List<Transmitter>
suspend fun getTransmittersForCatNum(catNum: Int): List<SatTrans>
@Query("DELETE FROM transmitters")
suspend fun clearTransmitters()
@@ -17,13 +17,13 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.rtbishop.look4sat.repo.api
package com.rtbishop.look4sat.repo.remote
import com.rtbishop.look4sat.data.Transmitter
import com.rtbishop.look4sat.data.SatTrans
import retrofit2.http.GET
interface TransmittersApi {
interface TransApi {
@GET("transmitters/")
suspend fun fetchTransmitters(): List<Transmitter>
suspend fun fetchTransList(): List<SatTrans>
}
@@ -19,7 +19,6 @@ class MainActivity : AppCompatActivity() {
// )
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
@@ -48,7 +47,7 @@ class MainActivity : AppCompatActivity() {
// }
// private fun openSourcesDialog() {
// TleSourcesDialogFragment(viewModel.getTleSources()).apply {
// SourcesDialog(viewModel.getTleSources()).apply {
// setSourcesListener(this@MainActivity)
// show(supportFragmentManager, "TleSourcesDialog")
// }
@@ -26,8 +26,8 @@ import androidx.recyclerview.widget.RecyclerView
import com.rtbishop.look4sat.data.SatEntry
import com.rtbishop.look4sat.databinding.ItemSatEntryBinding
class SatEntryAdapter(private var entries: MutableList<SatEntry>) :
RecyclerView.Adapter<SatEntryAdapter.SatEntryHolder>() {
class EntriesAdapter(private var entries: MutableList<SatEntry>) :
RecyclerView.Adapter<EntriesAdapter.SatEntryHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SatEntryHolder {
val binding = ItemSatEntryBinding
@@ -29,12 +29,12 @@ import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.data.SatPass
import com.rtbishop.look4sat.databinding.ItemPassGeoBinding
import com.rtbishop.look4sat.databinding.ItemPassLeoBinding
import com.rtbishop.look4sat.ui.fragments.PassListFragmentDirections
import com.rtbishop.look4sat.ui.fragments.PassesFragmentDirections
import com.rtbishop.look4sat.utility.PrefsManager
import java.text.SimpleDateFormat
import java.util.*
class SatPassAdapter(
class PassesAdapter(
private var satPassList: MutableList<SatPass>,
private val prefsManager: PrefsManager
) :
@@ -125,7 +125,7 @@ class SatPassAdapter(
itemView.setOnClickListener {
val passIndex = satPassList.indexOf(satPass)
val action = PassListFragmentDirections.actionPassToPolar(passIndex)
val action = PassesFragmentDirections.actionPassToPolar(passIndex)
itemView.findNavController().navigate(action)
}
}
@@ -148,7 +148,7 @@ class SatPassAdapter(
itemView.setOnClickListener {
val passIndex = satPassList.indexOf(satPass)
val action = PassListFragmentDirections.actionPassToPolar(passIndex)
val action = PassesFragmentDirections.actionPassToPolar(passIndex)
itemView.findNavController().navigate(action)
}
}
@@ -28,8 +28,8 @@ import androidx.recyclerview.widget.RecyclerView
import com.rtbishop.look4sat.data.TleSource
import com.rtbishop.look4sat.databinding.ItemTleSourceBinding
class TleSourcesAdapter(private var sources: MutableList<TleSource>) :
RecyclerView.Adapter<TleSourcesAdapter.TleSourceHolder>() {
class SourcesAdapter(private var sources: MutableList<TleSource>) :
RecyclerView.Adapter<SourcesAdapter.TleSourceHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TleSourceHolder {
val binding = ItemTleSourceBinding
@@ -25,21 +25,21 @@ import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.data.Transmitter
import com.rtbishop.look4sat.databinding.ItemTransmitterBinding
import com.rtbishop.look4sat.data.SatTrans
import com.rtbishop.look4sat.databinding.ItemTransBinding
import com.rtbishop.look4sat.utility.PassPredictor
import java.util.*
class TransmitterAdapter : RecyclerView.Adapter<TransmitterAdapter.TransmitterHolder>() {
class TransAdapter : RecyclerView.Adapter<TransAdapter.TransHolder>() {
private var transmittersList = emptyList<Transmitter>()
private var transmittersList = emptyList<SatTrans>()
private lateinit var predictor: PassPredictor
fun setPredictor(predict: PassPredictor) {
predictor = predict
}
fun setList(list: List<Transmitter>) {
fun setList(list: List<SatTrans>) {
transmittersList = list
}
@@ -47,86 +47,86 @@ class TransmitterAdapter : RecyclerView.Adapter<TransmitterAdapter.TransmitterHo
return transmittersList.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransmitterHolder {
val binding = ItemTransmitterBinding
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransHolder {
val binding = ItemTransBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
return TransmitterHolder(binding.root, binding)
return TransHolder(binding.root, binding)
}
override fun onBindViewHolder(holder: TransmitterHolder, position: Int) {
override fun onBindViewHolder(holder: TransHolder, position: Int) {
holder.bind(transmittersList[position])
}
inner class TransmitterHolder(itemView: View, private val binding: ItemTransmitterBinding) :
inner class TransHolder(itemView: View, private val binding: ItemTransBinding) :
RecyclerView.ViewHolder(itemView) {
fun bind(transmitter: Transmitter) {
fun bind(satTrans: SatTrans) {
val context: Context = itemView.context
val freqDivider = 1000000f
binding.transDescription.text = transmitter.description
binding.transDescription.text = satTrans.description
if (transmitter.downlinkLow != null && transmitter.downlinkHigh == null) {
if (satTrans.downlinkLow != null && satTrans.downlinkHigh == null) {
binding.transDownlink.text = String
.format(
context.getString(R.string.trans_down_low),
transmitter.downlinkLow / freqDivider
satTrans.downlinkLow / freqDivider
)
binding.transDownlinkDoppler.text = String
.format(
context.getString(R.string.trans_down_low_doppler),
predictor.getDownlinkFreq(transmitter.downlinkLow, Date()) / freqDivider
predictor.getDownlinkFreq(satTrans.downlinkLow, Date()) / freqDivider
)
} else if (transmitter.downlinkLow != null && transmitter.downlinkHigh != null) {
} else if (satTrans.downlinkLow != null && satTrans.downlinkHigh != null) {
binding.transDownlink.text = String
.format(
context.getString(R.string.trans_down_lowHigh),
transmitter.downlinkLow / freqDivider,
transmitter.downlinkHigh / freqDivider
satTrans.downlinkLow / freqDivider,
satTrans.downlinkHigh / freqDivider
)
binding.transDownlinkDoppler.text = String
.format(
context.getString(R.string.trans_down_lowHigh_doppler),
predictor.getDownlinkFreq(transmitter.downlinkLow, Date()) / freqDivider,
predictor.getDownlinkFreq(transmitter.downlinkHigh, Date()) / freqDivider
predictor.getDownlinkFreq(satTrans.downlinkLow, Date()) / freqDivider,
predictor.getDownlinkFreq(satTrans.downlinkHigh, Date()) / freqDivider
)
} else {
binding.transDownlink.text = context.getString(R.string.no_downlink)
binding.transDownlinkDoppler.text = context.getString(R.string.no_downlink_doppler)
}
if (transmitter.uplinkLow != null && transmitter.uplinkHigh == null) {
if (satTrans.uplinkLow != null && satTrans.uplinkHigh == null) {
binding.transUplink.text = String.format(
context.getString(R.string.trans_up_low),
transmitter.uplinkLow / freqDivider
satTrans.uplinkLow / freqDivider
)
binding.transUplinkDoppler.text = String.format(
context.getString(R.string.trans_up_low_doppler),
predictor.getUplinkFreq(transmitter.uplinkLow, Date()) / freqDivider
predictor.getUplinkFreq(satTrans.uplinkLow, Date()) / freqDivider
)
} else if (transmitter.uplinkLow != null && transmitter.uplinkHigh != null) {
} else if (satTrans.uplinkLow != null && satTrans.uplinkHigh != null) {
binding.transUplink.text = String.format(
context.getString(R.string.trans_up_lowHigh),
transmitter.uplinkLow / freqDivider,
transmitter.uplinkHigh / freqDivider
satTrans.uplinkLow / freqDivider,
satTrans.uplinkHigh / freqDivider
)
binding.transUplinkDoppler.text = String.format(
context.getString(R.string.trans_up_lowHigh_doppler),
predictor.getUplinkFreq(transmitter.uplinkLow, Date()) / freqDivider,
predictor.getUplinkFreq(transmitter.uplinkHigh, Date()) / freqDivider
predictor.getUplinkFreq(satTrans.uplinkLow, Date()) / freqDivider,
predictor.getUplinkFreq(satTrans.uplinkHigh, Date()) / freqDivider
)
} else {
binding.transUplink.text = context.getString(R.string.no_uplink)
binding.transUplinkDoppler.text = context.getString(R.string.no_uplink_doppler)
}
if (transmitter.mode != null) {
if (satTrans.mode != null) {
binding.transMode.text =
String.format(context.getString(R.string.trans_mode), transmitter.mode)
String.format(context.getString(R.string.trans_mode), satTrans.mode)
} else {
binding.transMode.text = context.getString(R.string.no_mode)
}
if (transmitter.isInverted) {
if (satTrans.isInverted) {
binding.transInverted.text = String.format(
context.getString(R.string.trans_inverted),
context.getString(R.string.btn_yes)
@@ -31,9 +31,9 @@ class AboutFragment : Fragment(R.layout.fragment_about) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = FragmentAboutBinding.bind(view)
binding.tvAboutVersion.text =
String.format(getString(R.string.app_version), BuildConfig.VERSION_NAME)
binding.tvAboutMessage.movementMethod = LinkMovementMethod.getInstance()
FragmentAboutBinding.bind(view).apply {
version.text = String.format(getString(R.string.app_version), BuildConfig.VERSION_NAME)
message.movementMethod = LinkMovementMethod.getInstance()
}
}
}
@@ -27,19 +27,19 @@ import android.widget.SearchView
import androidx.appcompat.app.AppCompatDialogFragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.rtbishop.look4sat.data.SatEntry
import com.rtbishop.look4sat.databinding.DialogSatEntryBinding
import com.rtbishop.look4sat.ui.adapters.SatEntryAdapter
import com.rtbishop.look4sat.databinding.DialogEntriesBinding
import com.rtbishop.look4sat.ui.adapters.EntriesAdapter
import java.util.*
class SatEntryDialogFragment(private var entries: MutableList<SatEntry>) :
class EntriesDialog(private var entries: MutableList<SatEntry>) :
AppCompatDialogFragment(), SearchView.OnQueryTextListener {
private lateinit var entriesListener: EntriesSubmitListener
private val entryAdapter = SatEntryAdapter(entries)
private val entryAdapter = EntriesAdapter(entries)
private var selectAllToggle = true
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val binding = DialogSatEntryBinding.inflate(requireActivity().layoutInflater)
val binding = DialogEntriesBinding.inflate(requireActivity().layoutInflater)
val satEntryDialog = Dialog(requireActivity()).apply {
window?.requestFeature(Window.FEATURE_NO_TITLE)
setContentView(binding.root)
@@ -50,7 +50,7 @@ class SatEntryDialogFragment(private var entries: MutableList<SatEntry>) :
}
binding.dialogSearch.apply {
setOnQueryTextListener(this@SatEntryDialogFragment)
setOnQueryTextListener(this@EntriesDialog)
onActionViewExpanded()
clearFocus()
}
@@ -67,7 +67,7 @@ class SatEntryDialogFragment(private var entries: MutableList<SatEntry>) :
return satEntryDialog
}
fun setEntriesListener(listener: EntriesSubmitListener): SatEntryDialogFragment {
fun setEntriesListener(listener: EntriesSubmitListener): EntriesDialog {
entriesListener = listener
return this
}
@@ -0,0 +1,17 @@
package com.rtbishop.look4sat.ui.fragments
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.databinding.FragmentEntriesBinding
class EntriesFragment : Fragment(R.layout.fragment_entries) {
private lateinit var binding: FragmentEntriesBinding
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentEntriesBinding.bind(view)
}
}
@@ -20,7 +20,7 @@ import com.rtbishop.look4sat.dagger.ViewModelFactory
import com.rtbishop.look4sat.data.Result
import com.rtbishop.look4sat.data.SatItem
import com.rtbishop.look4sat.data.SatPass
import com.rtbishop.look4sat.databinding.FragmentMapOsmBinding
import com.rtbishop.look4sat.databinding.FragmentMapBinding
import com.rtbishop.look4sat.ui.SharedViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@@ -39,13 +39,13 @@ import javax.inject.Inject
import kotlin.math.pow
import kotlin.math.sqrt
class MapOsmFragment : Fragment(R.layout.fragment_map_osm) {
class MapFragment : Fragment(R.layout.fragment_map) {
@Inject
lateinit var modelFactory: ViewModelFactory
private lateinit var mainActivity: FragmentActivity
private lateinit var viewModel: SharedViewModel
private lateinit var binding: FragmentMapOsmBinding
private lateinit var binding: FragmentMapBinding
private lateinit var trackPaint: Paint
private lateinit var footprintPaint: Paint
private lateinit var selectedPass: SatPass
@@ -53,7 +53,7 @@ class MapOsmFragment : Fragment(R.layout.fragment_map_osm) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentMapOsmBinding.bind(view)
binding = FragmentMapBinding.bind(view)
mainActivity = requireActivity()
(mainActivity.application as Look4SatApp).appComponent.inject(this)
viewModel = ViewModelProvider(mainActivity, modelFactory).get(SharedViewModel::class.java)
@@ -36,9 +36,9 @@ import com.rtbishop.look4sat.dagger.ViewModelFactory
import com.rtbishop.look4sat.data.Result
import com.rtbishop.look4sat.data.SatEntry
import com.rtbishop.look4sat.data.SatPass
import com.rtbishop.look4sat.databinding.FragmentPassListBinding
import com.rtbishop.look4sat.databinding.FragmentPassesBinding
import com.rtbishop.look4sat.ui.SharedViewModel
import com.rtbishop.look4sat.ui.adapters.SatPassAdapter
import com.rtbishop.look4sat.ui.adapters.PassesAdapter
import com.rtbishop.look4sat.utility.Extensions.snack
import com.rtbishop.look4sat.utility.PrefsManager
import kotlinx.coroutines.launch
@@ -46,7 +46,7 @@ import java.util.*
import java.util.concurrent.TimeUnit
import javax.inject.Inject
class PassListFragment : Fragment(R.layout.fragment_pass_list) {
class PassesFragment : Fragment(R.layout.fragment_passes) {
@Inject
lateinit var modelFactory: ViewModelFactory
@@ -55,10 +55,10 @@ class PassListFragment : Fragment(R.layout.fragment_pass_list) {
lateinit var prefsManager: PrefsManager
private lateinit var viewModel: SharedViewModel
private lateinit var satPassAdapter: SatPassAdapter
private lateinit var passesAdapter: PassesAdapter
private lateinit var aosTimer: CountDownTimer
private lateinit var mainActivity: FragmentActivity
private lateinit var binding: FragmentPassListBinding
private lateinit var binding: FragmentPassesBinding
private var isTimerSet: Boolean = false
private var satPassList: MutableList<SatPass> = mutableListOf()
@@ -66,10 +66,10 @@ class PassListFragment : Fragment(R.layout.fragment_pass_list) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mainActivity = requireActivity()
binding = FragmentPassListBinding.bind(view)
binding = FragmentPassesBinding.bind(view)
(mainActivity.application as Look4SatApp).appComponent.inject(this)
viewModel = ViewModelProvider(mainActivity, modelFactory).get(SharedViewModel::class.java)
satPassAdapter = SatPassAdapter(satPassList, prefsManager)
passesAdapter = PassesAdapter(satPassList, prefsManager)
setupObservers()
setupComponents()
@@ -77,7 +77,7 @@ class PassListFragment : Fragment(R.layout.fragment_pass_list) {
override fun onStart() {
super.onStart()
if (satPassAdapter.itemCount == 0) {
if (passesAdapter.itemCount == 0) {
viewModel.calculatePasses()
}
}
@@ -87,41 +87,29 @@ class PassListFragment : Fragment(R.layout.fragment_pass_list) {
when (result) {
is Result.Success -> {
satPassList = result.data
satPassAdapter.setList(satPassList)
if (satPassList.isNotEmpty()) {
binding.layoutInfo.visibility = View.INVISIBLE
binding.recPassList.visibility = View.VISIBLE
} else {
binding.layoutInfo.visibility = View.VISIBLE
binding.recPassList.visibility = View.INVISIBLE
}
passesAdapter.setList(satPassList)
setTimer()
// binding.refLayoutPassList.isRefreshing = false
}
is Result.InProgress -> {
// binding.refLayoutPassList.isRefreshing = true
}
}
})
}
private fun setupComponents() {
binding.recPassList.apply {
binding.passesRecycler.apply {
layoutManager = LinearLayoutManager(mainActivity)
adapter = satPassAdapter
adapter = passesAdapter
isVerticalScrollBarEnabled = false
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
}
satPassAdapter.setList(satPassList)
passesAdapter.setList(satPassList)
setTimer()
// binding.refLayoutPassList.setProgressBackgroundColorSchemeResource(R.color.themeAccent)
// binding.refLayoutPassList.setColorSchemeResources(R.color.backgroundDark)
// binding.refLayoutPassList.setOnRefreshListener { viewModel.calculatePasses() }
binding.toolbarFilter.setOnClickListener {
binding.passesFilter.setOnClickListener {
showSatPassPrefsDialog(viewModel.getHoursAhead(), viewModel.getMinElevation())
}
binding.fabSatSelect.setOnClickListener {
binding.passesFab.setOnClickListener {
lifecycleScope.launch {
val list = viewModel.getAllEntries() as MutableList
if (list.isEmpty()) {
@@ -134,7 +122,7 @@ class PassListFragment : Fragment(R.layout.fragment_pass_list) {
}
private fun showSatPassPrefsDialog(hoursAhead: Int, minEl: Double) {
val satPassPrefView = View.inflate(mainActivity, R.layout.dialog_pass_pref, null)
val satPassPrefView = View.inflate(mainActivity, R.layout.dialog_passes, null)
val etHoursAhead = satPassPrefView.findViewById<EditText>(R.id.pref_et_hoursAhead)
val etMinEl = satPassPrefView.findViewById<EditText>(R.id.pref_et_minEl)
etHoursAhead.setText(hoursAhead.toString())
@@ -172,15 +160,15 @@ class PassListFragment : Fragment(R.layout.fragment_pass_list) {
}
private fun showSelectSatDialog(tleMainList: MutableList<SatEntry>) {
val listener = object : SatEntryDialogFragment.EntriesSubmitListener {
val listener = object : EntriesDialog.EntriesSubmitListener {
override fun onEntriesSubmit(catNumList: MutableList<Int>) {
viewModel.updateEntriesSelection(catNumList)
}
}
SatEntryDialogFragment(tleMainList).apply {
EntriesDialog(tleMainList).apply {
setEntriesListener(listener)
show(mainActivity.supportFragmentManager, "SatEntryDialogFragment")
show(mainActivity.supportFragmentManager, "EntriesDialog")
}
}
@@ -210,13 +198,13 @@ class PassListFragment : Fragment(R.layout.fragment_pass_list) {
}
override fun onTick(millisUntilFinished: Long) {
binding.toolbarTimer.text = String.format(
binding.passesTimer.text = String.format(
mainActivity.getString(R.string.pat_timer),
TimeUnit.MILLISECONDS.toHours(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60
)
satPassAdapter.updateRecycler()
passesAdapter.updateRecycler()
}
}
}
@@ -230,13 +218,13 @@ class PassListFragment : Fragment(R.layout.fragment_pass_list) {
}
override fun onTick(millisUntilFinished: Long) {
binding.toolbarTimer.text = String.format(
binding.passesTimer.text = String.format(
mainActivity.getString(R.string.pat_timer),
TimeUnit.MILLISECONDS.toHours(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60
)
satPassAdapter.updateRecycler()
passesAdapter.updateRecycler()
}
}
}
@@ -246,7 +234,7 @@ class PassListFragment : Fragment(R.layout.fragment_pass_list) {
aosTimer.cancel()
isTimerSet = false
}
if (resetToNull) binding.toolbarTimer.text =
if (resetToNull) binding.passesTimer.text =
String.format(getString(R.string.pat_timer), 0, 0, 0)
}
}
@@ -34,9 +34,9 @@ import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.dagger.ViewModelFactory
import com.rtbishop.look4sat.data.Result
import com.rtbishop.look4sat.data.SatPass
import com.rtbishop.look4sat.databinding.FragmentPolarViewBinding
import com.rtbishop.look4sat.databinding.FragmentPolarBinding
import com.rtbishop.look4sat.ui.SharedViewModel
import com.rtbishop.look4sat.ui.adapters.TransmitterAdapter
import com.rtbishop.look4sat.ui.adapters.TransAdapter
import com.rtbishop.look4sat.ui.views.PolarView
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -44,28 +44,28 @@ import java.util.*
import javax.inject.Inject
import kotlin.math.round
class PolarViewFragment : Fragment(R.layout.fragment_polar_view), SensorEventListener {
class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
@Inject
lateinit var modelFactory: ViewModelFactory
private lateinit var mainActivity: FragmentActivity
private lateinit var viewModel: SharedViewModel
private lateinit var binding: FragmentPolarViewBinding
private lateinit var binding: FragmentPolarBinding
private lateinit var satPass: SatPass
private lateinit var sensorManager: SensorManager
private var polarView: PolarView? = null
private val args: PolarViewFragmentArgs by navArgs()
private val transmitterAdapter = TransmitterAdapter()
private val args: PolarFragmentArgs by navArgs()
private val transmitterAdapter = TransAdapter()
private var magneticDeclination = 0f
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mainActivity = requireActivity()
binding = FragmentPolarViewBinding.bind(view)
binding = FragmentPolarBinding.bind(view)
(mainActivity.application as Look4SatApp).appComponent.inject(this)
viewModel = ViewModelProvider(mainActivity, modelFactory).get(SharedViewModel::class.java)
sensorManager = mainActivity.getSystemService(Context.SENSOR_SERVICE) as SensorManager
binding.recPolar.apply {
binding.recycler.apply {
layoutManager = LinearLayoutManager(mainActivity)
adapter = transmitterAdapter
}
@@ -111,7 +111,7 @@ class PolarViewFragment : Fragment(R.layout.fragment_polar_view), SensorEventLis
val refreshRate = viewModel.getRefreshRate()
satPass = result.data[args.satPassIndex]
polarView = PolarView(mainActivity, satPass)
binding.framePolar.addView(polarView)
binding.frame.addView(polarView)
observeTransmitters()
refreshText(refreshRate)
}
@@ -124,11 +124,11 @@ class PolarViewFragment : Fragment(R.layout.fragment_polar_view), SensorEventLis
transmitterAdapter.setPredictor(satPass.predictor)
transmitterAdapter.setList(it)
transmitterAdapter.notifyDataSetChanged()
binding.recPolar.visibility = View.VISIBLE
binding.tvPolarNoTrans.visibility = View.INVISIBLE
binding.recycler.visibility = View.VISIBLE
binding.noTransMsg.visibility = View.INVISIBLE
} else {
binding.recPolar.visibility = View.INVISIBLE
binding.tvPolarNoTrans.visibility = View.VISIBLE
binding.recycler.visibility = View.INVISIBLE
binding.noTransMsg.visibility = View.VISIBLE
}
})
}
@@ -164,9 +164,9 @@ class PolarViewFragment : Fragment(R.layout.fragment_polar_view), SensorEventLis
val polarEl = mainActivity.getString(R.string.pat_elevation)
val polarRng = mainActivity.getString(R.string.pat_distance)
val polarAlt = mainActivity.getString(R.string.pat_altitude)
binding.tvPolarAz.text = String.format(polarAz, Math.toDegrees(satPos.azimuth))
binding.tvPolarEl.text = String.format(polarEl, Math.toDegrees(satPos.elevation))
binding.tvPolarRng.text = String.format(polarRng, satPos.range)
binding.tvPolarAlt.text = String.format(polarAlt, satPos.altitude)
binding.azimuth.text = String.format(polarAz, Math.toDegrees(satPos.azimuth))
binding.elevation.text = String.format(polarEl, Math.toDegrees(satPos.elevation))
binding.distance.text = String.format(polarRng, satPos.range)
binding.altitude.text = String.format(polarAlt, satPos.altitude)
}
}
@@ -27,7 +27,7 @@ import androidx.preference.PreferenceFragmentCompat
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.utility.Extensions.snack
class PreferencesFragment : PreferenceFragmentCompat(),
class PrefsFragment : PreferenceFragmentCompat(),
SharedPreferences.OnSharedPreferenceChangeListener {
private lateinit var keyLat: String
@@ -26,18 +26,18 @@ import android.view.Window
import androidx.appcompat.app.AppCompatDialogFragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.rtbishop.look4sat.data.TleSource
import com.rtbishop.look4sat.databinding.DialogTleSourcesBinding
import com.rtbishop.look4sat.ui.adapters.TleSourcesAdapter
import com.rtbishop.look4sat.databinding.DialogSourcesBinding
import com.rtbishop.look4sat.ui.adapters.SourcesAdapter
class TleSourcesDialogFragment(sources: List<TleSource>) :
class SourcesDialog(sources: List<TleSource>) :
AppCompatDialogFragment() {
private lateinit var sourcesListener: SourcesSubmitListener
private val emptySource = TleSource("")
private val sourcesAdapter = TleSourcesAdapter(sources.toMutableList())
private val sourcesAdapter = SourcesAdapter(sources.toMutableList())
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val binding = DialogTleSourcesBinding.inflate(requireActivity().layoutInflater)
val binding = DialogSourcesBinding.inflate(requireActivity().layoutInflater)
val tleSourcesDialog = Dialog(requireActivity()).apply {
window?.requestFeature(Window.FEATURE_NO_TITLE)
setContentView(binding.root)
@@ -70,7 +70,7 @@ class TleSourcesDialogFragment(sources: List<TleSource>) :
return tleSourcesDialog
}
fun setSourcesListener(listener: SourcesSubmitListener): TleSourcesDialogFragment {
fun setSourcesListener(listener: SourcesSubmitListener): SourcesDialog {
sourcesListener = listener
return this
}
@@ -1,171 +0,0 @@
package com.rtbishop.look4sat.ui.views
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.view.View
import androidx.core.content.ContextCompat
import com.github.amsacode.predict4java.GroundStationPosition
import com.github.amsacode.predict4java.Position
import com.github.amsacode.predict4java.SatPos
import com.github.amsacode.predict4java.TLE
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.data.SatPass
import java.util.*
import kotlin.math.abs
class MapView(context: Context) : View(context) {
constructor(context: Context, groundStationPosition: GroundStationPosition) : this(context) {
gsp = groundStationPosition
}
private lateinit var passList: List<SatPass>
private lateinit var gsp: GroundStationPosition
private lateinit var selectedSat: TLE
private val scale = resources.displayMetrics.density
private val groundTrackPaint = Paint().apply {
isAntiAlias = true
color = ContextCompat.getColor(context, R.color.satTrack)
style = Paint.Style.STROKE
strokeWidth = scale
}
private val satPaintPrim = Paint().apply {
isAntiAlias = true
color = ContextCompat.getColor(context, R.color.satPrimary)
style = Paint.Style.STROKE
strokeWidth = scale
}
private val satPaintSec = Paint().apply {
isAntiAlias = true
color = ContextCompat.getColor(context, R.color.satSecondary)
style = Paint.Style.STROKE
strokeWidth = scale
}
private val txtPaint = Paint().apply {
isAntiAlias = true
color = ContextCompat.getColor(context, R.color.satPrimary)
style = Paint.Style.FILL
strokeWidth = scale
textSize = 16f
setShadowLayer(2f, 2f, 2f, Color.BLACK)
}
private val outlinePaint = Paint().apply {
isAntiAlias = true
color = Color.BLACK
style = Paint.Style.FILL_AND_STROKE
strokeWidth = scale
textSize = 16f
}
private val rect = Rect()
private var checked = 0
private var degLon = 0f
private var degLat = 0f
fun setList(satPassList: List<SatPass>) {
passList = satPassList
}
fun setChecked(item: Int) {
checked = item
selectedSat = passList[checked].tle
}
@SuppressLint("DrawAllocation")
override fun onDraw(canvas: Canvas) {
degLon = width / 360f
degLat = height / 180f
canvas.translate(width / 2f, height / 2f)
drawHomeLoc(canvas)
val currentTime = Date(System.currentTimeMillis())
val orbitalPeriod = (24 * 60 / selectedSat.meanmo).toInt()
val predictor = passList[checked].predictor
val positions = predictor.getPositions(currentTime, 60, 0, orbitalPeriod * 3)
drawGroundTrack(canvas, positions)
passList.forEach { satPass -> drawSat(canvas, satPass, currentTime, satPaintSec) }
drawSat(canvas, passList[checked], currentTime, satPaintPrim)
}
private fun drawHomeLoc(canvas: Canvas) {
val lon = gsp.longitude.toFloat()
val lat = gsp.latitude.toFloat() * -1
val cx = lon * degLon
val cy = lat * degLat
val gspName = context.getString(R.string.map_gsp)
txtPaint.getTextBounds(gspName, 0, gspName.length, rect)
canvas.drawCircle(cx, cy, scale * 2, txtPaint)
canvas.drawText(gspName, cx - rect.width() / 2, cy - txtPaint.textSize, outlinePaint)
canvas.drawText(gspName, cx - rect.width() / 2, cy - txtPaint.textSize, txtPaint)
}
private fun drawGroundTrack(canvas: Canvas, list: List<SatPos>) {
val path = Path()
var lon: Float
var lat: Float
var lastLon = 181f
list.withIndex().forEach { (index, satPos) ->
lon = Math.toDegrees(satPos.longitude).toFloat()
lat = Math.toDegrees(satPos.latitude).toFloat() * -1
if (lon > 180f) lon -= 360f
lon *= degLon
lat *= degLat
if (index == 0 || abs(lon - lastLon) > 180) path.moveTo(lon, lat)
else path.lineTo(lon, lat)
lastLon = lon
}
canvas.drawPath(path, groundTrackPaint)
}
private fun drawSat(canvas: Canvas, satPass: SatPass, date: Date, paint: Paint) {
val tle = satPass.tle
val predictor = satPass.predictor
val satPosNow = predictor.getSatPos(date)
val footprintPosList = satPosNow.rangeCircle
drawFootprint(canvas, footprintPosList, paint)
drawName(canvas, satPosNow, tle.name)
}
private fun drawFootprint(canvas: Canvas, list: List<Position>, paint: Paint) {
val path = Path()
var lon: Float
var lat: Float
var lastLon = 181f
list.withIndex().forEach { (index, position) ->
lon = position.lon.toFloat()
lat = position.lat.toFloat() * -1
if (lon > 180f) lon -= 360f
lon *= degLon
lat *= degLat
if (index == 0 || abs(lon - lastLon) > 180) path.moveTo(lon, lat)
else path.lineTo(lon, lat)
lastLon = lon
}
canvas.drawPath(path, paint)
}
private fun drawName(canvas: Canvas, position: SatPos, name: String) {
var lon = Math.toDegrees(position.longitude).toFloat()
val lat = Math.toDegrees(position.latitude).toFloat() * -1
if (lon > 180f) lon -= 360f
val cx = lon * degLon
val cy = lat * degLat
canvas.drawCircle(cx, cy, scale * 2, txtPaint)
txtPaint.getTextBounds(name, 0, name.length, rect)
canvas.drawText(name, cx - rect.width() / 2, cy - txtPaint.textSize, outlinePaint)
canvas.drawText(name, cx - rect.width() / 2, cy - txtPaint.textSize, txtPaint)
}
}
@@ -42,31 +42,17 @@ import java.util.*
class PassPredictor(private val tle: TLE, private val qth: GroundStationPosition) {
private val sat: Satellite = SatelliteFactory.createSatellite(tle)
private val south = "south"
private val north = "north"
private val deadSpotNone = "none"
private val speedOfLight = 2.99792458E8
private val twoPi = Math.PI * 2.0
private val timeZone: TimeZone = TimeZone.getTimeZone("UTC")
private var iterationCount = 0
fun getDownlinkFreq(freq: Long, date: Date): Long {
val cal = Calendar.getInstance(timeZone).apply {
clear()
timeInMillis = date.time
}
val satPos = getSatPos(cal.time)
val rangeRate = satPos.rangeRate
val rangeRate = getSatPos(date).rangeRate
return (freq.toDouble() * (speedOfLight - rangeRate * 1000.0) / speedOfLight).toLong()
}
fun getUplinkFreq(freq: Long, date: Date): Long {
val cal = Calendar.getInstance(timeZone).apply {
clear()
timeInMillis = date.time
}
val satPos = getSatPos(cal.time)
val rangeRate = satPos.rangeRate
val rangeRate = getSatPos(date).rangeRate
return (freq.toDouble() * (speedOfLight + rangeRate * 1000.0) / speedOfLight).toLong()
}
@@ -155,7 +141,7 @@ class PassPredictor(private val tle: TLE, private val qth: GroundStationPosition
var maxElevation = 0.0
var elevation: Double
var prevPos: SatPos
var polePassed = deadSpotNone
var polePassed = "none"
// get the current position
val cal = Calendar.getInstance(timeZone).apply {
@@ -206,7 +192,7 @@ class PassPredictor(private val tle: TLE, private val qth: GroundStationPosition
do {
satPos = getPosition(cal, 30)
val currPolePassed = getPolePassed(prevPos, satPos)
if (currPolePassed != deadSpotNone) {
if (currPolePassed != "none") {
polePassed = currPolePassed
}
elevation = satPos.elevation
@@ -242,23 +228,17 @@ class PassPredictor(private val tle: TLE, private val qth: GroundStationPosition
}
private fun getPolePassed(prevPos: SatPos, satPos: SatPos): String {
var polePassed = deadSpotNone
val az1 = prevPos.azimuth / twoPi * 360.0
val az2 = satPos.azimuth / twoPi * 360.0
var polePassed = "none"
val north = "north"
val south = "south"
val az1 = Math.toDegrees(prevPos.azimuth)
val az2 = Math.toDegrees(satPos.azimuth)
if (az1 > az2) {
// we may be moving from 350 or greater through north
if (az1 > 350 && az2 < 10) polePassed = north
else {
// we may be moving from 190 or greater through south
if (az1 > 180 && az2 < 180) polePassed = south
}
else if (az1 > 180 && az2 < 180) polePassed = south
} else {
// we may be moving from 10 or less through north
if (az1 < 10 && az2 > 350) polePassed = north
else {
// we may be moving from 170 or more through south
if (az1 < 180 && az2 > 180) polePassed = south
}
else if (az1 < 180 && az2 > 180) polePassed = south
}
return polePassed
}