diff --git a/app/build.gradle b/app/build.gradle index 207ea30d..3129ee7c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "com.rtbishop.look4sat" minSdkVersion 21 targetSdkVersion 30 - versionCode 240 - versionName "2.4.0" + versionCode 250 + versionName "2.5.0" } buildTypes { diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/satItemScreen/SatItemFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/satItemScreen/SatItemFragment.kt index 615385a0..44435893 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/satItemScreen/SatItemFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/satItemScreen/SatItemFragment.kt @@ -26,6 +26,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.SimpleItemAnimator +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.rtbishop.look4sat.R import com.rtbishop.look4sat.databinding.DialogSourceBinding import com.rtbishop.look4sat.databinding.FragmentEntriesBinding @@ -64,7 +65,7 @@ class SatItemFragment : Fragment(R.layout.fragment_entries) { importWeb.setOnClickListener { viewModel.updateEntriesFromWeb(null) } importSource.setOnClickListener { showSourceDialog() } importFile.setOnClickListener { filePicker.launch("*/*") } - selectMode.setOnClickListener { viewModel.createModesDialog(requireContext()).show() } + selectMode.setOnClickListener { showModesDialog() } selectAll.setOnClickListener { viewModel.selectCurrentItems() } searchBar.setOnQueryTextListener(viewModel) } @@ -114,4 +115,33 @@ class SatItemFragment : Fragment(R.layout.fragment_entries) { } dialogBuilder.create().show() } + + private fun showModesDialog() { + val modes = arrayOf( + "AFSK", "AFSK S-Net", "AFSK SALSAT", "AHRPT", "AM", "APT", "BPSK", "BPSK PMT-A3", + "CERTO", "CW", "DQPSK", "DSTAR", "DUV", "FFSK", "FM", "FMN", "FSK", "FSK AX.100 Mode 5", + "FSK AX.100 Mode 6", "FSK AX.25 G3RUH", "GFSK", "GFSK Rktr", "GMSK", "HRPT", "LoRa", + "LRPT", "LSB", "MFSK", "MSK", "MSK AX.100 Mode 5", "MSK AX.100 Mode 6", "OFDM", "OQPSK", + "PSK", "PSK31", "PSK63", "QPSK", "QPSK31", "QPSK63", "SSTV", "USB", "WSJT" + ) + val savedModes = BooleanArray(modes.size) + val selectedModes = viewModel.loadSelectedModes().toMutableList() + selectedModes.forEach { savedModes[modes.indexOf(it)] = true } + val dialogBuilder = MaterialAlertDialogBuilder(requireContext()).apply { + setTitle(context.getString(R.string.modes_title)) + setMultiChoiceItems(modes, savedModes) { _, which, isChecked -> + when { + isChecked -> selectedModes.add(modes[which]) + selectedModes.contains(modes[which]) -> selectedModes.remove(modes[which]) + } + } + setPositiveButton(context.getString(android.R.string.ok)) { _, _ -> + viewModel.saveSelectedModes(selectedModes) + } + setNeutralButton(context.getString(android.R.string.cancel)) { dialog, _ -> + dialog.dismiss() + } + } + dialogBuilder.create().show() + } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/satItemScreen/SatItemViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/satItemScreen/SatItemViewModel.kt index 6f6e696d..85744139 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/satItemScreen/SatItemViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/satItemScreen/SatItemViewModel.kt @@ -18,13 +18,9 @@ package com.rtbishop.look4sat.presentation.satItemScreen import android.content.ContentResolver -import android.content.Context import android.net.Uri import android.widget.SearchView -import androidx.appcompat.app.AlertDialog import androidx.lifecycle.* -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.rtbishop.look4sat.R import com.rtbishop.look4sat.data.SatDataRepository import com.rtbishop.look4sat.domain.model.SatItem import com.rtbishop.look4sat.framework.model.Result @@ -40,7 +36,7 @@ class SatItemViewModel @Inject constructor( private val satDataRepository: SatDataRepository, ) : ViewModel(), SatItemAdapter.EntriesClickListener, SearchView.OnQueryTextListener { - private val transModes = MutableLiveData(satDataRepository.loadModesSelection()) + private val transModes = MutableLiveData(satDataRepository.loadSelectedModes()) private val currentQuery = MutableLiveData(String()) private val itemsWithModes = transModes.switchMap { modes -> liveData { satDataRepository.getSatItems().collect { emit(filterByModes(it, modes)) } } @@ -83,28 +79,13 @@ class SatItemViewModel @Inject constructor( } } - fun createModesDialog(context: Context): AlertDialog { - val modes = satDataRepository.getAllModes() - val savedModes = BooleanArray(modes.size) - val selectedModes = satDataRepository.loadModesSelection().toMutableList() - selectedModes.forEach { savedModes[modes.indexOf(it)] = true } - val dialogBuilder = MaterialAlertDialogBuilder(context).apply { - setTitle(context.getString(R.string.modes_title)) - setMultiChoiceItems(modes, savedModes) { _, which, isChecked -> - when { - isChecked -> selectedModes.add(modes[which]) - selectedModes.contains(modes[which]) -> selectedModes.remove(modes[which]) - } - } - setPositiveButton(context.getString(android.R.string.ok)) { _, _ -> - transModes.value = selectedModes - satDataRepository.saveModesSelection(selectedModes) - } - setNeutralButton(context.getString(android.R.string.cancel)) { dialog, _ -> - dialog.dismiss() - } - } - return dialogBuilder.create() + fun loadSelectedModes(): List { + return satDataRepository.loadSelectedModes() + } + + fun saveSelectedModes(modes: List) { + transModes.value = modes + satDataRepository.saveSelectedModes(modes) } override fun onQueryTextSubmit(query: String): Boolean { diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/satMapScreen/SatMapFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/satMapScreen/SatMapFragment.kt index d23e61fb..40fd60a9 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/satMapScreen/SatMapFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/satMapScreen/SatMapFragment.kt @@ -49,21 +49,19 @@ class SatMapFragment : Fragment(R.layout.fragment_map) { @Inject lateinit var sharedPreferences: SharedPreferences - private val viewModelSat: SatMapViewModel by viewModels() + private val viewModel: SatMapViewModel by viewModels() private val minLat = MapView.getTileSystem().minLatitude private val maxLat = MapView.getTileSystem().maxLatitude - private val trackPaint = Paint().apply { + private val trackPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { strokeWidth = 2f style = Paint.Style.STROKE color = Color.RED strokeCap = Paint.Cap.ROUND strokeJoin = Paint.Join.ROUND - isAntiAlias = true } - private val footprintPaint = Paint().apply { + private val footprintPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { style = Paint.Style.FILL_AND_STROKE color = Color.parseColor("#26FFE082") - isAntiAlias = true } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -73,10 +71,9 @@ class SatMapFragment : Fragment(R.layout.fragment_map) { mapView.apply { setMultiTouchControls(true) setTileSource(TileSourceFactory.WIKIMEDIA) - val minZoom = getMinZoom(resources.displayMetrics.heightPixels) - minZoomLevel = minZoom + minZoomLevel = getMinZoom(resources.displayMetrics.heightPixels) maxZoomLevel = 6.0 - controller.setZoom(minZoom + 0.5) + controller.setZoom(minZoomLevel + 0.5) zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER) overlayManager.tilesOverlay.loadingBackgroundColor = Color.TRANSPARENT overlayManager.tilesOverlay.loadingLineColor = Color.TRANSPARENT @@ -86,17 +83,17 @@ class SatMapFragment : Fragment(R.layout.fragment_map) { overlays.addAll(Array(4) { FolderOverlay() }) } } - binding.fabPrev.setOnClickListener { viewModelSat.scrollSelection(true) } - binding.fabNext.setOnClickListener { viewModelSat.scrollSelection(false) } + binding.fabPrev.setOnClickListener { viewModel.scrollSelection(true) } + binding.fabNext.setOnClickListener { viewModel.scrollSelection(false) } setupObservers(binding) } private fun setupObservers(binding: FragmentMapBinding) { - viewModelSat.stationPos.observe(viewLifecycleOwner, { renderStationPos(it, binding) }) - viewModelSat.allSatPositions.observe(viewLifecycleOwner, { renderSatPositions(it, binding) }) - viewModelSat.satTrack.observe(viewLifecycleOwner, { renderSatTrack(it, binding) }) - viewModelSat.satFootprint.observe(viewLifecycleOwner, { renderSatFootprint(it, binding) }) - viewModelSat.satData.observe(viewLifecycleOwner, { renderSatData(it, binding) }) + viewModel.stationPos.observe(viewLifecycleOwner, { renderStationPos(it, binding) }) + viewModel.satPositions.observe(viewLifecycleOwner, { renderSatPositions(it, binding) }) + viewModel.satTrack.observe(viewLifecycleOwner, { renderSatTrack(it, binding) }) + viewModel.satFootprint.observe(viewLifecycleOwner, { renderSatFootprint(it, binding) }) + viewModel.satData.observe(viewLifecycleOwner, { renderSatData(it, binding) }) } private fun renderStationPos(stationPos: Position, binding: FragmentMapBinding) { @@ -116,7 +113,7 @@ class SatMapFragment : Fragment(R.layout.fragment_map) { binding.apply { val markers = FolderOverlay() posMap.entries.forEach { - if (viewModelSat.shouldUseTextLabels()) { + if (viewModel.shouldUseTextLabels()) { Marker(mapView).apply { setInfoWindow(null) textLabelFontSize = 24 @@ -131,7 +128,7 @@ class SatMapFragment : Fragment(R.layout.fragment_map) { Timber.d(exception) } setOnMarkerClickListener { _, _ -> - viewModelSat.selectSatellite(it.key) + viewModel.selectSatellite(it.key) return@setOnMarkerClickListener true } markers.add(this) @@ -147,7 +144,7 @@ class SatMapFragment : Fragment(R.layout.fragment_map) { Timber.d(exception) } setOnMarkerClickListener { _, _ -> - viewModelSat.selectSatellite(it.key) + viewModel.selectSatellite(it.key) return@setOnMarkerClickListener true } markers.add(this) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/satMapScreen/SatMapViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/satMapScreen/SatMapViewModel.kt index 4ab877ad..1ae4d04e 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/satMapScreen/SatMapViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/satMapScreen/SatMapViewModel.kt @@ -60,8 +60,8 @@ class SatMapViewModel @Inject constructor( private val _satData = MutableLiveData() val satData: LiveData = this._satData - private val _allSatPositions = MutableLiveData>() - val allSatPositions: LiveData> = _allSatPositions + private val _satPositions = MutableLiveData>() + val satPositions: LiveData> = _satPositions init { viewModelScope.launch { @@ -118,7 +118,7 @@ class SatMapViewModel @Inject constructor( val osmLon = clipLon(Math.toDegrees(satPos.longitude)) satPositions[satellite] = Position(osmLat, osmLon) } - _allSatPositions.postValue(satPositions) + _satPositions.postValue(satPositions) } } diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ea8b3061..05ec7edd 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -44,7 +44,7 @@ Местоположение наземной станции Установить позицию по данным GPS - Местоположение отключено + Нет данных геолокации Нет разрешения использовать геоданные Установить позицию по локатору QTH Неправильный локатор QTH @@ -72,11 +72,11 @@ \n— Вам за использование этого приложения! \nЖелаю всегда чистого неба над головой! \n— David A. B. Johnson и Dave Moten за работу над библиотекой predict4java и - открытие доступа к ней по лицензии GNU GPLv2 + за доступ к ней по лицензии GNU GPLv2 \n— Alexandru Csete за его замечательную программу Gpredict, которая вдохновила меня на создание Look4Sat. \n— Доктору T.S. Kelso за его сайт - Celestrak, который предоставляет доступ к файлам орбит Two-Line Element. + Celestrak и доступ к файлам орбит Two-Line Element. \n— Libre Space Foundation за проект SatNOGS, API и базу данных с огромным количеством информации о спутниках. \n— Square за библиотеки OkHttp, Retrofit, Moshi и доступ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 11bb37fd..3ffe0d5e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,7 +1,7 @@ Look4Sat - Placeholder + dummy No Yes @@ -60,7 +60,7 @@ Ground station position Set position from GPS data - Location is switched off + No geolocation data Check your location permissions Set position from QTH locator Invalid QTH locator diff --git a/app/src/main/res/xml/preference.xml b/app/src/main/res/xml/preference.xml index bb1a7919..c249a72d 100644 --- a/app/src/main/res/xml/preference.xml +++ b/app/src/main/res/xml/preference.xml @@ -61,7 +61,7 @@ android:title="@string/pref_map_labels_title" app:iconSpaceReserved="false"> diff --git a/core/src/main/java/com/rtbishop/look4sat/data/SatDataRepository.kt b/core/src/main/java/com/rtbishop/look4sat/data/SatDataRepository.kt index 57fd50f9..cf33d179 100644 --- a/core/src/main/java/com/rtbishop/look4sat/data/SatDataRepository.kt +++ b/core/src/main/java/com/rtbishop/look4sat/data/SatDataRepository.kt @@ -42,23 +42,11 @@ class SatDataRepository( "https://www.prismnet.com/~mmccants/tles/inttles.zip" ) - private val transmittersModes = arrayOf( - "AFSK", "AFSK S-Net", "AFSK SALSAT", "AHRPT", "AM", "APT", "BPSK", "BPSK PMT-A3", - "CERTO", "CW", "DQPSK", "DSTAR", "DUV", "FFSK", "FM", "FMN", "FSK", "FSK AX.100 Mode 5", - "FSK AX.100 Mode 6", "FSK AX.25 G3RUH", "GFSK", "GFSK Rktr", "GMSK", "HRPT", "LoRa", - "LRPT", "LSB", "MFSK", "MSK", "MSK AX.100 Mode 5", "MSK AX.100 Mode 6", "OFDM", "OQPSK", - "PSK", "PSK31", "PSK63", "QPSK", "QPSK31", "QPSK63", "SSTV", "USB", "WSJT" - ) - - fun getAllModes(): Array { - return transmittersModes - } - - fun saveModesSelection(modes: List) { + fun saveSelectedModes(modes: List) { preferencesSource.saveModesSelection(modes) } - fun loadModesSelection(): List { + fun loadSelectedModes(): List { return preferencesSource.loadModesSelection() } diff --git a/fastlane/metadata/android/en-US/changelogs/250.txt b/fastlane/metadata/android/en-US/changelogs/250.txt new file mode 100644 index 00000000..e95c9fbe --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/250.txt @@ -0,0 +1,6 @@ +Added simple custom source TLE update dialog +Added immediate initial setup +Added pass direction arrow to radar view #52 +Added orientation pointer to radar view +Fixed radar view update bug #51 +Switched to modular architecture \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png index ce6b6327..445629a6 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png index 1f17380a..aab711a9 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png index 178961fa..5b2612d0 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png index 5cdec6c3..2b266557 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/en-US/whatsnew/whatsnew-en-US b/fastlane/metadata/android/en-US/whatsnew/whatsnew-en-US index a3f94317..e95c9fbe 100644 --- a/fastlane/metadata/android/en-US/whatsnew/whatsnew-en-US +++ b/fastlane/metadata/android/en-US/whatsnew/whatsnew-en-US @@ -1,5 +1,6 @@ -Removed hardcoded screen orientation -Removed redundant permission from manifest -Added antenna rotator control via socket -Showing azimuth for respective maxElevation -Showing satellite name on the polar screen +Added simple custom source TLE update dialog +Added immediate initial setup +Added pass direction arrow to radar view #52 +Added orientation pointer to radar view +Fixed radar view update bug #51 +Switched to modular architecture \ No newline at end of file