mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-04 11:37:22 +00:00
Added BottomAppBar to several fragments, various ui changes
This commit is contained in:
1 parent
64b5010a44
commit
bdc0000476
61 files changed
+626
-390
No files matched your search
@@ -24,8 +24,6 @@ import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import androidx.navigation.ui.NavigationUI
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.databinding.ActivityMainBinding
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
@@ -43,14 +41,14 @@ class MainActivity : AppCompatActivity() {
|
||||
val binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
val host = supportFragmentManager.findFragmentById(R.id.navigation_host) as NavHostFragment
|
||||
setContentView(binding.root)
|
||||
binding.navigationBar.apply {
|
||||
setupWithNavController(host.navController)
|
||||
setOnItemSelectedListener { item ->
|
||||
NavigationUI.onNavDestinationSelected(item, host.navController)
|
||||
host.navController.popBackStack(item.itemId, inclusive = false)
|
||||
true
|
||||
}
|
||||
}
|
||||
// binding.navigationBar.apply {
|
||||
// setupWithNavController(host.navController)
|
||||
// setOnItemSelectedListener { item ->
|
||||
// NavigationUI.onNavDestinationSelected(item, host.navController)
|
||||
// host.navController.popBackStack(item.itemId, inclusive = false)
|
||||
// true
|
||||
// }
|
||||
// }
|
||||
mainViewModel.calculatePasses()
|
||||
}
|
||||
}
|
||||
+9
-4
@@ -32,6 +32,7 @@ import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.databinding.FragmentEntriesBinding
|
||||
import com.rtbishop.look4sat.domain.model.DataState
|
||||
import com.rtbishop.look4sat.domain.model.SatItem
|
||||
import com.rtbishop.look4sat.presentation.setNavResult
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -59,11 +60,15 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) {
|
||||
addItemDecoration(itemDecoration)
|
||||
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
|
||||
}
|
||||
entriesBack.setOnClickListener { findNavController().navigateUp() }
|
||||
entriesBackBtn.setOnClickListener { findNavController().navigateUp() }
|
||||
entriesSearch.doOnTextChanged { text, _, _, _ -> viewModel.setQuery(text.toString()) }
|
||||
entriesMode.setOnClickListener { showModesDialog() }
|
||||
entriesSelectAll.setOnClickListener { viewModel.selectCurrentItems() }
|
||||
entriesAccept.setOnClickListener { viewModel.saveSelection() }
|
||||
entriesModesBtn.setOnClickListener { showModesDialog() }
|
||||
entriesSelectBtn.setOnClickListener { viewModel.selectCurrentItems(true) }
|
||||
entriesClearBtn.setOnClickListener { viewModel.selectCurrentItems(false) }
|
||||
entriesAcceptBtn.setOnClickListener {
|
||||
setNavResult("selection", viewModel.saveSelection())
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
}
|
||||
viewModel.satData.observe(viewLifecycleOwner) { satData ->
|
||||
handleSatData(satData, binding, adapter)
|
||||
|
||||
+10
-9
@@ -41,13 +41,13 @@ class EntriesViewModel @Inject constructor(
|
||||
private val itemsWithQuery = currentQuery.switchMap { query ->
|
||||
itemsWithModes.map { items -> filterByQuery(items, query) }
|
||||
}
|
||||
private var shouldSelectAll = true
|
||||
// private var shouldSelectAll = true
|
||||
val satData = itemsWithQuery.map { items -> DataState.Success(items) }
|
||||
|
||||
fun selectCurrentItems() {
|
||||
fun selectCurrentItems(selectAll: Boolean) {
|
||||
itemsWithQuery.value?.let { itemsWithQuery ->
|
||||
updateSelection(itemsWithQuery.map { item -> item.catnum }, shouldSelectAll)
|
||||
shouldSelectAll = shouldSelectAll.not()
|
||||
updateSelection(itemsWithQuery.map { item -> item.catnum }, selectAll)
|
||||
// shouldSelectAll = shouldSelectAll.not()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,15 +61,16 @@ class EntriesViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun setQuery(query: String) {
|
||||
shouldSelectAll = true
|
||||
// shouldSelectAll = true
|
||||
currentQuery.value = query
|
||||
}
|
||||
|
||||
fun saveSelection() {
|
||||
itemsFromRepo.value?.let { itemsAll ->
|
||||
fun saveSelection(): List<Int> {
|
||||
return itemsFromRepo.value?.let { itemsAll ->
|
||||
val filteredItems = itemsAll.filter { item -> item.isSelected }
|
||||
repository.setEntriesSelection(filteredItems.map { item -> item.catnum })
|
||||
}
|
||||
// repository.setEntriesSelection(filteredItems.map { item -> item.catnum })
|
||||
filteredItems.map { item -> item.catnum }
|
||||
} ?: emptyList()
|
||||
}
|
||||
|
||||
override fun updateSelection(catNums: List<Int>, isSelected: Boolean) {
|
||||
|
||||
@@ -92,9 +92,9 @@ 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) }
|
||||
mapBackBtn.setOnClickListener { findNavController().navigateUp() }
|
||||
mapPrevBtn.setOnClickListener { viewModel.scrollSelection(true) }
|
||||
mapNextBtn.setOnClickListener { viewModel.scrollSelection(false) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+41
-26
@@ -24,6 +24,7 @@ import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.databinding.FragmentPassesBinding
|
||||
@@ -51,59 +52,59 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
|
||||
val layoutManager = LinearLayoutManager(context)
|
||||
val itemDecoration = DividerItemDecoration(context, layoutManager.orientation)
|
||||
binding.run {
|
||||
passesList.apply {
|
||||
passesRecycler.apply {
|
||||
setHasFixedSize(true)
|
||||
this.adapter = adapter
|
||||
this.layoutManager = layoutManager
|
||||
addItemDecoration(itemDecoration)
|
||||
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
|
||||
addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
if (dy > 0 && passesFab.visibility == View.VISIBLE) passesFab.hide()
|
||||
else if (dy < 0 && passesFab.visibility != View.VISIBLE) passesFab.show()
|
||||
}
|
||||
})
|
||||
}
|
||||
passesSwipe.apply {
|
||||
setColorSchemeResources(R.color.surfaceToolbar)
|
||||
setProgressBackgroundColorSchemeResource(R.color.themeAccent)
|
||||
setOnRefreshListener { passesViewModel.forceCalculation() }
|
||||
}
|
||||
passesFilter.setOnClickListener { navigateToPassPrefs() }
|
||||
passesSettings.setOnClickListener { navigateToSettings() }
|
||||
passesRefreshBtn.setOnClickListener { refreshPasses() }
|
||||
passesMapBtn.setOnClickListener { navigateToMap() }
|
||||
passesFilterBtn.setOnClickListener { navigateToPassPrefs() }
|
||||
passesFab.setOnClickListener { navigateToEntries() }
|
||||
passesSettingsBtn.setOnClickListener { navigateToSettings() }
|
||||
}
|
||||
passesViewModel.passes.observe(viewLifecycleOwner) { passesResult ->
|
||||
handleNewPasses(passesResult, adapter, binding)
|
||||
handleNewPasses(passesResult, adapter)
|
||||
}
|
||||
getNavResult<Pair<Int, Double>>(R.id.nav_passes, "prefs") { prefs ->
|
||||
passesViewModel.saveCalculationPrefs(prefs.first, prefs.second)
|
||||
passesViewModel.forceCalculation(prefs.first, prefs.second)
|
||||
}
|
||||
getNavResult<List<Int>>(R.id.nav_passes, "selection") { selection ->
|
||||
passesViewModel.saveSelectionAndRecalc(selection)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleNewPasses(
|
||||
dataState: DataState<List<SatPass>>,
|
||||
passesAdapter: PassesAdapter,
|
||||
binding: FragmentPassesBinding
|
||||
) {
|
||||
when (dataState) {
|
||||
private fun handleNewPasses(state: DataState<List<SatPass>>, adapter: PassesAdapter) {
|
||||
when (state) {
|
||||
is DataState.Success -> {
|
||||
passesAdapter.submitList(dataState.data)
|
||||
adapter.submitList(state.data)
|
||||
binding.apply {
|
||||
passesSwipe.isRefreshing = false
|
||||
passesList.visibility = View.VISIBLE
|
||||
passesError.visibility = View.INVISIBLE
|
||||
passesRecycler.visibility = View.VISIBLE
|
||||
passesErrorMsg.visibility = View.INVISIBLE
|
||||
}
|
||||
tickMainTimer(dataState.data, binding)
|
||||
tickMainTimer(state.data, binding)
|
||||
}
|
||||
is DataState.Loading -> {
|
||||
binding.apply {
|
||||
passesTimer.text = 0L.toTimerString()
|
||||
passesSwipe.isRefreshing = true
|
||||
passesList.visibility = View.INVISIBLE
|
||||
passesError.visibility = View.INVISIBLE
|
||||
passesRecycler.visibility = View.INVISIBLE
|
||||
passesErrorMsg.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
binding.apply {
|
||||
passesTimer.text = 0L.toTimerString()
|
||||
passesSwipe.isRefreshing = false
|
||||
passesList.visibility = View.INVISIBLE
|
||||
passesError.visibility = View.VISIBLE
|
||||
passesRecycler.visibility = View.INVISIBLE
|
||||
passesErrorMsg.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,11 +127,25 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshPasses() {
|
||||
passesViewModel.forceCalculation()
|
||||
}
|
||||
|
||||
private fun navigateToMap() {
|
||||
val direction = PassesFragmentDirections.actionGlobalMapFragment()
|
||||
findNavController().navigate(direction)
|
||||
}
|
||||
|
||||
private fun navigateToPassPrefs() {
|
||||
val direction = PassesFragmentDirections.actionPassesToPassPrefs()
|
||||
findNavController().navigate(direction)
|
||||
}
|
||||
|
||||
private fun navigateToEntries() {
|
||||
val direction = PassesFragmentDirections.actionGlobalEntriesFragment()
|
||||
findNavController().navigate(direction)
|
||||
}
|
||||
|
||||
private fun navigateToSettings() {
|
||||
val direction = PassesFragmentDirections.actionGlobalSettingsFragment()
|
||||
findNavController().navigate(direction)
|
||||
|
||||
@@ -57,6 +57,13 @@ class PassesViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun saveSelectionAndRecalc(selection: List<Int>) {
|
||||
viewModelScope.launch {
|
||||
repository.setEntriesSelection(selection)
|
||||
forceCalculation()
|
||||
}
|
||||
}
|
||||
|
||||
fun forceCalculation(
|
||||
hoursAhead: Int = settings.getHoursAhead(),
|
||||
minElevation: Double = settings.getMinElevation(),
|
||||
|
||||
@@ -53,7 +53,7 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
|
||||
|
||||
private fun setupViews() {
|
||||
val context = requireContext()
|
||||
val adapter = RadiosAdapter()
|
||||
val adapter = RadioAdapter()
|
||||
val layoutManager = LinearLayoutManager(context)
|
||||
val itemDecoration = DividerItemDecoration(context, layoutManager.orientation)
|
||||
binding.run {
|
||||
@@ -68,7 +68,7 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupObservers(radiosAdapter: RadiosAdapter) {
|
||||
private fun setupObservers(radioAdapter: RadioAdapter) {
|
||||
viewModel.getPass(args.catNum, args.aosTime).observe(viewLifecycleOwner) { pass ->
|
||||
radarView = RadarView(requireContext()).apply {
|
||||
setShowAim(preferences.getUseCompass())
|
||||
@@ -82,7 +82,7 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
|
||||
}
|
||||
viewModel.transmitters.observe(viewLifecycleOwner) { list ->
|
||||
if (list.isNotEmpty()) {
|
||||
radiosAdapter.submitList(list)
|
||||
radioAdapter.submitList(list)
|
||||
binding.radarRecyclerMsg.text = getString(R.string.trans_data)
|
||||
} else {
|
||||
binding.radarRecyclerMsg.text = getString(R.string.trans_no_data)
|
||||
|
||||
+34
-41
@@ -23,11 +23,11 @@ import androidx.recyclerview.widget.AsyncListDiffer
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.databinding.ItemTransBinding
|
||||
import com.rtbishop.look4sat.databinding.ItemRadioBinding
|
||||
import com.rtbishop.look4sat.domain.model.SatRadio
|
||||
import java.util.*
|
||||
|
||||
class RadiosAdapter : RecyclerView.Adapter<RadiosAdapter.TransHolder>() {
|
||||
class RadioAdapter : RecyclerView.Adapter<RadioAdapter.TransHolder>() {
|
||||
|
||||
private val diffCallback = object : DiffUtil.ItemCallback<SatRadio>() {
|
||||
override fun areItemsTheSame(oldItem: SatRadio, newItem: SatRadio): Boolean {
|
||||
@@ -40,9 +40,7 @@ class RadiosAdapter : RecyclerView.Adapter<RadiosAdapter.TransHolder>() {
|
||||
}
|
||||
private val differ = AsyncListDiffer(this, diffCallback)
|
||||
|
||||
fun submitList(radios: List<SatRadio>) {
|
||||
differ.submitList(radios)
|
||||
}
|
||||
fun submitList(items: List<SatRadio>) = differ.submitList(items)
|
||||
|
||||
override fun getItemCount() = differ.currentList.size
|
||||
|
||||
@@ -54,56 +52,51 @@ class RadiosAdapter : RecyclerView.Adapter<RadiosAdapter.TransHolder>() {
|
||||
holder.bind(differ.currentList[position])
|
||||
}
|
||||
|
||||
class TransHolder private constructor(private val binding: ItemTransBinding) :
|
||||
class TransHolder private constructor(private val binding: ItemRadioBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
private val divider = 1000000f
|
||||
private val strNo = itemView.context.getString(R.string.no)
|
||||
private val strYes = itemView.context.getString(R.string.yes)
|
||||
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 formatLink = itemView.context.getString(R.string.trans_link_low)
|
||||
private val formatLinkNull = itemView.context.getString(R.string.trans_no_link)
|
||||
private val isInverted = itemView.context.getString(R.string.trans_inverted)
|
||||
private val inverted = itemView.context.getString(R.string.trans_inverted)
|
||||
|
||||
fun bind(radio: SatRadio) {
|
||||
binding.transDesc.text = radio.info
|
||||
|
||||
radio.downlink.let { downlink ->
|
||||
if (downlink != null) {
|
||||
val downlinkFreq = downlink / divider
|
||||
binding.transDownlink.text =
|
||||
String.format(Locale.ENGLISH, formatLink, downlinkFreq)
|
||||
} else {
|
||||
binding.transDownlink.text = formatLinkNull
|
||||
binding.run {
|
||||
radioInfo.text = radio.info
|
||||
radio.downlink.let { downlink ->
|
||||
if (downlink != null) {
|
||||
radioDownlink.text = String.format(Locale.ENGLISH, link, downlink / divider)
|
||||
} else {
|
||||
radioDownlink.text = linkNull
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
radio.uplink.let { uplink ->
|
||||
if (uplink != null) {
|
||||
val uplinkFreq = uplink / divider
|
||||
binding.transUplink.text = String.format(Locale.ENGLISH, formatLink, uplinkFreq)
|
||||
} else {
|
||||
binding.transUplink.text = formatLinkNull
|
||||
radio.uplink.let { uplink ->
|
||||
if (uplink != null) {
|
||||
radioUplink.text = String.format(Locale.ENGLISH, link, uplink / divider)
|
||||
} else {
|
||||
radioUplink.text = linkNull
|
||||
}
|
||||
}
|
||||
if (radio.mode != null) {
|
||||
radioMode.text = String.format(mode, radio.mode)
|
||||
} else {
|
||||
radioMode.text = String.format(mode, stringNo)
|
||||
}
|
||||
if (radio.isInverted) {
|
||||
radioInverted.text = String.format(inverted, stringYes)
|
||||
} else {
|
||||
radioInverted.text = String.format(inverted, stringNo)
|
||||
}
|
||||
}
|
||||
|
||||
if (radio.mode != null) {
|
||||
binding.transMode.text = String.format(mode, radio.mode)
|
||||
} else {
|
||||
binding.transMode.text = String.format(mode, strNo)
|
||||
}
|
||||
|
||||
if (radio.isInverted) {
|
||||
binding.transInverted.text = String.format(isInverted, strYes)
|
||||
} else {
|
||||
binding.transInverted.text = String.format(isInverted, strNo)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun from(parent: ViewGroup): TransHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
return TransHolder(ItemTransBinding.inflate(inflater, parent, false))
|
||||
return TransHolder(ItemRadioBinding.inflate(inflater, parent, false))
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
@@ -27,6 +27,7 @@ import android.widget.EditText
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
@@ -71,6 +72,11 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
binding.settingsScroll.apply {
|
||||
setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, y, _, newY ->
|
||||
if (y > newY) binding.settingsFab.hide() else binding.settingsFab.show()
|
||||
})
|
||||
}
|
||||
binding.prefsBack.setOnClickListener { findNavController().navigateUp() }
|
||||
setupAboutCard()
|
||||
setupDataCard()
|
||||
|
||||
Reference in new issue
Block a user