Restored Preferences fragment functionality

This commit is contained in:
Arty Bishop committed 2022-01-09 17:59:24 +00:00
1 parent 9ca8ec65c4
commit be26b3e1dc
7 files changed
+154 -70

No files matched your search

@@ -22,8 +22,8 @@ import android.hardware.GeomagneticField
import android.location.LocationManager
import androidx.core.content.edit
import com.rtbishop.look4sat.BuildConfig
import com.rtbishop.look4sat.domain.predict.GeoPos
import com.rtbishop.look4sat.domain.QthConverter
import com.rtbishop.look4sat.domain.predict.GeoPos
import com.rtbishop.look4sat.presentation.round
import javax.inject.Inject
import javax.inject.Singleton
@@ -109,19 +109,31 @@ class PreferencesSource @Inject constructor(
return preferences.getBoolean(keyTextLabels, false)
}
fun shouldUseUTC(): Boolean {
fun getUseUTC(): Boolean {
return preferences.getBoolean(keyTimeUTC, false)
}
fun shouldUseCompass(): Boolean {
fun setUseUTC(value: Boolean) {
preferences.edit { putBoolean(keyTimeUTC, value) }
}
fun getUseCompass(): Boolean {
return preferences.getBoolean(keyCompass, true)
}
fun shouldShowSweep(): Boolean {
fun setUseCompass(value: Boolean) {
preferences.edit { putBoolean(keyCompass, value) }
}
fun getShowSweep(): Boolean {
return preferences.getBoolean(keyRadarSweep, true)
}
fun isSetupDone(): Boolean {
fun setShowSweep(value: Boolean) {
preferences.edit { putBoolean(keyRadarSweep, value) }
}
fun getSetupDone(): Boolean {
return preferences.getBoolean(keyInitialSetup, false)
}
@@ -143,13 +155,33 @@ class PreferencesSource @Inject constructor(
return emptyList()
}
fun isRotatorEnabled(): Boolean {
fun getRotatorEnabled(): Boolean {
return preferences.getBoolean(keyRotator, false)
}
fun setRotatorEnabled(value: Boolean) {
preferences.edit { putBoolean(keyRotator, value) }
}
fun getRotatorServer(): Pair<String, Int> {
val address = preferences.getString(keyRotatorAddress, null) ?: "127.0.0.1"
val port = preferences.getString(keyRotatorPort, null) ?: "4533"
return Pair(address, port.toInt())
}
fun getRotatorIp(): String {
return preferences.getString(keyRotatorAddress, null) ?: "127.0.0.1"
}
fun setRotatorIp(value: String) {
preferences.edit { putString(keyRotatorAddress, value) }
}
fun getRotatorPort(): String {
return preferences.getString(keyRotatorPort, null) ?: "4533"
}
fun setRotatorPort(value: String) {
preferences.edit { putString(keyRotatorPort, value) }
}
}
@@ -19,9 +19,13 @@ package com.rtbishop.look4sat.presentation
import android.content.Context
import android.content.SharedPreferences
import android.content.res.Resources
import android.os.Bundle
import android.widget.EditText
import android.widget.FrameLayout
import android.widget.Toast
import androidx.annotation.IdRes
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
@@ -101,8 +105,38 @@ fun String.getHash(type: String = "SHA-256"): String {
return result.toString()
}
fun String.isEmailValid(): Boolean {
fun String.isValidEmail(): Boolean {
val expression = "^[\\w.-]+@([\\w\\-]+\\.)+[A-Z]{2,8}$"
val pattern = Pattern.compile(expression, Pattern.CASE_INSENSITIVE)
return pattern.matcher(this).matches()
}
fun String.isValidIPv4(): Boolean {
val ip4 = "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\\.(?!\$)|\$)){4}\$"
return this.matches(ip4.toRegex())
}
fun String.isValidPort(): Boolean {
return this.isNotEmpty() && this.toInt() in 1024..65535
}
fun Float.toPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()
fun AlertDialog.Builder.setEditText(editText: EditText): AlertDialog.Builder {
val container = FrameLayout(context)
container.addView(editText)
val containerParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT
)
val marginHorizontal = 32F
val marginTop = 24F
containerParams.topMargin = (marginTop / 2).toPx()
containerParams.leftMargin = marginHorizontal.toInt()
containerParams.rightMargin = marginHorizontal.toInt()
container.layoutParams = containerParams
val superContainer = FrameLayout(context)
superContainer.addView(container)
setView(superContainer)
return this
}
@@ -28,7 +28,6 @@ import com.rtbishop.look4sat.domain.DataRepository
import com.rtbishop.look4sat.framework.PreferencesSource
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collect
import java.util.*
import javax.inject.Inject
@@ -46,7 +45,7 @@ class PassesViewModel @Inject constructor(
val isFirstLaunchDone: LiveData<Boolean> = _isFirstLaunchDone
init {
if (preferences.isSetupDone()) {
if (preferences.getSetupDone()) {
viewModelScope.launch {
_passes.postValue(DataState.Loading)
val timeNow = System.currentTimeMillis()
@@ -97,7 +96,7 @@ class PassesViewModel @Inject constructor(
}
fun shouldUseUTC(): Boolean {
return preferences.shouldUseUTC()
return preferences.getUseUTC()
}
private suspend fun tickPasses(passes: List<SatPass>) = withContext(Dispatchers.Default) {
@@ -24,8 +24,11 @@ import android.net.Uri
import android.os.Bundle
import android.text.method.LinkMovementMethod
import android.view.View
import android.widget.EditText
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
@@ -34,8 +37,7 @@ import com.rtbishop.look4sat.BuildConfig
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.databinding.FragmentPrefsBinding
import com.rtbishop.look4sat.framework.PreferencesSource
import com.rtbishop.look4sat.presentation.getNavResult
import com.rtbishop.look4sat.presentation.navigateSafe
import com.rtbishop.look4sat.presentation.*
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@@ -44,6 +46,7 @@ class PrefsFragment : Fragment(R.layout.fragment_prefs) {
@Inject
lateinit var preferences: PreferencesSource
private val viewModel: PrefsViewModel by viewModels()
private val locPermFine = Manifest.permission.ACCESS_FINE_LOCATION
private val locPermCoarse = Manifest.permission.ACCESS_COARSE_LOCATION
@@ -64,13 +67,15 @@ class PrefsFragment : Fragment(R.layout.fragment_prefs) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentPrefsBinding.bind(view)
setupInfoCard()
setupAboutCard()
setupDataCard()
setupLocationCard()
setupWarrantyCard()
setupOtherCard()
setupTrackingCard()
}
private fun setupInfoCard() {
private fun setupAboutCard() {
_binding?.prefsInfo?.let { binding ->
binding.aboutVersion.text =
String.format(getString(R.string.about_version), BuildConfig.VERSION_NAME)
@@ -92,21 +97,77 @@ class PrefsFragment : Fragment(R.layout.fragment_prefs) {
findNavController().navigateSafe(R.id.action_prefs_to_sources)
}
binding.updateBtnFile.setOnClickListener { filePicker.launch("*/*") }
}
getNavResult<List<String>>(R.id.nav_passes, "sources") { sources ->
viewModel.updateDataFromWeb(sources)
getNavResult<List<String>>(R.id.nav_prefs, "sources") { sources ->
viewModel.updateDataFromWeb(sources)
}
}
}
private fun setupLocationCard() {
_binding?.prefsLocation?.let { binding ->
binding.locationBtnGps.setOnClickListener {
updatePositionFromGPS()
}
binding.locationBtnQth.setOnClickListener {
val editText = EditText(requireActivity())
AlertDialog.Builder(requireContext())
.setTitle("Title")
.setEditText(editText)
.setPositiveButton("OK") { _, _ ->
val editTextInput = editText.text.toString()
updatePositionFromQth(editTextInput)
}
.setNeutralButton("Cancel", null)
.create()
.show()
}
}
}
private fun setupTrackingCard() {
_binding?.prefsTracking?.let { binding ->
binding.trackingSwitch.apply {
isChecked = preferences.getRotatorEnabled()
binding.trackingIp.isEnabled = isChecked
binding.trackingIpEdit.setText(preferences.getRotatorIp())
binding.trackingPort.isEnabled = isChecked
binding.trackingPortEdit.setText(preferences.getRotatorPort())
setOnCheckedChangeListener { _, isChecked ->
preferences.setRotatorEnabled(isChecked)
binding.trackingIp.isEnabled = isChecked
binding.trackingPort.isEnabled = isChecked
}
}
binding.trackingIpEdit.doOnTextChanged { text, _, _, _ ->
if (text.toString().isValidIPv4()) preferences.setRotatorIp(text.toString())
}
binding.trackingPortEdit.doOnTextChanged { text, _, _, _ ->
if (text.toString().isValidPort()) preferences.setRotatorPort(text.toString())
}
}
}
private fun setupOtherCard() {
_binding?.prefsOther?.let { binding ->
binding.otherSwitchUtc.apply {
isChecked = preferences.getUseUTC()
setOnCheckedChangeListener { _, isChecked -> preferences.setUseUTC(isChecked) }
}
binding.otherSwitchSweep.apply {
isChecked = preferences.getShowSweep()
setOnCheckedChangeListener { _, isChecked -> preferences.setShowSweep(isChecked) }
}
binding.otherSwitchSensors.apply {
isChecked = preferences.getUseCompass()
setOnCheckedChangeListener { _, isChecked -> preferences.setUseCompass(isChecked) }
}
}
}
private fun setupWarrantyCard() {
_binding?.prefsWarranty?.let { binding ->
val moveMethod = LinkMovementMethod.getInstance()
binding.warrantyThanks.movementMethod = moveMethod
binding.warrantyLicense.movementMethod = moveMethod
binding.warrantyThanks.movementMethod = LinkMovementMethod.getInstance()
binding.warrantyLicense.movementMethod = LinkMovementMethod.getInstance()
}
}
@@ -122,56 +183,14 @@ class PrefsFragment : Fragment(R.layout.fragment_prefs) {
} else locPermReq.launch(arrayOf(locPermFine, locPermCoarse))
}
private fun updatePositionFromQth(qthString: String): Boolean {
return if (preferences.updatePositionFromQTH(qthString)) {
private fun updatePositionFromQth(qthString: String) {
if (preferences.updatePositionFromQTH(qthString)) {
showSnack(getString(R.string.pref_pos_success))
true
} else {
showSnack(getString(R.string.pref_pos_qth_error))
false
}
}
private fun setupLater() {
// findPreference<Preference>(PreferencesSource.keyPositionGPS)?.apply {
// setOnPreferenceClickListener {
// updatePositionFromGPS()
// return@setOnPreferenceClickListener true
// }
// }
//
// findPreference<Preference>(PreferencesSource.keyPositionQTH)?.apply {
// setOnPreferenceChangeListener { _, newValue ->
// updatePositionFromQth(newValue.toString())
// }
// }
//
// findPreference<EditTextPreference>(PreferencesSource.keyRotatorAddress)?.apply {
// setOnPreferenceChangeListener { _, newValue ->
// val ip4 = "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\\.(?!\$)|\$)){4}\$"
// if (newValue.toString().matches(ip4.toRegex())) {
// return@setOnPreferenceChangeListener true
// } else {
// showSnack(getString(R.string.tracking_ip_invalid))
// return@setOnPreferenceChangeListener false
// }
// }
// }
//
// findPreference<EditTextPreference>(PreferencesSource.keyRotatorPort)?.apply {
// setOnBindEditTextListener { it.inputType = InputType.TYPE_CLASS_NUMBER }
// setOnPreferenceChangeListener { _, newValue ->
// val portValue = newValue.toString()
// if (portValue.isNotEmpty() && portValue.toInt() in 1024..65535) {
// return@setOnPreferenceChangeListener true
// } else {
// showSnack(getString(R.string.tracking_port_invalid))
// return@setOnPreferenceChangeListener false
// }
// }
// }
}
private fun showSnack(message: String) {
Snackbar.make(requireView(), message, Snackbar.LENGTH_SHORT).show()
}
@@ -78,8 +78,8 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
val aosTime = requireArguments().getLong("aosTime")
viewModel.getPass(catNum, aosTime).observe(viewLifecycleOwner) { pass ->
radarView = RadarView(requireContext()).apply {
setShowAim(preferences.shouldUseCompass())
setScanning(preferences.shouldShowSweep())
setShowAim(preferences.getUseCompass())
setScanning(preferences.getShowSweep())
}
binding.radarFrame.addView(radarView)
viewModel.radarData.observe(viewLifecycleOwner, { passData ->
@@ -29,7 +29,6 @@ import com.rtbishop.look4sat.framework.PreferencesSource
import com.rtbishop.look4sat.presentation.round
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.util.*
@@ -64,11 +63,11 @@ class RadarViewModel @Inject constructor(
}
fun enableSensor() {
if (preferences.shouldUseCompass()) orientationSource.startListening(this)
if (preferences.getUseCompass()) orientationSource.startListening(this)
}
fun disableSensor() {
if (preferences.shouldUseCompass()) orientationSource.stopListening()
if (preferences.getUseCompass()) orientationSource.stopListening()
}
override fun onOrientationChanged(azimuth: Float, pitch: Float, roll: Float) {
@@ -85,7 +84,7 @@ class RadarViewModel @Inject constructor(
}
while (isActive) {
val satPos = predictor.getSatPos(satPass.satellite, stationPos, Date().time)
if (preferences.isRotatorEnabled()) {
if (preferences.getRotatorEnabled()) {
val server = preferences.getRotatorServer().first
val port = preferences.getRotatorServer().second
val azimuth = Math.toDegrees(satPos.azimuth).round(1)
+1
View File
@@ -11,4 +11,5 @@
<color name="greySurface">#1e1e1e</color>
<color name="mapInfoLayout">#99000000</color>
<color name="mtrl_textinput_default_box_stroke_color">@color/greyLight</color>
<color name="mtrl_textinput_disabled_color">@color/bgDark</color>
</resources>