Restored satellite selection functionality

pull/87/head
Arty Bishop 2022-02-14 19:16:55 +00:00
rodzic 80ba3644f7
commit a7c840d532
11 zmienionych plików z 118 dodań i 87 usunięć

Wyświetl plik

@ -39,26 +39,29 @@ interface EntriesDao {
suspend fun insertEntries(entries: List<SatEntry>)
@Transaction
suspend fun updateEntries(entries: List<SatEntry>, cleanup: Boolean = false) {
suspend fun updateEntries(entries: List<SatEntry>) {
val entriesSelection = getEntriesSelection()
if (cleanup) deleteEntries()
insertEntries(entries)
restoreSelection(entriesSelection, true)
}
@Query("UPDATE entries SET isSelected = :isSelected WHERE catnum = :catnum")
suspend fun updateEntrySelection(catnum: Int, isSelected: Boolean)
@Transaction
suspend fun updateEntriesSelection(catnums: List<Int>, isSelected: Boolean) {
catnums.forEach { catnum -> updateEntrySelection(catnum, isSelected) }
restoreEntriesSelection(entriesSelection)
}
@Transaction
suspend fun restoreSelection(catnums: List<Int>, isSelected: Boolean) {
updateEntriesSelection(catnums, isSelected)
suspend fun restoreEntriesSelection(catnums: List<Int>) {
updateEntriesSelection(catnums)
}
@Transaction
suspend fun updateEntriesSelection(catnums: List<Int>) {
clearEntriesSelection()
catnums.forEach { catnum -> updateEntrySelection(catnum) }
}
@Query("UPDATE entries SET isSelected = 1 WHERE catnum = :catnum")
suspend fun updateEntrySelection(catnum: Int)
@Query("UPDATE entries SET isSelected = 0")
suspend fun clearEntriesSelection()
@Query("DELETE FROM entries")
suspend fun deleteEntries()
}

Wyświetl plik

@ -62,8 +62,8 @@ class LocalSource(
entriesDao.updateEntries(entries.toFrameworkEntries())
}
override suspend fun updateEntriesSelection(catnums: List<Int>, isSelected: Boolean) {
entriesDao.updateEntriesSelection(catnums, isSelected)
override suspend fun updateEntriesSelection(catnums: List<Int>) {
entriesDao.updateEntriesSelection(catnums)
}
override suspend fun updateTransmitters(transmitters: List<Transmitter>) {

Wyświetl plik

@ -37,19 +37,21 @@ import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class EntriesFragment : Fragment(R.layout.fragment_entries) {
private lateinit var binding: FragmentEntriesBinding
private val viewModel: EntriesViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupComponents(view)
binding = FragmentEntriesBinding.bind(view)
setupComponents()
}
private fun setupComponents(view: View) {
private fun setupComponents() {
val context = requireContext()
val adapter = EntriesAdapter(viewModel)
val layoutManager = GridLayoutManager(context, 2)
val itemDecoration = DividerItemDecoration(context, layoutManager.orientation)
val binding = FragmentEntriesBinding.bind(view).apply {
binding.run {
entriesRecycler.apply {
setHasFixedSize(true)
this.adapter = adapter
@ -61,6 +63,7 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) {
entriesSearch.doOnTextChanged { text, _, _, _ -> viewModel.setQuery(text.toString()) }
entriesMode.setOnClickListener { showModesDialog() }
entriesSelectAll.setOnClickListener { viewModel.selectCurrentItems() }
entriesAccept.setOnClickListener { viewModel.saveSelection() }
}
viewModel.satData.observe(viewLifecycleOwner) { satData ->
handleSatData(satData, binding, adapter)

Wyświetl plik

@ -67,6 +67,13 @@ class EntriesViewModel @Inject constructor(
currentQuery.value = query
}
fun saveSelection() {
itemsFromRepo.value?.let { itemsAll ->
val selectedIds = itemsAll.filter { it.isSelected }.map { it.catnum }
repository.updateSelection(selectedIds)
}
}
override fun updateSelection(catNums: List<Int>, isSelected: Boolean) {
itemsFromRepo.value?.let { itemsAll ->
val copiedList = itemsAll.map { item -> item.copy() }

Wyświetl plik

@ -50,6 +50,7 @@ class MapFragment : Fragment(R.layout.fragment_map) {
@Inject
lateinit var sharedPreferences: SharedPreferences
private lateinit var binding: FragmentMapBinding
private val args: MapFragmentArgs by navArgs()
private val viewModel: MapViewModel by viewModels()
@ -69,8 +70,14 @@ class MapFragment : Fragment(R.layout.fragment_map) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentMapBinding.bind(view)
setupComponents()
setupObservers()
}
private fun setupComponents() {
Configuration.getInstance().load(requireContext(), sharedPreferences)
val binding = FragmentMapBinding.bind(view).apply {
binding.run {
mapView.apply {
setMultiTouchControls(true)
setTileSource(TileSourceFactory.WIKIMEDIA)
@ -85,23 +92,22 @@ class MapFragment : Fragment(R.layout.fragment_map) {
// add overlays: 0 - GSP, 1 - SatTrack, 2 - SatFootprint, 3 - SatIcons
overlays.addAll(Array(4) { FolderOverlay() })
}
mapBack.setOnClickListener { findNavController().navigateUp() }
mapBtnPrev.setOnClickListener { viewModel.scrollSelection(true) }
mapBtnNext.setOnClickListener { viewModel.scrollSelection(false) }
}
binding.mapBack.setOnClickListener { findNavController().navigateUp() }
binding.mapBtnPrev.setOnClickListener { viewModel.scrollSelection(true) }
binding.mapBtnNext.setOnClickListener { viewModel.scrollSelection(false) }
setupObservers(binding)
}
private fun setupObservers(binding: FragmentMapBinding) {
private fun setupObservers() {
viewModel.selectDefaultSatellite(args.catNum)
viewModel.stationPosLiveData.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.mapData.observe(viewLifecycleOwner) { renderSatData(it, binding) }
viewModel.stationPosLiveData.observe(viewLifecycleOwner) { renderStationPos(it) }
viewModel.satPositions.observe(viewLifecycleOwner) { renderSatPositions(it) }
viewModel.satTrack.observe(viewLifecycleOwner) { renderSatTrack(it) }
viewModel.satFootprint.observe(viewLifecycleOwner) { renderSatFootprint(it) }
viewModel.mapData.observe(viewLifecycleOwner) { renderSatData(it) }
}
private fun renderStationPos(stationPos: GeoPos, binding: FragmentMapBinding) {
private fun renderStationPos(stationPos: GeoPos) {
binding.apply {
Marker(mapView).apply {
setInfoWindow(null)
@ -114,7 +120,7 @@ class MapFragment : Fragment(R.layout.fragment_map) {
}
}
private fun renderSatPositions(posMap: Map<Satellite, GeoPos>, binding: FragmentMapBinding) {
private fun renderSatPositions(posMap: Map<Satellite, GeoPos>) {
binding.apply {
val markers = FolderOverlay()
posMap.entries.forEach {
@ -143,7 +149,7 @@ class MapFragment : Fragment(R.layout.fragment_map) {
}
}
private fun renderSatTrack(satTrack: List<List<GeoPos>>, binding: FragmentMapBinding) {
private fun renderSatTrack(satTrack: List<List<GeoPos>>) {
val trackOverlay = FolderOverlay()
satTrack.forEach { track ->
val trackPoints = track.map { GeoPoint(it.latitude, it.longitude) }
@ -160,7 +166,7 @@ class MapFragment : Fragment(R.layout.fragment_map) {
binding.mapView.overlays[1] = trackOverlay
}
private fun renderSatFootprint(satFootprint: List<GeoPos>, binding: FragmentMapBinding) {
private fun renderSatFootprint(satFootprint: List<GeoPos>) {
val footprintPoints = satFootprint.map { GeoPoint(it.latitude, it.longitude) }
val footprintOverlay = Polygon().apply {
fillPaint.set(footprintPaint)
@ -174,7 +180,7 @@ class MapFragment : Fragment(R.layout.fragment_map) {
binding.mapView.overlays[2] = footprintOverlay
}
private fun renderSatData(mapData: MapData, binding: FragmentMapBinding) {
private fun renderSatData(mapData: MapData) {
binding.apply {
mapDataName.text =
String.format(getString(R.string.pat_osm_idName), mapData.catNum, mapData.name)

Wyświetl plik

@ -36,19 +36,21 @@ import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesClickListener {
private lateinit var binding: FragmentPassesBinding
private val passesViewModel: PassesViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupComponents(view)
binding = FragmentPassesBinding.bind(view)
setupComponents()
}
private fun setupComponents(view: View) {
private fun setupComponents() {
val context = requireContext()
val adapter = PassesAdapter(passesViewModel.shouldUseUTC(), this)
val layoutManager = LinearLayoutManager(context)
val itemDecoration = DividerItemDecoration(context, layoutManager.orientation)
val binding = FragmentPassesBinding.bind(view).apply {
binding.run {
passesList.apply {
setHasFixedSize(true)
this.adapter = adapter
@ -73,16 +75,6 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
}
}
private fun navigateToPassPrefs() {
val direction = PassesFragmentDirections.actionPassesToPassPrefs()
findNavController().navigate(direction)
}
private fun navigateToSettings() {
val direction = PassesFragmentDirections.actionGlobalSettingsFragment()
findNavController().navigate(direction)
}
private fun handleNewPasses(
dataState: DataState<List<SatPass>>,
passesAdapter: PassesAdapter,
@ -134,6 +126,16 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
}
}
private fun navigateToPassPrefs() {
val direction = PassesFragmentDirections.actionPassesToPassPrefs()
findNavController().navigate(direction)
}
private fun navigateToSettings() {
val direction = PassesFragmentDirections.actionGlobalSettingsFragment()
findNavController().navigate(direction)
}
override fun navigateToPass(satPass: SatPass) {
if (satPass.progress < 100) {
val catNum = satPass.catNum

Wyświetl plik

@ -40,21 +40,23 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
@Inject
lateinit var preferences: ISettingsHandler
private lateinit var binding: FragmentRadarBinding
private val args: RadarFragmentArgs by navArgs()
private val viewModel: RadarViewModel by viewModels()
private var radarView: RadarView? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupComponents(view)
binding = FragmentRadarBinding.bind(view)
setupViews()
}
private fun setupComponents(view: View) {
private fun setupViews() {
val context = requireContext()
val adapter = TransmittersAdapter()
val layoutManager = LinearLayoutManager(context)
val itemDecoration = DividerItemDecoration(context, layoutManager.orientation)
FragmentRadarBinding.bind(view).apply {
binding.run {
radarRecycler.apply {
setHasFixedSize(true)
this.adapter = adapter
@ -62,14 +64,11 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
addItemDecoration(itemDecoration)
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
}
setupObservers(adapter, this)
setupObservers(adapter)
}
}
private fun setupObservers(
transmittersAdapter: TransmittersAdapter,
binding: FragmentRadarBinding
) {
private fun setupObservers(transmittersAdapter: TransmittersAdapter) {
viewModel.getPass(args.catNum, args.aosTime).observe(viewLifecycleOwner) { pass ->
radarView = RadarView(requireContext()).apply {
setShowAim(preferences.getUseCompass())
@ -79,7 +78,7 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
viewModel.radarData.observe(viewLifecycleOwner) { passData ->
radarView?.setPosition(passData.satPos)
radarView?.setPositions(passData.satTrack)
setPassText(pass, passData.satPos, binding)
setPassText(pass, passData.satPos)
}
viewModel.transmitters.observe(viewLifecycleOwner) { list ->
if (list.isNotEmpty()) {
@ -101,12 +100,7 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
}
}
private fun navigateToMap(catnum: Int) {
val direction = RadarFragmentDirections.actionGlobalMapFragment(catnum)
findNavController().navigate(direction)
}
private fun setPassText(satPass: SatPass, satPos: SatPos, binding: FragmentRadarBinding) {
private fun setPassText(satPass: SatPass, satPos: SatPos) {
val timeNow = System.currentTimeMillis()
val polarAz = getString(R.string.pat_azimuth)
val polarEl = getString(R.string.pat_elevation)
@ -135,6 +129,11 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
}
}
private fun navigateToMap(catnum: Int) {
val direction = RadarFragmentDirections.actionGlobalMapFragment(catnum)
findNavController().navigate(direction)
}
override fun onResume() {
super.onResume()
viewModel.enableSensor()

Wyświetl plik

@ -46,6 +46,7 @@ import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class SettingsFragment : Fragment(R.layout.fragment_settings) {
private lateinit var binding: FragmentSettingsBinding
private val viewModel: SettingsViewModel by viewModels()
private val locationFine = Manifest.permission.ACCESS_FINE_LOCATION
private val locationCoarse = Manifest.permission.ACCESS_COARSE_LOCATION
@ -64,23 +65,31 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val settingsBinding = FragmentSettingsBinding.bind(view)
settingsBinding.prefsBack.setOnClickListener { findNavController().navigateUp() }
setupAboutCard(settingsBinding)
setupDataCard(settingsBinding)
setupLocationCard(settingsBinding)
setupTrackingCard(settingsBinding)
setupOtherCard(settingsBinding)
setupWarrantyCard(settingsBinding)
binding = FragmentSettingsBinding.bind(view)
setupViews()
setupObservers()
}
private fun setupViews() {
binding.prefsBack.setOnClickListener { findNavController().navigateUp() }
setupAboutCard()
setupDataCard()
setupLocationCard()
setupTrackingCard()
setupOtherCard()
setupWarrantyCard()
}
private fun setupObservers() {
viewModel.stationPosition.asLiveData().observe(viewLifecycleOwner) { stationPos ->
stationPos?.let { handleStationPosition(stationPos, settingsBinding) }
stationPos?.let { handleStationPosition(stationPos) }
}
viewModel.getUpdateState().asLiveData().observe(viewLifecycleOwner) { updateState ->
updateState?.let { handleSatState(updateState, settingsBinding) }
updateState?.let { handleSatState(updateState) }
}
}
private fun setupAboutCard(binding: FragmentSettingsBinding) {
private fun setupAboutCard() {
binding.prefsInfo.aboutVersion.text =
String.format(getString(R.string.about_version), BuildConfig.VERSION_NAME)
binding.prefsInfo.aboutBtnGithub.setOnClickListener {
@ -94,8 +103,8 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
}
}
private fun setupLocationCard(binding: FragmentSettingsBinding) {
setPositionText(viewModel.getStationPosition(), binding)
private fun setupLocationCard() {
setPositionText(viewModel.getStationPosition())
binding.prefsLocation.locationBtnGps.setOnClickListener {
locationRequest.launch(arrayOf(locationFine, locationCoarse))
}
@ -114,7 +123,7 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
}
}
private fun setupDataCard(binding: FragmentSettingsBinding) {
private fun setupDataCard() {
binding.prefsData.updateBtnFile.setOnClickListener { contentRequest.launch("*/*") }
binding.prefsData.updateBtnWeb.setOnClickListener {
val action = SettingsFragmentDirections.actionPrefsToSources()
@ -126,7 +135,7 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
}
}
private fun setupTrackingCard(binding: FragmentSettingsBinding) {
private fun setupTrackingCard() {
binding.prefsTracking.trackingSwitch.apply {
isChecked = viewModel.getRotatorEnabled()
binding.prefsTracking.trackingIp.isEnabled = isChecked
@ -147,7 +156,7 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
}
}
private fun setupOtherCard(binding: FragmentSettingsBinding) {
private fun setupOtherCard() {
binding.prefsOther.otherSwitchUtc.apply {
isChecked = viewModel.getUseUTC()
setOnCheckedChangeListener { _, isChecked -> viewModel.setUseUTC(isChecked) }
@ -162,22 +171,22 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
}
}
private fun setupWarrantyCard(binding: FragmentSettingsBinding) {
private fun setupWarrantyCard() {
binding.prefsWarranty.warrantyThanks.movementMethod = LinkMovementMethod.getInstance()
binding.prefsWarranty.warrantyLicense.movementMethod = LinkMovementMethod.getInstance()
}
private fun setPositionText(geoPos: GeoPos, binding: FragmentSettingsBinding) {
private fun setPositionText(geoPos: GeoPos) {
val latFormat = getString(R.string.location_lat)
val lonFormat = getString(R.string.location_lon)
binding.prefsLocation.locationLat.text = String.format(latFormat, geoPos.latitude)
binding.prefsLocation.locationLon.text = String.format(lonFormat, geoPos.longitude)
}
private fun handleStationPosition(pos: DataState<GeoPos>, binding: FragmentSettingsBinding) {
private fun handleStationPosition(pos: DataState<GeoPos>) {
when (pos) {
is DataState.Success -> {
setPositionText(pos.data, binding)
setPositionText(pos.data)
binding.prefsLocation.locationProgress.isIndeterminate = false
viewModel.setPositionHandled()
showToast(getString(R.string.pref_pos_success))
@ -194,7 +203,7 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
}
}
private fun handleSatState(state: DataState<Long>, binding: FragmentSettingsBinding) {
private fun handleSatState(state: DataState<Long>) {
when (state) {
is DataState.Success -> {
binding.prefsData.updateProgress.isIndeterminate = false

Wyświetl plik

@ -116,8 +116,10 @@ class DataRepository(
override suspend fun getTransmitters(catnum: Int) = localSource.getTransmitters(catnum)
override suspend fun updateSelection(catnums: List<Int>, isSelected: Boolean) {
localSource.updateEntriesSelection(catnums, isSelected)
override fun updateSelection(catnums: List<Int>) {
repositoryScope.launch {
localSource.updateEntriesSelection(catnums)
}
}
private suspend fun importSatellites(stream: InputStream): List<SatEntry> {

Wyświetl plik

@ -36,7 +36,7 @@ interface ILocalSource {
suspend fun updateEntries(entries: List<SatEntry>)
suspend fun updateEntriesSelection(catnums: List<Int>, isSelected: Boolean)
suspend fun updateEntriesSelection(catnums: List<Int>)
suspend fun updateTransmitters(transmitters: List<Transmitter>)

Wyświetl plik

@ -42,5 +42,5 @@ interface IDataRepository {
suspend fun getTransmitters(catnum: Int): List<Transmitter>
suspend fun updateSelection(catnums: List<Int>, isSelected: Boolean = true)
fun updateSelection(catnums: List<Int>)
}