Replaced PreferencesAPI fragment with a regular one

This commit is contained in:
Arty Bishop committed 2022-01-09 17:59:10 +00:00
1 parent 1156824463
commit 9ca8ec65c4
25 files changed
+846 -454

No files matched your search

@@ -22,7 +22,6 @@ import android.content.Context
import android.content.SharedPreferences
import android.hardware.SensorManager
import android.location.LocationManager
import androidx.preference.PreferenceManager
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@@ -55,6 +54,6 @@ object AppModule {
@Provides
@Singleton
fun provideSharedPreferences(@ApplicationContext context: Context): SharedPreferences {
return PreferenceManager.getDefaultSharedPreferences(context)
return context.getSharedPreferences("default", Context.MODE_PRIVATE)
}
}
@@ -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.presentation.infoScreen
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.text.method.LinkMovementMethod
import android.view.View
import androidx.fragment.app.Fragment
import com.rtbishop.look4sat.BuildConfig
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.databinding.FragmentInfoBinding
class InfoFragment : Fragment(R.layout.fragment_info) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
FragmentInfoBinding.bind(view).apply {
infoVersion.text =
String.format(getString(R.string.info_version), BuildConfig.VERSION_NAME)
infoBtnGithub.setOnClickListener {
gotoUrl("https://github.com/rt-bishop/Look4Sat/")
}
infoBtnFdroid.setOnClickListener {
gotoUrl("https://f-droid.org/en/packages/com.rtbishop.look4sat/")
}
infoBtnDonate.setOnClickListener {
gotoUrl("https://www.buymeacoffee.com/rtbishop")
}
val moveMethod = LinkMovementMethod.getInstance()
infoThanks.movementMethod = moveMethod
infoWarranty.movementMethod = moveMethod
}
}
private fun gotoUrl(url: String) {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
}
}
@@ -0,0 +1,187 @@
/*
* 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.presentation.prefsScreen
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.text.method.LinkMovementMethod
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import com.google.android.material.snackbar.Snackbar
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 dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
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
private val contentContract = ActivityResultContracts.GetContent()
private val filePicker = registerForActivityResult(contentContract) { uri ->
uri?.let { viewModel.updateDataFromFile(uri) }
}
private val permReqContract = ActivityResultContracts.RequestMultiplePermissions()
private val locPermReq = registerForActivityResult(permReqContract) { permissions ->
when {
permissions[locPermFine] == true -> updatePositionFromGPS()
permissions[locPermCoarse] == true -> updatePositionFromGPS()
else -> showSnack(getString(R.string.pref_pos_gps_error))
}
}
private var _binding: FragmentPrefsBinding? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentPrefsBinding.bind(view)
setupInfoCard()
setupDataCard()
setupLocationCard()
setupWarrantyCard()
}
private fun setupInfoCard() {
_binding?.prefsInfo?.let { binding ->
binding.aboutVersion.text =
String.format(getString(R.string.about_version), BuildConfig.VERSION_NAME)
binding.aboutBtnGithub.setOnClickListener {
gotoUrl("https://github.com/rt-bishop/Look4Sat/")
}
binding.aboutBtnDonate.setOnClickListener {
gotoUrl("https://www.buymeacoffee.com/rtbishop")
}
binding.aboutBtnFdroid.setOnClickListener {
gotoUrl("https://f-droid.org/en/packages/com.rtbishop.look4sat/")
}
}
}
private fun setupDataCard() {
_binding?.prefsData?.let { binding ->
binding.updateBtnWeb.setOnClickListener {
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)
}
}
private fun setupLocationCard() {
}
private fun setupWarrantyCard() {
_binding?.prefsWarranty?.let { binding ->
val moveMethod = LinkMovementMethod.getInstance()
binding.warrantyThanks.movementMethod = moveMethod
binding.warrantyLicense.movementMethod = moveMethod
}
}
private fun updatePositionFromGPS() {
val locPermString = Manifest.permission.ACCESS_FINE_LOCATION
val locPermResult = ContextCompat.checkSelfPermission(requireContext(), locPermString)
if (locPermResult == PackageManager.PERMISSION_GRANTED) {
if (preferences.updatePositionFromGPS()) {
showSnack(getString(R.string.pref_pos_success))
} else {
showSnack(getString(R.string.pref_pos_gps_null))
}
} else locPermReq.launch(arrayOf(locPermFine, locPermCoarse))
}
private fun updatePositionFromQth(qthString: String): Boolean {
return 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()
}
private fun gotoUrl(url: String) {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
}
override fun onDestroyView() {
_binding = null
super.onDestroyView()
}
}
@@ -0,0 +1,62 @@
/*
* 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.presentation.prefsScreen
import android.content.ContentResolver
import android.net.Uri
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.rtbishop.look4sat.domain.DataRepository
import com.rtbishop.look4sat.framework.PreferencesSource
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class PrefsViewModel @Inject constructor(
private val preferences: PreferencesSource,
private val resolver: ContentResolver,
private val dataRepository: DataRepository
) : ViewModel() {
private val coroutineHandler = CoroutineExceptionHandler { _, throwable ->
// Timber.d(throwable)
// _satData.value = DataState.Error(throwable)
}
fun updateDataFromFile(uri: Uri) {
viewModelScope.launch(coroutineHandler) {
// _satData.value = DataState.Loading
runCatching {
resolver.openInputStream(uri)?.use { stream ->
dataRepository.updateDataFromFile(stream)
}
}.onFailure {
// _satData.value = DataState.Error(it)
}
}
}
fun updateDataFromWeb(sources: List<String>) {
viewModelScope.launch(coroutineHandler) {
// _satData.value = DataState.Loading
dataRepository.updateDataFromWeb(sources)
}
}
}
@@ -1,124 +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.presentation.settingsScreen
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.text.InputType
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.preference.EditTextPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.google.android.material.snackbar.Snackbar
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.framework.PreferencesSource
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class SettingsFragment : PreferenceFragmentCompat() {
@Inject
lateinit var preferences: PreferencesSource
private val permReqContract = ActivityResultContracts.RequestMultiplePermissions()
private val locPermFine = Manifest.permission.ACCESS_FINE_LOCATION
private val locPermCoarse = Manifest.permission.ACCESS_COARSE_LOCATION
private val locPermReq = registerForActivityResult(permReqContract) { permissions ->
when {
permissions[locPermFine] == true -> updatePositionFromGPS()
permissions[locPermCoarse] == true -> updatePositionFromGPS()
else -> showSnack(getString(R.string.pref_pos_gps_error))
}
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preference, rootKey)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
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_rotator_address_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_rotator_port_invalid))
return@setOnPreferenceChangeListener false
}
}
}
}
private fun updatePositionFromQth(qthString: String): Boolean {
return if (preferences.updatePositionFromQTH(qthString)) {
showSnack(getString(R.string.pref_pos_success))
true
} else {
showSnack(getString(R.string.pref_pos_qth_error))
false
}
}
private fun updatePositionFromGPS() {
val locPermString = Manifest.permission.ACCESS_FINE_LOCATION
val locPermResult = ContextCompat.checkSelfPermission(requireContext(), locPermString)
if (locPermResult == PackageManager.PERMISSION_GRANTED) {
if (preferences.updatePositionFromGPS()) {
showSnack(getString(R.string.pref_pos_success))
} else {
showSnack(getString(R.string.pref_pos_gps_null))
}
} else locPermReq.launch(arrayOf(locPermFine, locPermCoarse))
}
private fun showSnack(message: String) {
Snackbar.make(requireView(), message, Snackbar.LENGTH_SHORT).show()
}
}