Various changes to layouts and strings

This commit is contained in:
Arty Bishop committed 2022-03-01 18:32:59 +00:00
1 parent acc308379c
commit 930e05cc58
40 files changed
+538 -631

No files matched your search

@@ -74,7 +74,7 @@ class LocationHandler @Inject constructor(
}
} else {
_stationPosition.value =
DataState.Error(context.getString(R.string.pref_pos_manual_error))
DataState.Error(context.getString(R.string.location_manual_error))
}
}
@@ -89,7 +89,7 @@ class LocationHandler @Inject constructor(
manager.requestLocationUpdates(providerGps, 0L, 0f, this)
}
} else {
_stationPosition.value = DataState.Error(context.getString(R.string.pref_pos_gps_null))
_stationPosition.value = DataState.Error(context.getString(R.string.location_null))
}
}
@@ -104,7 +104,7 @@ class LocationHandler @Inject constructor(
manager.requestLocationUpdates(providerNet, 0L, 0f, this)
}
} else {
_stationPosition.value = DataState.Error(context.getString(R.string.pref_pos_gps_null))
_stationPosition.value = DataState.Error(context.getString(R.string.location_null))
}
}
@@ -117,7 +117,7 @@ class LocationHandler @Inject constructor(
settings.saveStationPosition(currentPosition)
_stationPosition.value = DataState.Success(currentPosition)
} else {
_stationPosition.value = DataState.Error(context.getString(R.string.pref_pos_qth_error))
_stationPosition.value = DataState.Error(context.getString(R.string.location_qth_error))
}
}
@@ -27,6 +27,9 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import javax.inject.Qualifier
import javax.inject.Singleton
@Module
@@ -56,4 +59,20 @@ object AppModule {
fun provideSharedPreferences(@ApplicationContext context: Context): SharedPreferences {
return context.getSharedPreferences("default", Context.MODE_PRIVATE)
}
@Provides
@DefaultDispatcher
fun provideDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default
@Provides
@IoDispatcher
fun provideIoDispatcher(): CoroutineDispatcher = Dispatchers.IO
}
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class DefaultDispatcher
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class IoDispatcher
@@ -1,55 +0,0 @@
/*
* Look4Sat. Amateur radio satellite tracker and pass predictor.
* Copyright (C) 2019-2021 Arty Bishop (bishop.arty@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.rtbishop.look4sat.injection
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import javax.inject.Qualifier
@Module
@InstallIn(SingletonComponent::class)
object KotlinModule {
@Provides
@DefaultDispatcher
fun provideDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default
@Provides
@IoDispatcher
fun provideIoDispatcher(): CoroutineDispatcher = Dispatchers.IO
@Provides
@MainDispatcher
fun provideMainDispatcher(): CoroutineDispatcher = Dispatchers.Main
}
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class DefaultDispatcher
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class IoDispatcher
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class MainDispatcher
@@ -27,7 +27,6 @@ import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator
import com.google.android.material.snackbar.Snackbar
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.databinding.FragmentEntriesBinding
import com.rtbishop.look4sat.domain.model.DataState
@@ -44,22 +43,14 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentEntriesBinding.bind(view)
setupComponents()
}
private fun setupComponents() {
val context = requireContext()
val adapter = EntriesAdapter(viewModel)
val layoutManager = GridLayoutManager(context, 2)
val itemDecoration = DividerItemDecoration(context, layoutManager.orientation)
binding.run {
val entriesAdapter = EntriesAdapter(viewModel)
binding = FragmentEntriesBinding.bind(view).apply {
entriesRecycler.apply {
setHasFixedSize(true)
this.adapter = adapter
this.layoutManager = layoutManager
addItemDecoration(itemDecoration)
adapter = entriesAdapter
layoutManager = GridLayoutManager(requireContext(), 2)
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
addItemDecoration(DividerItemDecoration(requireContext(), 1))
addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (dy > 0 && entriesFab.visibility == View.VISIBLE) entriesFab.hide()
@@ -67,29 +58,28 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) {
}
})
}
entriesBackBtn.setOnClickListener { findNavController().navigateUp() }
entriesBtnBack.setOnClickListener { findNavController().navigateUp() }
entriesSearch.doOnTextChanged { text, _, _, _ -> viewModel.setQuery(text.toString()) }
entriesModesBtn.setOnClickListener { navigateToModesDialog() }
entriesSelectBtn.setOnClickListener { viewModel.selectCurrentItems(true) }
entriesClearBtn.setOnClickListener { viewModel.selectCurrentItems(false) }
entriesBtnModes.setOnClickListener {
val direction = EntriesFragmentDirections.entriesToModes()
findNavController().navigate(direction)
}
entriesBtnSelect.setOnClickListener { viewModel.selectCurrentItems(true) }
entriesBtnClear.setOnClickListener { viewModel.selectCurrentItems(false) }
entriesFab.setOnClickListener {
setNavResult("selection", viewModel.saveSelection())
findNavController().popBackStack()
}
}
viewModel.satData.observe(viewLifecycleOwner) { satData ->
handleSatData(satData, binding, adapter)
handleSatData(satData, entriesAdapter)
}
getNavResult<List<String>>(R.id.nav_entries, "modes") { modes ->
viewModel.saveSelectedModes(modes)
}
}
private fun handleSatData(
dataState: DataState<List<SatItem>>,
binding: FragmentEntriesBinding,
entriesAdapter: EntriesAdapter
) {
private fun handleSatData(dataState: DataState<List<SatItem>>, entriesAdapter: EntriesAdapter) {
when (dataState) {
is DataState.Success -> {
entriesAdapter.submitList(dataState.data)
@@ -100,18 +90,7 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) {
binding.entriesProgress.visibility = View.VISIBLE
binding.entriesRecycler.visibility = View.INVISIBLE
}
is DataState.Error -> {
binding.entriesProgress.visibility = View.INVISIBLE
binding.entriesRecycler.visibility = View.VISIBLE
val message = getString(R.string.entries_update_error)
Snackbar.make(requireView(), message, Snackbar.LENGTH_SHORT).show()
}
DataState.Handled -> {}
else -> {}
}
}
private fun navigateToModesDialog() {
val direction = EntriesFragmentDirections.actionEntriesToModes()
findNavController().navigate(direction)
}
}
@@ -98,9 +98,9 @@ class MapFragment : Fragment(R.layout.fragment_map) {
// add overlays: 0 - GSP, 1 - SatTrack, 2 - SatFootprint, 3 - SatIcons
overlays.addAll(Array(4) { FolderOverlay() })
}
mapBackBtn.setOnClickListener { findNavController().navigateUp() }
mapPrevBtn.setOnClickListener { viewModel.scrollSelection(true) }
mapNextBtn.setOnClickListener { viewModel.scrollSelection(false) }
mapBtnBack.setOnClickListener { findNavController().navigateUp() }
mapBtnPrev.setOnClickListener { viewModel.scrollSelection(true) }
mapBtnNext.setOnClickListener { viewModel.scrollSelection(false) }
}
}
@@ -118,7 +118,7 @@ class MapFragment : Fragment(R.layout.fragment_map) {
Marker(mapView).apply {
setInfoWindow(null)
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_gps)
icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_position)
position = GeoPoint(stationPos.latitude, stationPos.longitude)
mapView.overlays[0] = this
mapView.invalidate()
@@ -206,13 +206,13 @@ class MapFragment : Fragment(R.layout.fragment_map) {
mapTitle.text = mapData.name
mapDataId.text = String.format(getString(R.string.map_sat_id), mapData.catNum)
mapDataQth.text = String.format(getString(R.string.map_qth), mapData.qthLoc)
mapDataAlt.text = String.format(getString(R.string.pat_altitude), mapData.altitude)
mapDataDst.text = String.format(getString(R.string.pat_distance), mapData.range)
mapDataVel.text = String.format(getString(R.string.pat_osm_vel), mapData.velocity)
mapDataAlt.text = String.format(getString(R.string.map_altitude), mapData.altitude)
mapDataDst.text = String.format(getString(R.string.map_distance), mapData.range)
mapDataVel.text = String.format(getString(R.string.map_velocity), mapData.velocity)
mapDataLat.text =
String.format(getString(R.string.pat_osm_lat), mapData.osmPos.latitude)
String.format(getString(R.string.map_latitude), mapData.osmPos.latitude)
mapDataLon.text =
String.format(getString(R.string.pat_osm_lon), mapData.osmPos.longitude)
String.format(getString(R.string.map_longitude), mapData.osmPos.longitude)
}
binding.mapView.invalidate()
}
@@ -33,7 +33,7 @@ class FilterDialog : AppCompatDialogFragment() {
)
filterHoursEdit.setText(preferences.getHoursAhead().toString())
filterElevEdit.setText(preferences.getMinElevation().toString())
filterPosBtn.setOnClickListener {
filterBtnPos.setOnClickListener {
val hoursAhead = try {
filterHoursEdit.text.toString().toInt()
} catch (exception: Exception) {
@@ -47,7 +47,7 @@ class FilterDialog : AppCompatDialogFragment() {
setNavResult("prefs", Pair(hoursAhead, minElevation))
dismiss()
}
filterNegBtn.setOnClickListener { dismiss() }
filterBtnNeg.setOnClickListener { dismiss() }
}
}
}
@@ -73,7 +73,7 @@ class PassesAdapter(private val clickListener: PassesClickListener) :
private val altFormat = itemView.context.getString(R.string.pass_altitude)
private val losAzFormat = itemView.context.getString(R.string.pass_los)
private val startTimeFormat = itemView.context.getString(R.string.pass_startTime)
private val elevFormat = itemView.context.getString(R.string.pat_elevation)
private val elevFormat = itemView.context.getString(R.string.pass_elevation)
private val endTimeFormat = itemView.context.getString(R.string.pass_endTime)
private val placeholder = itemView.context.getString(R.string.pass_placeholder)
private val timeZoneUTC = TimeZone.getTimeZone("UTC")
@@ -62,17 +62,17 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
}
})
}
passesRefreshBtn.setOnClickListener { viewModel.calculatePasses() }
passesMapBtn.setOnClickListener {
val dir = PassesFragmentDirections.actionGlobalMapFragment()
passesBtnRefresh.setOnClickListener { viewModel.calculatePasses() }
passesBtnMap.setOnClickListener {
val dir = PassesFragmentDirections.globalToMap()
findNavController().navigate(dir)
}
passesFilterBtn.setOnClickListener {
val dir = PassesFragmentDirections.actionPassesToFilter()
passesBtnFilter.setOnClickListener {
val dir = PassesFragmentDirections.passesToFilter()
findNavController().navigate(dir)
}
passesSettingsBtn.setOnClickListener {
val dir = PassesFragmentDirections.actionGlobalSettingsFragment()
passesBtnSettings.setOnClickListener {
val dir = PassesFragmentDirections.globalToSettings()
findNavController().navigate(dir)
}
setupAnimator()
@@ -82,7 +82,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
override fun navigateToPass(satPass: SatPass) {
if (satPass.progress < 100) satPass.run {
val dir = PassesFragmentDirections.actionGlobalRadarFragment(this.catNum, this.aosTime)
val dir = PassesFragmentDirections.globalToRadar(this.catNum, this.aosTime)
findNavController().navigate(dir)
}
}
@@ -98,7 +98,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
duration = 875
interpolator = LinearInterpolator()
repeatCount = ValueAnimator.INFINITE
addUpdateListener { binding?.passesRefreshBtn?.rotation = animatedValue as Float }
addUpdateListener { binding?.passesBtnRefresh?.rotation = animatedValue as Float }
}
}
@@ -121,7 +121,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
binding?.run {
if (number > 0) {
passesFab.setOnClickListener {
val direction = PassesFragmentDirections.actionGlobalEntriesFragment()
val direction = PassesFragmentDirections.globalToEntries()
findNavController().navigate(direction)
}
} else {
@@ -140,20 +140,18 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
passesAdapter.submitList(state.data)
tickMainTimer(state.data)
if (state.data.isNotEmpty()) { // show new passes list
passesRecycler.visibility = View.VISIBLE
passesEmpty.visibility = View.INVISIBLE
passesRefreshBtn.isEnabled = true
passesBtnRefresh.isEnabled = true
refreshAnimator?.cancel()
} else { // show no passes message
passesRecycler.visibility = View.INVISIBLE
passesEmpty.visibility = View.VISIBLE
passesRefreshBtn.isEnabled = true
passesBtnRefresh.isEnabled = true
refreshAnimator?.cancel()
}
}
is DataState.Loading -> {
refreshAnimator?.start()
passesRefreshBtn.isEnabled = false
passesBtnRefresh.isEnabled = false
passesTimer.text = 0L.toTimerString()
}
else -> {}
@@ -89,23 +89,23 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
viewModel.transmitters.observe(viewLifecycleOwner) { list ->
if (list.isNotEmpty()) {
radioAdapter.submitList(list)
radarRecyclerMsg.text = getString(R.string.trans_data)
radarEmptyMsg.text = getString(R.string.radio_data)
} else {
radarRecyclerMsg.text = getString(R.string.trans_no_data)
radarEmptyMsg.text = getString(R.string.radio_no_data)
}
radarView?.invalidate()
}
viewModel.orientation.observe(viewLifecycleOwner) { value ->
radarView?.setOrientation(value.first, value.second, value.third)
}
radarBack.setOnClickListener { findNavController().navigateUp() }
radarMap.setOnClickListener {
val direction = RadarFragmentDirections.actionGlobalMapFragment(pass.catNum)
radarBtnBack.setOnClickListener { findNavController().navigateUp() }
radarBtnMap.setOnClickListener {
val direction = RadarFragmentDirections.globalToMap(pass.catNum)
findNavController().navigate(direction)
}
radarBtnNotify.isEnabled = false
radarBtnSettings.setOnClickListener {
val direction = RadarFragmentDirections.actionGlobalSettingsFragment()
val direction = RadarFragmentDirections.globalToSettings()
findNavController().navigate(direction)
}
}
@@ -56,12 +56,12 @@ class RadioAdapter : RecyclerView.Adapter<RadioAdapter.TransHolder>() {
RecyclerView.ViewHolder(binding.root) {
private val divider = 1000000f
private val stringYes = itemView.context.getString(R.string.yes)
private val stringNo = itemView.context.getString(R.string.no)
private val link = itemView.context.getString(R.string.trans_link_low)
private val linkNull = itemView.context.getString(R.string.trans_no_link)
private val mode = itemView.context.getString(R.string.trans_mode)
private val inverted = itemView.context.getString(R.string.trans_inverted)
private val stringYes = itemView.context.getString(R.string.radio_string_yes)
private val stringNo = itemView.context.getString(R.string.radio_string_no)
private val link = itemView.context.getString(R.string.radio_link_low)
private val linkNull = itemView.context.getString(R.string.radio_no_link)
private val mode = itemView.context.getString(R.string.radio_mode)
private val inverted = itemView.context.getString(R.string.radio_inverted)
fun bind(radio: SatRadio) {
binding.run {
@@ -32,11 +32,11 @@ class LocatorDialog : AppCompatDialogFragment() {
WindowManager.LayoutParams.WRAP_CONTENT
)
locatorEdit.setText(preferences.loadStationLocator())
locatorPosBtn.setOnClickListener {
locatorBtnPos.setOnClickListener {
setNavResult("locator", locatorEdit.text.toString())
dismiss()
}
locatorNegBtn.setOnClickListener { dismiss() }
locatorBtnNeg.setOnClickListener { dismiss() }
}
}
}
@@ -7,48 +7,48 @@ import android.view.ViewGroup
import android.view.WindowManager
import androidx.appcompat.app.AppCompatDialogFragment
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.databinding.DialogLocationBinding
import com.rtbishop.look4sat.databinding.DialogPositionBinding
import com.rtbishop.look4sat.domain.ISettings
import com.rtbishop.look4sat.presentation.setNavResult
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class LocationDialog : AppCompatDialogFragment() {
class PositionDialog : AppCompatDialogFragment() {
@Inject
lateinit var preferences: ISettings
override fun onCreateView(inflater: LayoutInflater, group: ViewGroup?, state: Bundle?): View? {
return inflater.inflate(R.layout.dialog_location, group, false)
return inflater.inflate(R.layout.dialog_position, group, false)
}
override fun onViewCreated(view: View, state: Bundle?) {
super.onViewCreated(view, state)
DialogLocationBinding.bind(view).run {
DialogPositionBinding.bind(view).run {
dialog?.window?.setBackgroundDrawableResource(R.color.transparent)
dialog?.window?.setLayout(
(resources.displayMetrics.widthPixels * 0.94).toInt(),
WindowManager.LayoutParams.WRAP_CONTENT
)
val location = preferences.loadStationPosition()
locationLatEdit.setText(location.latitude.toString())
locationLonEdit.setText(location.longitude.toString())
locationPosBtn.setOnClickListener {
positionLatEdit.setText(location.latitude.toString())
positionLonEdit.setText(location.longitude.toString())
positionBtnPos.setOnClickListener {
val latitude = try {
locationLatEdit.text.toString().toDouble()
positionLatEdit.text.toString().toDouble()
} catch (exception: Exception) {
180.0
}
val longitude = try {
locationLonEdit.text.toString().toDouble()
positionLonEdit.text.toString().toDouble()
} catch (exception: Exception) {
400.0
}
setNavResult("location", Pair(latitude, longitude))
setNavResult("position", Pair(latitude, longitude))
dismiss()
}
locationNegBtn.setOnClickListener { dismiss() }
positionBtnNeg.setOnClickListener { dismiss() }
}
}
}
@@ -52,7 +52,7 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
when {
permissions[locationFine] == true -> viewModel.setPositionFromGps()
permissions[locationCoarse] == true -> viewModel.setPositionFromNet()
else -> showToast(getString(R.string.pref_pos_gps_error))
else -> showToast(getString(R.string.location_gps_error))
}
}
private val contentContract = ActivityResultContracts.GetContent()
@@ -63,27 +63,28 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentSettingsBinding.bind(view)
setupComponents()
setupObservers()
}
private fun setupComponents() {
binding.settingsScroll.apply {
setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, y, _, newY ->
if (y > newY) binding.settingsFab.hide() else binding.settingsFab.show()
binding = FragmentSettingsBinding.bind(view).apply {
settingsBtnBack.setOnClickListener { findNavController().navigateUp() }
settingsScroll.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, y, _, newY ->
if (y > newY) settingsFab.hide() else settingsFab.show()
})
settingsAbout.aboutVersion.text =
String.format(getString(R.string.app_version), BuildConfig.VERSION_NAME)
settingsBtnGithub.setOnClickListener {
gotoUrl("https://github.com/rt-bishop/Look4Sat/")
}
settingsFab.setOnClickListener {
gotoUrl("https://www.buymeacoffee.com/rtbishop")
}
settingsBtnFdroid.setOnClickListener {
gotoUrl("https://f-droid.org/en/packages/com.rtbishop.look4sat/")
}
}
binding.settingsBack.setOnClickListener { findNavController().navigateUp() }
setupAboutCard()
setupDataCard()
setupLocationCard()
setupTrackingCard()
setupDataCard()
setupRemoteCard()
setupOtherCard()
setupWarrantyCard()
}
private fun setupObservers() {
setupOutroCard()
viewModel.stationPosition.asLiveData().observe(viewLifecycleOwner) { stationPos ->
stationPos?.let { handleStationPosition(stationPos) }
}
@@ -92,140 +93,138 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
}
}
private fun setupAboutCard() {
binding.settingsInfo.aboutVersion.text =
String.format(getString(R.string.app_version), BuildConfig.VERSION_NAME)
binding.settingsGithubBtn.setOnClickListener {
gotoUrl("https://github.com/rt-bishop/Look4Sat/")
}
binding.settingsFab.setOnClickListener {
gotoUrl("https://www.buymeacoffee.com/rtbishop")
}
binding.settingsFdroidBtn.setOnClickListener {
gotoUrl("https://f-droid.org/en/packages/com.rtbishop.look4sat/")
}
}
private fun setupLocationCard() {
setPositionText(viewModel.getStationPosition())
binding.settingsLocation.positionBtnGps.setOnClickListener {
locationRequest.launch(arrayOf(locationFine, locationCoarse))
}
binding.settingsLocation.positionBtnManual.setOnClickListener {
val action = SettingsFragmentDirections.actionPrefsToLocation()
findNavController().navigate(action)
}
binding.settingsLocation.positionBtnQth.setOnClickListener {
val action = SettingsFragmentDirections.actionPrefsToLocator()
findNavController().navigate(action)
}
getNavResult<Pair<Double, Double>>(R.id.nav_settings, "location") { location ->
viewModel.setStationPosition(location.first, location.second)
}
getNavResult<String>(R.id.nav_settings, "locator") { locator ->
viewModel.setPositionFromQth(locator)
binding.run {
setPositionText(viewModel.getStationPosition())
settingsLocation.locationBtnGps.setOnClickListener {
locationRequest.launch(arrayOf(locationFine, locationCoarse))
}
settingsLocation.locationBtnManual.setOnClickListener {
val action = SettingsFragmentDirections.globalToPosition()
findNavController().navigate(action)
}
settingsLocation.locationBtnQth.setOnClickListener {
val action = SettingsFragmentDirections.globalToLocator()
findNavController().navigate(action)
}
getNavResult<Pair<Double, Double>>(R.id.nav_settings, "position") { position ->
viewModel.setStationPosition(position.first, position.second)
}
getNavResult<String>(R.id.nav_settings, "locator") { locator ->
viewModel.setPositionFromQth(locator)
}
}
}
private fun setupDataCard() {
binding.settingsData.dataBtnFile.setOnClickListener { contentRequest.launch("*/*") }
binding.settingsData.dataBtnWeb.setOnClickListener {
val action = SettingsFragmentDirections.actionPrefsToSources()
findNavController().navigate(action)
}
binding.settingsData.dataBtnClear.setOnClickListener { viewModel.clearData() }
viewModel.entriesTotal.observe(viewLifecycleOwner) { number ->
val entriesFormat = getString(R.string.fmt_entries)
binding.settingsData.dataEntries.text = String.format(entriesFormat, number)
}
viewModel.radiosTotal.observe(viewLifecycleOwner) { number ->
val radiosFormat = getString(R.string.fmt_radios)
binding.settingsData.dataRadios.text = String.format(radiosFormat, number)
}
getNavResult<List<String>>(R.id.nav_settings, "sources") { sources ->
viewModel.updateDataFromWeb(sources)
binding.run {
settingsData.dataBtnFile.setOnClickListener { contentRequest.launch("*/*") }
settingsData.dataBtnWeb.setOnClickListener {
val action = SettingsFragmentDirections.settingsToSources()
findNavController().navigate(action)
}
settingsData.dataBtnClear.setOnClickListener { viewModel.clearData() }
viewModel.entriesTotal.observe(viewLifecycleOwner) { number ->
val entriesFormat = getString(R.string.data_entries)
settingsData.dataEntries.text = String.format(entriesFormat, number)
}
viewModel.radiosTotal.observe(viewLifecycleOwner) { number ->
val radiosFormat = getString(R.string.data_radios)
settingsData.dataRadios.text = String.format(radiosFormat, number)
}
getNavResult<List<String>>(R.id.nav_settings, "sources") { sources ->
viewModel.updateDataFromWeb(sources)
}
}
}
private fun setupTrackingCard() {
binding.settingsTracking.remoteSwitch.apply {
isChecked = viewModel.getRotatorEnabled()
binding.settingsTracking.remoteIp.isEnabled = isChecked
binding.settingsTracking.remoteIpEdit.setText(viewModel.getRotatorServer())
binding.settingsTracking.remotePort.isEnabled = isChecked
binding.settingsTracking.remotePortEdit.setText(viewModel.getRotatorPort())
setOnCheckedChangeListener { _, isChecked ->
viewModel.setRotatorEnabled(isChecked)
binding.settingsTracking.remoteIp.isEnabled = isChecked
binding.settingsTracking.remotePort.isEnabled = isChecked
private fun setupRemoteCard() {
binding.run {
settingsRemote.remoteSwitch.apply {
isChecked = viewModel.getRotatorEnabled()
settingsRemote.remoteIp.isEnabled = isChecked
settingsRemote.remoteIpEdit.setText(viewModel.getRotatorServer())
settingsRemote.remotePort.isEnabled = isChecked
settingsRemote.remotePortEdit.setText(viewModel.getRotatorPort())
setOnCheckedChangeListener { _, isChecked ->
viewModel.setRotatorEnabled(isChecked)
settingsRemote.remoteIp.isEnabled = isChecked
settingsRemote.remotePort.isEnabled = isChecked
}
}
settingsRemote.remoteIpEdit.doOnTextChanged { text, _, _, _ ->
if (text.toString().isValidIPv4()) viewModel.setRotatorServer(text.toString())
}
settingsRemote.remotePortEdit.doOnTextChanged { text, _, _, _ ->
if (text.toString().isValidPort()) viewModel.setRotatorPort(text.toString())
}
}
binding.settingsTracking.remoteIpEdit.doOnTextChanged { text, _, _, _ ->
if (text.toString().isValidIPv4()) viewModel.setRotatorServer(text.toString())
}
binding.settingsTracking.remotePortEdit.doOnTextChanged { text, _, _, _ ->
if (text.toString().isValidPort()) viewModel.setRotatorPort(text.toString())
}
}
private fun setupOtherCard() {
binding.settingsOther.otherSwitchUtc.apply {
isChecked = viewModel.getUseUTC()
setOnCheckedChangeListener { _, isChecked -> viewModel.setUseUTC(isChecked) }
}
binding.settingsOther.otherSwitchSweep.apply {
isChecked = viewModel.getShowSweep()
setOnCheckedChangeListener { _, isChecked -> viewModel.setShowSweep(isChecked) }
}
binding.settingsOther.otherSwitchSensors.apply {
isChecked = viewModel.getUseCompass()
setOnCheckedChangeListener { _, isChecked -> viewModel.setUseCompass(isChecked) }
binding.run {
settingsOther.otherSwitchUtc.apply {
isChecked = viewModel.getUseUTC()
setOnCheckedChangeListener { _, isChecked -> viewModel.setUseUTC(isChecked) }
}
settingsOther.otherSwitchSweep.apply {
isChecked = viewModel.getShowSweep()
setOnCheckedChangeListener { _, isChecked -> viewModel.setShowSweep(isChecked) }
}
settingsOther.otherSwitchSensors.apply {
isChecked = viewModel.getUseCompass()
setOnCheckedChangeListener { _, isChecked -> viewModel.setUseCompass(isChecked) }
}
}
}
private fun setupWarrantyCard() {
binding.settingsWarranty.outroThanks.movementMethod = LinkMovementMethod.getInstance()
binding.settingsWarranty.outroLicense.movementMethod = LinkMovementMethod.getInstance()
}
private fun setPositionText(geoPos: GeoPos) {
val latFormat = getString(R.string.location_lat)
val lonFormat = getString(R.string.location_lon)
binding.settingsLocation.positionLat.text = String.format(latFormat, geoPos.latitude)
binding.settingsLocation.positionLon.text = String.format(lonFormat, geoPos.longitude)
private fun setupOutroCard() {
binding.run {
settingsOutro.outroThanks.movementMethod = LinkMovementMethod.getInstance()
settingsOutro.outroLicense.movementMethod = LinkMovementMethod.getInstance()
}
}
private fun handleStationPosition(pos: DataState<GeoPos>) {
when (pos) {
is DataState.Success -> {
setPositionText(pos.data)
binding.settingsLocation.positionProgress.isIndeterminate = false
binding.settingsLocation.locationProgress.isIndeterminate = false
viewModel.setPositionHandled()
showToast(getString(R.string.pref_pos_success))
showToast(getString(R.string.location_success))
}
is DataState.Error -> {
binding.settingsLocation.positionProgress.isIndeterminate = false
binding.settingsLocation.locationProgress.isIndeterminate = false
viewModel.setPositionHandled()
showToast(pos.message.toString())
}
DataState.Loading -> {
binding.settingsLocation.positionProgress.isIndeterminate = true
binding.settingsLocation.locationProgress.isIndeterminate = true
}
DataState.Handled -> {}
}
}
private fun setPositionText(geoPos: GeoPos) {
binding.run {
val latFormat = getString(R.string.location_lat)
val lonFormat = getString(R.string.location_lon)
settingsLocation.locationLat.text = String.format(latFormat, geoPos.latitude)
settingsLocation.locationLon.text = String.format(lonFormat, geoPos.longitude)
}
}
private fun handleSatState(state: DataState<Long>) {
when (state) {
is DataState.Success -> {
binding.settingsData.dataProgress.isIndeterminate = false
viewModel.setUpdateHandled()
showToast("Data updated successfully")
showToast(getString(R.string.data_success))
}
is DataState.Error -> {
binding.settingsData.dataProgress.isIndeterminate = false
viewModel.setUpdateHandled()
showToast(state.message.toString())
showToast(getString(R.string.data_error))
}
is DataState.Loading -> {
binding.settingsData.dataProgress.isIndeterminate = true