mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Added filter dialog, removed PassesFragment
This commit is contained in:
1 parent
a08cfc7fb8
commit
acb851d4f6
11 files changed
+79
-821
No files matched your search
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* Look4Sat. Amateur radio satellite tracker and pass predictor.
|
|
||||||
* Copyright (C) 2019-2022 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.framework.model
|
|
||||||
|
|
||||||
data class DataSource(var url: String = String())
|
|
||||||
@@ -17,54 +17,70 @@
|
|||||||
*/
|
*/
|
||||||
package com.rtbishop.look4sat.presentation.passesScreen
|
package com.rtbishop.look4sat.presentation.passesScreen
|
||||||
|
|
||||||
import android.os.Bundle
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import android.view.LayoutInflater
|
import androidx.compose.foundation.layout.Column
|
||||||
import android.view.View
|
import androidx.compose.foundation.layout.Row
|
||||||
import android.view.ViewGroup
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import android.view.WindowManager
|
import androidx.compose.material3.*
|
||||||
import androidx.appcompat.app.AppCompatDialogFragment
|
import androidx.compose.runtime.Composable
|
||||||
import com.rtbishop.look4sat.R
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import com.rtbishop.look4sat.databinding.DialogFilterBinding
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import com.rtbishop.look4sat.domain.ISettingsManager
|
import androidx.compose.ui.Alignment
|
||||||
import com.rtbishop.look4sat.presentation.setNavResult
|
import androidx.compose.ui.Modifier
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import javax.inject.Inject
|
import androidx.compose.ui.window.Dialog
|
||||||
|
import com.rtbishop.look4sat.presentation.CardButton
|
||||||
|
import com.rtbishop.look4sat.presentation.MainTheme
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@Preview(showBackground = true)
|
||||||
class FilterDialog : AppCompatDialogFragment() {
|
@Composable
|
||||||
|
private fun FilterDialogPreview() {
|
||||||
|
MainTheme { FilterDialog(8, 16.0, {}) { _, _ -> } }
|
||||||
|
}
|
||||||
|
|
||||||
@Inject
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
lateinit var preferences: ISettingsManager
|
@Composable
|
||||||
|
fun FilterDialog(hours: Int, elevation: Double, toggle: () -> Unit, save: (Int, Double) -> Unit) {
|
||||||
override fun onCreateView(inflater: LayoutInflater, group: ViewGroup?, state: Bundle?): View? {
|
val hoursValue = rememberSaveable { mutableStateOf(hours) }
|
||||||
return inflater.inflate(R.layout.dialog_filter, group, false)
|
val elevValue = rememberSaveable { mutableStateOf(elevation) }
|
||||||
}
|
Dialog(onDismissRequest = { toggle() }) {
|
||||||
|
ElevatedCard {
|
||||||
override fun onViewCreated(view: View, state: Bundle?) {
|
Column(
|
||||||
super.onViewCreated(view, state)
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
DialogFilterBinding.bind(view).apply {
|
modifier = Modifier.fillMaxWidth(1f)
|
||||||
dialog?.window?.setBackgroundDrawableResource(R.color.transparent)
|
) {
|
||||||
dialog?.window?.setLayout(
|
Text(text = "Filter passes", color = MaterialTheme.colorScheme.primary)
|
||||||
(resources.displayMetrics.widthPixels * 0.94).toInt(),
|
Text(text = "Show passes that occur within X hours")
|
||||||
WindowManager.LayoutParams.WRAP_CONTENT
|
OutlinedTextField(value = hoursValue.value.toString(), onValueChange = { newValue ->
|
||||||
)
|
val hoursAhead = try {
|
||||||
filterHoursEdit.setText(preferences.getHoursAhead().toString())
|
newValue.toInt()
|
||||||
filterElevEdit.setText(preferences.getMinElevation().toString())
|
} catch (exception: Exception) {
|
||||||
filterBtnPos.setOnClickListener {
|
12
|
||||||
val hoursAhead = try {
|
}
|
||||||
filterHoursEdit.text.toString().toInt()
|
hoursValue.value = hoursAhead
|
||||||
} catch (exception: Exception) {
|
})
|
||||||
24
|
Text(text = "Show passes with max elevation above")
|
||||||
|
OutlinedTextField(value = elevValue.value.toString(), onValueChange = { newValue ->
|
||||||
|
val maxElevation = try {
|
||||||
|
newValue.toDouble()
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
16.0
|
||||||
|
}
|
||||||
|
elevValue.value = maxElevation
|
||||||
|
})
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
CardButton(onClick = { toggle() }, text = "Cancel")
|
||||||
|
CardButton(
|
||||||
|
onClick = {
|
||||||
|
save(hoursValue.value, elevValue.value)
|
||||||
|
toggle()
|
||||||
|
}, text = "Accept"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val minElevation = try {
|
|
||||||
filterElevEdit.text.toString().toDouble()
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
16.0
|
|
||||||
}
|
|
||||||
setNavResult("prefs", Pair(hoursAhead, minElevation))
|
|
||||||
dismiss()
|
|
||||||
}
|
}
|
||||||
filterBtnNeg.setOnClickListener { dismiss() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
* Look4Sat. Amateur radio satellite tracker and pass predictor.
|
|
||||||
* Copyright (C) 2019-2022 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.passesScreen
|
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.ViewGroup
|
|
||||||
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.ItemPassBinding
|
|
||||||
import com.rtbishop.look4sat.domain.predict.SatPass
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class PassesAdapter(private val clickListener: PassesClickListener) :
|
|
||||||
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
|
||||||
|
|
||||||
private val diffCallback = object : DiffUtil.ItemCallback<SatPass>() {
|
|
||||||
override fun areItemsTheSame(oldItem: SatPass, newItem: SatPass): Boolean {
|
|
||||||
return oldItem.catNum == newItem.catNum && oldItem.aosTime == newItem.aosTime
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun areContentsTheSame(oldItem: SatPass, newItem: SatPass): Boolean {
|
|
||||||
return oldItem.progress == newItem.progress
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private val differ = AsyncListDiffer(this, diffCallback)
|
|
||||||
private var isUTC: Boolean = false
|
|
||||||
|
|
||||||
interface PassesClickListener {
|
|
||||||
fun navigateToPass(satPass: SatPass)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun submitList(passes: List<SatPass>) {
|
|
||||||
differ.submitList(passes)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setUTC(isUTC: Boolean) {
|
|
||||||
this.isUTC = isUTC
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount() = differ.currentList.size
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
|
||||||
return PassHolder.from(parent)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
|
||||||
(holder as PassHolder).bind(differ.currentList[position], clickListener, isUTC)
|
|
||||||
}
|
|
||||||
|
|
||||||
class PassHolder private constructor(private val binding: ItemPassBinding) :
|
|
||||||
RecyclerView.ViewHolder(binding.root) {
|
|
||||||
|
|
||||||
private val satIdFormat = itemView.context.getString(R.string.pass_satId)
|
|
||||||
private val aosAzFormat = itemView.context.getString(R.string.pass_aosAz)
|
|
||||||
private val altFormat = itemView.context.getString(R.string.pass_altitude)
|
|
||||||
private val losAzFormat = itemView.context.getString(R.string.pass_losAz)
|
|
||||||
private val startTimeFormat = itemView.context.getString(R.string.pass_startTime)
|
|
||||||
private val elevFormat = itemView.context.getString(R.string.pass_elevation)
|
|
||||||
private val endTimeFormat = itemView.context.getString(R.string.pass_endTime)
|
|
||||||
private val placeholder = itemView.context.getString(R.string.pass_placeholder)
|
|
||||||
private val timeZoneUTC = TimeZone.getTimeZone("UTC")
|
|
||||||
private val startFormat = SimpleDateFormat(startTimeFormat, Locale.getDefault())
|
|
||||||
private val endFormat = SimpleDateFormat(endTimeFormat, Locale.getDefault())
|
|
||||||
|
|
||||||
fun bind(satPass: SatPass, listener: PassesClickListener, shouldUseUTC: Boolean) {
|
|
||||||
binding.apply {
|
|
||||||
if (satPass.isDeepSpace) {
|
|
||||||
passName.text = satPass.name
|
|
||||||
passId.text = String.format(satIdFormat, satPass.catNum)
|
|
||||||
passAos.text = String.format(aosAzFormat, satPass.aosAzimuth)
|
|
||||||
passAltitude.text = String.format(altFormat, satPass.altitude)
|
|
||||||
passLos.text = String.format(losAzFormat, satPass.losAzimuth)
|
|
||||||
passStart.text = placeholder
|
|
||||||
passElev.text = String.format(elevFormat, satPass.maxElevation)
|
|
||||||
passEnd.text = placeholder
|
|
||||||
passProgress.progress = 100
|
|
||||||
} else {
|
|
||||||
if (shouldUseUTC) {
|
|
||||||
startFormat.timeZone = timeZoneUTC
|
|
||||||
endFormat.timeZone = timeZoneUTC
|
|
||||||
}
|
|
||||||
passName.text = satPass.name
|
|
||||||
passId.text = String.format(satIdFormat, satPass.catNum)
|
|
||||||
passAos.text = String.format(aosAzFormat, satPass.aosAzimuth)
|
|
||||||
passAltitude.text = String.format(altFormat, satPass.altitude)
|
|
||||||
passLos.text = String.format(losAzFormat, satPass.losAzimuth)
|
|
||||||
passStart.text = startFormat.format(Date(satPass.aosTime))
|
|
||||||
passElev.text = String.format(elevFormat, satPass.maxElevation)
|
|
||||||
passEnd.text = endFormat.format(Date(satPass.losTime))
|
|
||||||
passProgress.progress = satPass.progress.toInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
itemView.setOnClickListener {
|
|
||||||
listener.navigateToPass(satPass)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun from(parent: ViewGroup): PassHolder {
|
|
||||||
val inflater = LayoutInflater.from(parent.context)
|
|
||||||
return PassHolder(ItemPassBinding.inflate(inflater, parent, false))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
/*
|
|
||||||
* Look4Sat. Amateur radio satellite tracker and pass predictor.
|
|
||||||
* Copyright (C) 2019-2022 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.passesScreen
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
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
|
|
||||||
import com.rtbishop.look4sat.domain.model.DataState
|
|
||||||
import com.rtbishop.look4sat.domain.predict.SatPass
|
|
||||||
import com.rtbishop.look4sat.presentation.clickWithDebounce
|
|
||||||
import com.rtbishop.look4sat.presentation.getNavResult
|
|
||||||
import com.rtbishop.look4sat.utility.toTimerString
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesClickListener {
|
|
||||||
|
|
||||||
private val viewModel: PassesViewModel by viewModels()
|
|
||||||
private val passesAdapter = PassesAdapter(this)
|
|
||||||
private var binding: FragmentPassesBinding? = null
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
binding = FragmentPassesBinding.bind(view).apply {
|
|
||||||
passesAdapter.setUTC(viewModel.shouldUseUTC())
|
|
||||||
passesRecycler.apply {
|
|
||||||
setHasFixedSize(true)
|
|
||||||
adapter = passesAdapter
|
|
||||||
layoutManager = LinearLayoutManager(requireContext())
|
|
||||||
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
|
|
||||||
addItemDecoration(DividerItemDecoration(requireContext(), 1))
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
passesBtnRefresh.clickWithDebounce { viewModel.calculatePasses() }
|
|
||||||
passesBtnMap.clickWithDebounce {
|
|
||||||
val dir = PassesFragmentDirections.globalToMap()
|
|
||||||
findNavController().navigate(dir)
|
|
||||||
}
|
|
||||||
passesBtnFilter.clickWithDebounce {
|
|
||||||
val dir = PassesFragmentDirections.passesToFilter()
|
|
||||||
findNavController().navigate(dir)
|
|
||||||
}
|
|
||||||
passesBtnSettings.clickWithDebounce {
|
|
||||||
val dir = PassesFragmentDirections.globalToSettings()
|
|
||||||
findNavController().navigate(dir)
|
|
||||||
}
|
|
||||||
setupObservers()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun navigateToPass(satPass: SatPass) {
|
|
||||||
if (satPass.progress < 100) satPass.run {
|
|
||||||
val dir = PassesFragmentDirections.globalToRadar(this.catNum, this.aosTime)
|
|
||||||
findNavController().navigate(dir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
binding?.passesRecycler?.adapter = null
|
|
||||||
binding = null
|
|
||||||
super.onDestroyView()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupObservers() {
|
|
||||||
viewModel.entriesTotal.observe(viewLifecycleOwner) { number ->
|
|
||||||
handleEntriesTotal(number)
|
|
||||||
}
|
|
||||||
viewModel.passes.observe(viewLifecycleOwner) { passesResult ->
|
|
||||||
handleNewPasses(passesResult)
|
|
||||||
}
|
|
||||||
getNavResult<Pair<Int, Double>>(R.id.nav_passes, "prefs") { prefs ->
|
|
||||||
viewModel.calculatePasses(prefs.first, prefs.second)
|
|
||||||
}
|
|
||||||
getNavResult<List<Int>>(R.id.nav_passes, "selection") { items ->
|
|
||||||
viewModel.calculatePasses(selection = items)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleEntriesTotal(number: Int) {
|
|
||||||
binding?.run {
|
|
||||||
if (number > 0) {
|
|
||||||
passesFab.clickWithDebounce {
|
|
||||||
val direction = PassesFragmentDirections.globalToEntries()
|
|
||||||
findNavController().navigate(direction)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
passesFab.clickWithDebounce {
|
|
||||||
val errorMessage = getString(R.string.passes_empty_db)
|
|
||||||
Toast.makeText(requireContext(), errorMessage, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleNewPasses(state: DataState<List<SatPass>>) {
|
|
||||||
binding?.run {
|
|
||||||
when (state) {
|
|
||||||
is DataState.Success -> {
|
|
||||||
passesAdapter.submitList(state.data)
|
|
||||||
tickMainTimer(state.data)
|
|
||||||
if (state.data.isNotEmpty()) { // show new passes list
|
|
||||||
passesEmpty.visibility = View.INVISIBLE
|
|
||||||
passesProgress.visibility = View.INVISIBLE
|
|
||||||
} else { // show no passes message
|
|
||||||
passesEmpty.visibility = View.VISIBLE
|
|
||||||
passesProgress.visibility = View.INVISIBLE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is DataState.Loading -> {
|
|
||||||
passesEmpty.visibility = View.INVISIBLE
|
|
||||||
passesProgress.visibility = View.VISIBLE
|
|
||||||
passesTimer.text = 0L.toTimerString()
|
|
||||||
}
|
|
||||||
else -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun tickMainTimer(passes: List<SatPass>) {
|
|
||||||
binding?.run {
|
|
||||||
if (passes.isNotEmpty()) {
|
|
||||||
val timeNow = System.currentTimeMillis()
|
|
||||||
try {
|
|
||||||
val nextPass = passes.first { it.aosTime.minus(timeNow) > 0 }
|
|
||||||
val millisBeforeStart = nextPass.aosTime.minus(timeNow)
|
|
||||||
passesTimer.text = millisBeforeStart.toTimerString()
|
|
||||||
} catch (e: NoSuchElementException) {
|
|
||||||
val lastPass = passes.last()
|
|
||||||
val millisBeforeEnd = lastPass.losTime.minus(timeNow)
|
|
||||||
passesTimer.text = millisBeforeEnd.toTimerString()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
passesTimer.text = 0L.toTimerString()
|
|
||||||
}
|
|
||||||
passesBtnRefresh.isEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,6 +15,8 @@ import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
|||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
@@ -42,14 +44,23 @@ fun PassesScreen(viewModel: PassesViewModel = hiltViewModel()) {
|
|||||||
val state = viewModel.passes.observeAsState()
|
val state = viewModel.passes.observeAsState()
|
||||||
val timerText = viewModel.timerText.observeAsState()
|
val timerText = viewModel.timerText.observeAsState()
|
||||||
val isRefreshing = state.value is DataState.Loading
|
val isRefreshing = state.value is DataState.Loading
|
||||||
val refreshState = rememberPullRefreshState(
|
val refreshState = rememberPullRefreshState(refreshing = isRefreshing,
|
||||||
refreshing = isRefreshing,
|
|
||||||
onRefresh = { viewModel.calculatePasses() })
|
onRefresh = { viewModel.calculatePasses() })
|
||||||
|
|
||||||
val value = state.value
|
val value = state.value
|
||||||
var passes = emptyList<SatPass>()
|
var passes = emptyList<SatPass>()
|
||||||
if (value is DataState.Success) passes = value.data
|
if (value is DataState.Success) passes = value.data
|
||||||
|
|
||||||
|
val showDialog = rememberSaveable { mutableStateOf(false) }
|
||||||
|
val toggleDialog = { showDialog.value = showDialog.value.not() }
|
||||||
|
if (showDialog.value) {
|
||||||
|
FilterDialog(viewModel.getHoursAhead(),
|
||||||
|
viewModel.getMinElevation(),
|
||||||
|
{ toggleDialog() }) { hours, elev ->
|
||||||
|
viewModel.calculatePasses(hours, elev)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||||
ElevatedCard(modifier = Modifier.height(52.dp)) {
|
ElevatedCard(modifier = Modifier.height(52.dp)) {
|
||||||
Row(
|
Row(
|
||||||
@@ -57,7 +68,7 @@ fun PassesScreen(viewModel: PassesViewModel = hiltViewModel()) {
|
|||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
IconButton(onClick = {}) {
|
IconButton(onClick = { toggleDialog() }) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(id = R.drawable.ic_filter),
|
painter = painterResource(id = R.drawable.ic_filter),
|
||||||
contentDescription = null
|
contentDescription = null
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ class PassesViewModel @Inject constructor(
|
|||||||
val passes: LiveData<DataState<List<SatPass>>> = _passes
|
val passes: LiveData<DataState<List<SatPass>>> = _passes
|
||||||
val timerText: LiveData<Triple<String, String, String>> = _timerText
|
val timerText: LiveData<Triple<String, String, String>> = _timerText
|
||||||
|
|
||||||
|
fun getHoursAhead() = settings.getHoursAhead()
|
||||||
|
|
||||||
|
fun getMinElevation() = settings.getMinElevation()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
satelliteManager.calculatedPasses.collect { passes ->
|
satelliteManager.calculatedPasses.collect { passes ->
|
||||||
|
|||||||
@@ -1,131 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
style="@style/SurfaceCard"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/filter_title"
|
|
||||||
style="@style/DialogTitle"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:minHeight="48dp"
|
|
||||||
android:text="@string/filter_title"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/filter_hours_text"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/filter_btn_pos"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/filter_btn_neg"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/filter_hours_text"
|
|
||||||
style="@style/DialogText"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:text="@string/filter_hours_text"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/filter_hours_layout"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/filter_title"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/filter_title"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/filter_title" />
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
|
||||||
android:id="@+id/filter_hours_layout"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:hint="@string/filter_hours_hint"
|
|
||||||
android:importantForAutofill="no"
|
|
||||||
android:inputType="number"
|
|
||||||
android:minHeight="48dp"
|
|
||||||
app:endIconMode="clear_text"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/filter_elev_text"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/filter_hours_text"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/filter_hours_text"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/filter_hours_text">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
|
||||||
android:id="@+id/filter_hours_edit"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:inputType="textUri" />
|
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/filter_elev_text"
|
|
||||||
style="@style/DialogText"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:text="@string/filter_elev_text"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/filter_elev_layout"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/filter_hours_text"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/filter_hours_text"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/filter_hours_layout" />
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
|
||||||
android:id="@+id/filter_elev_layout"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:hint="@string/filter_elev_hint"
|
|
||||||
android:importantForAutofill="no"
|
|
||||||
android:inputType="number|numberDecimal"
|
|
||||||
android:minHeight="48dp"
|
|
||||||
app:endIconMode="clear_text"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/filter_btn_neg"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/filter_hours_layout"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/filter_hours_layout"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/filter_elev_text">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
|
||||||
android:id="@+id/filter_elev_edit"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:inputType="textUri" />
|
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/filter_btn_neg"
|
|
||||||
style="@style/NormalButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="6dp"
|
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:layout_marginBottom="6dp"
|
|
||||||
android:text="@string/btn_cancel"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/filter_btn_pos"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/filter_elev_layout" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/filter_btn_pos"
|
|
||||||
style="@style/NormalButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="6dp"
|
|
||||||
android:text="@string/btn_accept"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@+id/filter_btn_neg"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/filter_btn_neg" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
style="@style/SurfaceCard"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/sources_title"
|
|
||||||
style="@style/DialogTitle"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginStart="22dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:text="@string/sources_title"
|
|
||||||
android:textSize="18sp"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@+id/sources_btn_add"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/sources_btn_add"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/sources_btn_neg" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/sources_btn_add"
|
|
||||||
style="@style/NormalButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:text="@string/btn_add"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/sources_btn_pos"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/sources_title"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/sources_recycler"
|
|
||||||
style="@style/Recycler"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginStart="2dp"
|
|
||||||
android:layout_marginTop="2dp"
|
|
||||||
android:layout_marginEnd="2dp"
|
|
||||||
android:layout_marginBottom="2dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/sources_btn_pos"
|
|
||||||
app:layout_constraintDimensionRatio="w,1:1"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/sources_btn_pos"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/sources_btn_neg"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/sources_btn_add" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/sources_btn_neg"
|
|
||||||
style="@style/NormalButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="6dp"
|
|
||||||
android:layout_marginBottom="6dp"
|
|
||||||
android:text="@string/btn_cancel"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/sources_btn_pos"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/sources_btn_pos"
|
|
||||||
style="@style/NormalButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="6dp"
|
|
||||||
android:text="@string/btn_accept"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@+id/sources_btn_neg"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/sources_btn_neg" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:transitionGroup="true">
|
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
|
||||||
android:id="@+id/passes_toolbar"
|
|
||||||
style="@style/Toolbar">
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/passes_btn_refresh"
|
|
||||||
style="@style/ToolbarButton"
|
|
||||||
android:rotation="45"
|
|
||||||
android:layout_gravity="start|center_vertical"
|
|
||||||
android:contentDescription="@string/btn_refresh"
|
|
||||||
android:src="@drawable/ic_refresh" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/passes_timer"
|
|
||||||
style="@style/ToolbarTimer" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/passes_btn_map"
|
|
||||||
style="@style/ToolbarButton"
|
|
||||||
android:layout_gravity="end|center_vertical"
|
|
||||||
android:contentDescription="@string/btn_map"
|
|
||||||
android:src="@drawable/ic_map" />
|
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
|
||||||
style="@style/SurfaceCard"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginStart="@dimen/view_default_margin"
|
|
||||||
android:layout_marginTop="@dimen/surface_margin_top"
|
|
||||||
android:layout_marginEnd="@dimen/view_default_margin"
|
|
||||||
android:layout_marginBottom="@dimen/surface_margin_bot">
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/passes_recycler"
|
|
||||||
style="@style/Recycler"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/passes_progress"
|
|
||||||
style="@style/RecyclerProgress" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/passes_empty"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_marginStart="48dp"
|
|
||||||
android:layout_marginEnd="48dp"
|
|
||||||
android:layout_marginBottom="32dp"
|
|
||||||
android:orientation="vertical"
|
|
||||||
tools:ignore="UseCompoundDrawables">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/passes_empty_img"
|
|
||||||
android:layout_width="160dp"
|
|
||||||
android:layout_height="160dp"
|
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:layout_marginBottom="32dp"
|
|
||||||
android:contentDescription="@string/passes_error"
|
|
||||||
android:src="@drawable/ic_list"
|
|
||||||
app:tint="@color/textDisabled" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/passes_empty_msg"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/passes_error"
|
|
||||||
android:textSize="@dimen/text_size_mediumLarge" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
|
|
||||||
<com.google.android.material.bottomappbar.BottomAppBar
|
|
||||||
android:id="@+id/passes_bottomBar"
|
|
||||||
style="@style/BottomBar">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/passes_btn_filter"
|
|
||||||
style="@style/NormalButton"
|
|
||||||
android:layout_width="@dimen/button_width_max"
|
|
||||||
android:layout_marginStart="@dimen/button_margin_side"
|
|
||||||
android:layout_gravity="start|center_vertical"
|
|
||||||
android:text="@string/btn_filter" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/passes_btn_settings"
|
|
||||||
style="@style/NormalButton"
|
|
||||||
android:layout_width="@dimen/button_width_max"
|
|
||||||
android:layout_marginEnd="@dimen/button_margin_side"
|
|
||||||
android:layout_gravity="end|center_vertical"
|
|
||||||
android:text="@string/btn_settings" />
|
|
||||||
|
|
||||||
</com.google.android.material.bottomappbar.BottomAppBar>
|
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
||||||
android:id="@+id/passes_fab"
|
|
||||||
style="@style/FloatingActionButton"
|
|
||||||
android:src="@drawable/ic_satellite"
|
|
||||||
android:contentDescription="@string/btn_satellites"
|
|
||||||
app:layout_anchor="@id/passes_bottomBar" />
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
style="@style/RecyclerItemCard">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:id="@+id/pass_root"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="?android:selectableItemBackground">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pass_name"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:text="@string/pass_satName"
|
|
||||||
android:textColor="@color/accent"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pass_id"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:text="@string/pass_satId"
|
|
||||||
android:textColor="@color/accent"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@+id/pass_name"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pass_aos"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="2dp"
|
|
||||||
android:text="@string/pass_aosAz"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/pass_los"
|
|
||||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/pass_name"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/pass_name" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pass_altitude"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/pass_altitude"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@+id/pass_aos"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/pass_los"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/pass_aos" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pass_los"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/pass_losAz"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@+id/pass_aos"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/pass_id"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/pass_aos" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pass_start"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="2dp"
|
|
||||||
android:text="@string/pass_startTime"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/pass_end"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/pass_aos"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/pass_aos" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pass_elev"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/pass_elevation"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@+id/pass_start"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/pass_end"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/pass_start" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pass_end"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/pass_endTime"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
|
||||||
app:layout_constraintBaseline_toBaselineOf="@+id/pass_start"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/pass_los"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/pass_start" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/pass_progress"
|
|
||||||
style="?android:attr/progressBarStyleHorizontal"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="1dp"
|
|
||||||
android:layout_marginBottom="2dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/pass_end"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/pass_start"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/pass_elev" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
@@ -3,19 +3,7 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/nav_root"
|
android:id="@+id/nav_root"
|
||||||
app:startDestination="@id/nav_passes">
|
app:startDestination="@id/nav_radar">
|
||||||
<fragment
|
|
||||||
android:id="@+id/nav_passes"
|
|
||||||
android:name="com.rtbishop.look4sat.presentation.passesScreen.PassesFragment"
|
|
||||||
tools:layout="@layout/fragment_passes">
|
|
||||||
<action
|
|
||||||
android:id="@+id/passes_to_filter"
|
|
||||||
app:destination="@id/nav_filter"
|
|
||||||
app:enterAnim="@anim/nav_default_enter_anim"
|
|
||||||
app:exitAnim="@anim/nav_default_exit_anim"
|
|
||||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
|
||||||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
|
||||||
</fragment>
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/nav_radar"
|
android:id="@+id/nav_radar"
|
||||||
android:name="com.rtbishop.look4sat.presentation.radarScreen.RadarFragment"
|
android:name="com.rtbishop.look4sat.presentation.radarScreen.RadarFragment"
|
||||||
@@ -46,10 +34,6 @@
|
|||||||
android:id="@+id/nav_modes"
|
android:id="@+id/nav_modes"
|
||||||
android:name="com.rtbishop.look4sat.presentation.entriesScreen.ModesDialog"
|
android:name="com.rtbishop.look4sat.presentation.entriesScreen.ModesDialog"
|
||||||
tools:layout="@layout/dialog_modes" />
|
tools:layout="@layout/dialog_modes" />
|
||||||
<dialog
|
|
||||||
android:id="@+id/nav_filter"
|
|
||||||
android:name="com.rtbishop.look4sat.presentation.passesScreen.FilterDialog"
|
|
||||||
tools:layout="@layout/dialog_filter" />
|
|
||||||
<dialog
|
<dialog
|
||||||
android:id="@+id/nav_position"
|
android:id="@+id/nav_position"
|
||||||
android:name="com.rtbishop.look4sat.presentation.settingsScreen.PositionDialog"
|
android:name="com.rtbishop.look4sat.presentation.settingsScreen.PositionDialog"
|
||||||
|
|||||||
Reference in new issue
Block a user