Added multiple fixes to MapScreen and components

This commit is contained in:
Arty Bishop committed 2025-12-27 15:01:47 +00:00
1 parent 5b62474c27
commit 880fe10bfd
6 files changed
+192 -134

No files matched your search

@@ -209,11 +209,12 @@ fun CardButton(onClick: () -> Unit, text: String, modifier: Modifier = Modifier)
} }
@Composable @Composable
fun CardIcon(onClick: () -> Unit, iconId: Int, description: String? = null) { fun CardIcon(onClick: () -> Unit, iconId: Int, modifier: Modifier = Modifier) {
val clickableModifier = Modifier.clickable { onClick() } val clickableModifier = Modifier.clickable { onClick() }
val iconRes = ImageVector.vectorResource(iconId)
ElevatedCard(modifier = Modifier.size(48.dp)) { ElevatedCard(modifier = Modifier.size(48.dp)) {
Box(modifier = clickableModifier.fillMaxSize(), contentAlignment = Alignment.Center) { Box(modifier = clickableModifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Icon(imageVector = ImageVector.vectorResource(iconId), contentDescription = description) Icon(imageVector = iconRes, contentDescription = null, modifier = modifier)
} }
} }
} }
@@ -16,9 +16,10 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ElevatedCard import androidx.compose.material3.ElevatedCard
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.State
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
@@ -26,6 +27,7 @@ import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavGraphBuilder import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
@@ -38,7 +40,6 @@ import com.rtbishop.look4sat.presentation.components.CardIcon
import com.rtbishop.look4sat.presentation.components.NextPassRow import com.rtbishop.look4sat.presentation.components.NextPassRow
import com.rtbishop.look4sat.presentation.components.TimerBar import com.rtbishop.look4sat.presentation.components.TimerBar
import com.rtbishop.look4sat.presentation.components.TimerRow import com.rtbishop.look4sat.presentation.components.TimerRow
import com.rtbishop.look4sat.presentation.components.getDefaultPass
import org.osmdroid.tileprovider.tilesource.XYTileSource import org.osmdroid.tileprovider.tilesource.XYTileSource
import org.osmdroid.util.GeoPoint import org.osmdroid.util.GeoPoint
import org.osmdroid.views.CustomZoomButtonsController import org.osmdroid.views.CustomZoomButtonsController
@@ -70,31 +71,34 @@ private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
private val labelRect = Rect() private val labelRect = Rect()
fun NavGraphBuilder.mapDestination() { fun NavGraphBuilder.mapDestination() {
composable(Screen.Map.route) { MapScreen() } composable(Screen.Map.route) {
val viewModel = viewModel(MapViewModel::class.java, factory = MapViewModel.Factory)
val uiState = viewModel.uiState.collectAsStateWithLifecycle()
MapScreen(uiState)
}
} }
@Composable @Composable
private fun MapScreen() { private fun MapScreen(uiState: State<MapState>) {
val viewModel = viewModel(MapViewModel::class.java, factory = MapViewModel.Factory) val onItemClick = { item: OrbitalObject -> uiState.value.sendAction(MapAction.SelectItem(item)) }
viewModel.selectDefaultSatellite(-1) val selectPrev = { uiState.value.sendAction(MapAction.SelectPrev) }
val stationPos = viewModel.stationPosition.collectAsState(initial = null) val selectNext = { uiState.value.sendAction(MapAction.SelectNext) }
val positions = viewModel.positions.collectAsState(initial = null) val rotateMod = Modifier.rotate(180f)
val satTrack = viewModel.track.collectAsState(initial = null) val timeString = uiState.value.mapData?.aosTime ?: "00:00:00"
val footprint = viewModel.footprint.collectAsState(initial = null) val isTimeAos = uiState.value.mapData?.isTimeAos ?: true
val positionClick = { orbitalObject: OrbitalObject -> viewModel.selectSatellite(orbitalObject) }
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) { Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
TimerRow { TimerRow {
CardIcon(onClick = {}, iconId = R.drawable.ic_filter) CardIcon(onClick = selectPrev, iconId = R.drawable.ic_arrow, modifier = rotateMod)
TimerBar(timeString = "88:88:88", isTimeAos = true) TimerBar(timeString = timeString, isTimeAos = isTimeAos)
CardIcon(onClick = {}, iconId = R.drawable.ic_satellite) CardIcon(onClick = selectNext, iconId = R.drawable.ic_arrow)
} }
NextPassRow(pass = getDefaultPass()) NextPassRow(pass = uiState.value.orbitalPass)
ElevatedCard(modifier = Modifier.fillMaxSize()) { ElevatedCard(modifier = Modifier.fillMaxSize()) {
MapView(modifier = Modifier.fillMaxSize(), isLightTheme = viewModel.stateOfLightTheme) { mapView -> MapView(modifier = Modifier.fillMaxSize(), isLightUi = uiState.value.isLightUi) { mapView ->
stationPos.value?.let { setStationPosition(it, mapView) } uiState.value.stationPosition?.let { setStationPosition(it, mapView) }
positions.value?.let { setPositions(it, mapView, positionClick) } uiState.value.positions?.let { setPositions(it, mapView, onItemClick) }
satTrack.value?.let { setSatelliteTrack(it, mapView) } uiState.value.track?.let { setSatelliteTrack(it, mapView) }
footprint.value?.let { setFootprint(it, mapView) } uiState.value.footprint?.let { setFootprint(it, mapView) }
} }
} }
} }
@@ -218,10 +222,10 @@ private fun setFootprint(orbitalPos: OrbitalPos, mapView: MapView) {
@Composable @Composable
private fun MapView( private fun MapView(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
isLightTheme: Boolean, isLightUi: Boolean,
update: ((map: MapView) -> Unit)? = null update: ((map: MapView) -> Unit)? = null
) { ) {
val mapView = rememberMapViewWithLifecycle(isLightTheme) val mapView = rememberMapViewWithLifecycle(isLightUi)
AndroidView({ mapView }, modifier) { update?.invoke(it) } AndroidView({ mapView }, modifier) { update?.invoke(it) }
} }
@@ -18,11 +18,33 @@
package com.rtbishop.look4sat.presentation.map package com.rtbishop.look4sat.presentation.map
import com.rtbishop.look4sat.domain.predict.GeoPos import com.rtbishop.look4sat.domain.predict.GeoPos
import com.rtbishop.look4sat.domain.predict.OrbitalObject
import com.rtbishop.look4sat.domain.predict.OrbitalPass
import com.rtbishop.look4sat.domain.predict.OrbitalPos
data class MapState(
val mapData: MapData?,
val isLightUi: Boolean,
val stationPosition: GeoPos?,
val orbitalPass: OrbitalPass,
val track: List<List<GeoPos>>?,
val footprint: OrbitalPos?,
val positions: Map<OrbitalObject, GeoPos>?,
val sendAction: (MapAction) -> Unit
)
sealed class MapAction {
data object SelectPrev: MapAction()
data object SelectNext: MapAction()
data class SelectItem(val item: OrbitalObject): MapAction()
data class SelectDefaultItem(val catnum: Int): MapAction()
}
data class MapData( data class MapData(
val catNum: Int, val catNum: Int,
val name: String, val name: String,
val aosTime: String, val aosTime: String,
val isTimeAos: Boolean,
val azimuth: Double, val azimuth: Double,
val elevation: Double, val elevation: Double,
val range: Double, val range: Double,
@@ -25,7 +25,6 @@ import androidx.lifecycle.viewmodel.viewModelFactory
import com.rtbishop.look4sat.MainApplication import com.rtbishop.look4sat.MainApplication
import com.rtbishop.look4sat.domain.predict.GeoPos import com.rtbishop.look4sat.domain.predict.GeoPos
import com.rtbishop.look4sat.domain.predict.OrbitalObject import com.rtbishop.look4sat.domain.predict.OrbitalObject
import com.rtbishop.look4sat.domain.predict.OrbitalPos
import com.rtbishop.look4sat.domain.repository.ISatelliteRepo import com.rtbishop.look4sat.domain.repository.ISatelliteRepo
import com.rtbishop.look4sat.domain.repository.ISettingsRepo import com.rtbishop.look4sat.domain.repository.ISettingsRepo
import com.rtbishop.look4sat.domain.utility.clipLat import com.rtbishop.look4sat.domain.utility.clipLat
@@ -33,60 +32,62 @@ import com.rtbishop.look4sat.domain.utility.clipLon
import com.rtbishop.look4sat.domain.utility.positionToQth import com.rtbishop.look4sat.domain.utility.positionToQth
import com.rtbishop.look4sat.domain.utility.toDegrees import com.rtbishop.look4sat.domain.utility.toDegrees
import com.rtbishop.look4sat.domain.utility.toTimerString import com.rtbishop.look4sat.domain.utility.toTimerString
import java.util.Date import com.rtbishop.look4sat.presentation.components.getDefaultPass
import kotlin.collections.set
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.update
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.Date
import kotlin.collections.set
class MapViewModel(private val satelliteRepo: ISatelliteRepo, settingsRepo: ISettingsRepo) : ViewModel() { class MapViewModel(private val satelliteRepo: ISatelliteRepo, settingsRepo: ISettingsRepo) :
ViewModel() {
private val stationPos = settingsRepo.stationPosition.value private val stationPos = settingsRepo.stationPosition.value
private val defaultPass = getDefaultPass()
private val _uiState = MutableStateFlow(
MapState(
mapData = null,
isLightUi = settingsRepo.otherSettings.value.stateOfLightTheme,
stationPosition = null,
orbitalPass = defaultPass,
track = null,
footprint = null,
positions = null,
sendAction = ::handleAction
)
)
private var allPasses = satelliteRepo.passes.value private var allPasses = satelliteRepo.passes.value
private var allSatellites = satelliteRepo.satellites.value private var allSatellites = satelliteRepo.satellites.value
private var dataUpdateJob: Job? = null private var dataUpdateJob: Job? = null
private var dataUpdateRate = 1000L private var dataUpdateRate = 1000L
private var selectedOrbitalObject: OrbitalObject? = null private var selectedOrbitalObject: OrbitalObject? = null
val uiState: StateFlow<MapState> = _uiState
val stateOfLightTheme = settingsRepo.otherSettings.value.stateOfLightTheme init {
selectDefaultSatellite(-1)
val stationPosition = flow {
val osmLat = clipLat(stationPos.latitude)
val osmLon = clipLon(stationPos.longitude)
emit(GeoPos(osmLat, osmLon))
} }
private val _track = MutableSharedFlow<List<List<GeoPos>>>() private fun handleAction(action: MapAction) {
val track: SharedFlow<List<List<GeoPos>>> = _track when (action) {
MapAction.SelectPrev -> scrollSelection(true)
MapAction.SelectNext -> scrollSelection(false)
is MapAction.SelectItem -> selectSatellite(action.item)
is MapAction.SelectDefaultItem -> selectDefaultSatellite(action.catnum)
}
}
private val _footprint = MutableSharedFlow<OrbitalPos>() private fun getStationPosition() {
val footprint: SharedFlow<OrbitalPos> = _footprint val osmLat = clipLat(stationPos.latitude)
val osmLon = clipLon(stationPos.longitude)
_uiState.update { it.copy(stationPosition = GeoPos(osmLat, osmLon)) }
}
private val _mapData = MutableSharedFlow<MapData>() private fun selectDefaultSatellite(catnum: Int) {
// val mapData: SharedFlow<MapData> = _mapData
private val _positions = MutableSharedFlow<Map<OrbitalObject, GeoPos>>()
val positions: SharedFlow<Map<OrbitalObject, GeoPos>> = _positions
// fun scrollSelection(decrement: Boolean) {
// if (allSatellites.isNotEmpty()) {
// val index = allSatellites.indexOf(selectedSatellite)
// if (decrement) {
// if (index > 0) selectSatellite(allSatellites[index - 1])
// else selectSatellite(allSatellites[allSatellites.size - 1])
// } else {
// if (index < allSatellites.size - 1) selectSatellite(allSatellites[index + 1])
// else selectSatellite(allSatellites[0])
// }
// }
// }
fun selectDefaultSatellite(catnum: Int) {
if (allSatellites.isNotEmpty()) { if (allSatellites.isNotEmpty()) {
if (catnum == -1) { if (catnum == -1) {
allPasses.find { pass -> pass.progress < 100 && !pass.isDeepSpace } allPasses.find { pass -> pass.progress < 100 && !pass.isDeepSpace }
@@ -97,12 +98,26 @@ class MapViewModel(private val satelliteRepo: ISatelliteRepo, settingsRepo: ISet
} }
} }
fun selectSatellite(orbitalObject: OrbitalObject, updateFreq: Long = dataUpdateRate) { private fun scrollSelection(decrement: Boolean) {
if (allSatellites.isNotEmpty()) {
val index = allSatellites.indexOf(selectedOrbitalObject)
if (decrement) {
if (index > 0) selectSatellite(allSatellites[index - 1])
else selectSatellite(allSatellites[allSatellites.size - 1])
} else {
if (index < allSatellites.size - 1) selectSatellite(allSatellites[index + 1])
else selectSatellite(allSatellites[0])
}
}
}
private fun selectSatellite(orbitalObject: OrbitalObject, updateFreq: Long = dataUpdateRate) {
selectedOrbitalObject = orbitalObject selectedOrbitalObject = orbitalObject
viewModelScope.launch { viewModelScope.launch {
dataUpdateJob?.cancelAndJoin() dataUpdateJob?.cancelAndJoin()
dataUpdateJob = launch { dataUpdateJob = launch {
val dateNow = Date() val dateNow = Date()
getStationPosition()
getSatTrack(orbitalObject, stationPos, dateNow) getSatTrack(orbitalObject, stationPos, dateNow)
while (isActive) { while (isActive) {
dateNow.time = System.currentTimeMillis() dateNow.time = System.currentTimeMillis()
@@ -141,7 +156,7 @@ class MapViewModel(private val satelliteRepo: ISatelliteRepo, settingsRepo: ISet
currentTrack.add(currentPosition) currentTrack.add(currentPosition)
} }
satTracks.add(currentTrack) satTracks.add(currentTrack)
_track.emit(satTracks) _uiState.update { it.copy(track = satTracks) }
} }
private suspend fun getPositions(orbitalObjects: List<OrbitalObject>, pos: GeoPos, date: Date) { private suspend fun getPositions(orbitalObjects: List<OrbitalObject>, pos: GeoPos, date: Date) {
@@ -152,24 +167,29 @@ class MapViewModel(private val satelliteRepo: ISatelliteRepo, settingsRepo: ISet
val osmLon = clipLon(satPos.longitude.toDegrees()) val osmLon = clipLon(satPos.longitude.toDegrees())
positions[satellite] = GeoPos(osmLat, osmLon) positions[satellite] = GeoPos(osmLat, osmLon)
} }
_positions.emit(positions) _uiState.update { it.copy(positions = positions) }
} }
private suspend fun getSatFootprint(orbitalObject: OrbitalObject, pos: GeoPos, date: Date) { private suspend fun getSatFootprint(orbitalObject: OrbitalObject, pos: GeoPos, date: Date) {
val satPos = satelliteRepo.getPosition(orbitalObject, pos, date.time) val satPos = satelliteRepo.getPosition(orbitalObject, pos, date.time)
_footprint.emit(satPos) _uiState.update { it.copy(footprint = satPos) }
} }
private suspend fun getSatData(sat: OrbitalObject, pos: GeoPos, date: Date) { private suspend fun getSatData(sat: OrbitalObject, pos: GeoPos, date: Date) {
var orbitalPass = defaultPass
var aosTime = 0L.toTimerString() var aosTime = 0L.toTimerString()
var isTimeAos = true
allPasses.find { pass -> pass.catNum == sat.data.catnum && pass.progress < 100 } allPasses.find { pass -> pass.catNum == sat.data.catnum && pass.progress < 100 }
?.let { satPass -> ?.let { satPass ->
orbitalPass = satPass
if (!satPass.isDeepSpace) { if (!satPass.isDeepSpace) {
aosTime = if (date.time < satPass.aosTime) { aosTime = if (date.time < satPass.aosTime) {
val millisBeforeStart = satPass.aosTime.minus(date.time) val millisBeforeStart = satPass.aosTime.minus(date.time)
isTimeAos = true
millisBeforeStart.toTimerString() millisBeforeStart.toTimerString()
} else { } else {
val millisBeforeEnd = satPass.losTime.minus(date.time) val millisBeforeEnd = satPass.losTime.minus(date.time)
isTimeAos = false
millisBeforeEnd.toTimerString() millisBeforeEnd.toTimerString()
} }
} }
@@ -188,6 +208,7 @@ class MapViewModel(private val satelliteRepo: ISatelliteRepo, settingsRepo: ISet
sat.data.catnum, sat.data.catnum,
sat.data.name, sat.data.name,
aosTime, aosTime,
isTimeAos,
azimuth, azimuth,
elevation, elevation,
satPos.distance, satPos.distance,
@@ -199,7 +220,7 @@ class MapViewModel(private val satelliteRepo: ISatelliteRepo, settingsRepo: ISet
phase, phase,
visibility visibility
) )
_mapData.emit(satData) _uiState.update { it.copy(mapData = satData, orbitalPass = orbitalPass) }
} }
companion object { companion object {
@@ -4,6 +4,7 @@ import androidx.compose.foundation.MarqueeSpacing
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.basicMarquee import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
@@ -38,6 +39,7 @@ import androidx.navigation.compose.composable
import androidx.navigation.navArgument import androidx.navigation.navArgument
import com.rtbishop.look4sat.R import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.domain.model.SatRadio import com.rtbishop.look4sat.domain.model.SatRadio
import com.rtbishop.look4sat.domain.utility.toDegrees
import com.rtbishop.look4sat.presentation.MainTheme import com.rtbishop.look4sat.presentation.MainTheme
import com.rtbishop.look4sat.presentation.Screen import com.rtbishop.look4sat.presentation.Screen
import com.rtbishop.look4sat.presentation.components.CardIcon import com.rtbishop.look4sat.presentation.components.CardIcon
@@ -78,15 +80,53 @@ private fun RadarScreen(uiState: RadarState, navigateBack: () -> Unit) {
CardIcon(onClick = addToCalendar, iconId = R.drawable.ic_calendar) CardIcon(onClick = addToCalendar, iconId = R.drawable.ic_calendar)
} }
NextPassRow(pass = uiState.currentPass ?: getDefaultPass()) NextPassRow(pass = uiState.currentPass ?: getDefaultPass())
ElevatedCard(modifier = Modifier.aspectRatio(1f)) { Box(contentAlignment = Alignment.Center, modifier = Modifier.aspectRatio(1f)) {
uiState.orbitalPos?.let { item -> uiState.orbitalPos?.let { position ->
RadarViewCompose( ElevatedCard {
item = item, RadarViewCompose(
items = uiState.satTrack, item = position,
azimElev = uiState.orientationValues, items = uiState.satTrack,
shouldShowSweep = uiState.shouldShowSweep, azimElev = uiState.orientationValues,
shouldUseCompass = uiState.shouldUseCompass shouldShowSweep = uiState.shouldShowSweep,
) shouldUseCompass = uiState.shouldUseCompass
)
}
Column(
verticalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxSize()
.padding(horizontal = 6.dp, vertical = 4.dp)
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth()
) {
RadarTextTop(
position.azimuth,
stringResource(R.string.radar_az_text),
true
)
RadarTextTop(
position.elevation,
stringResource(R.string.radar_el_text),
false
)
}
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth()
) {
RadarTextBottom(
position.altitude,
stringResource(R.string.radar_alt_text),
true
)
RadarTextBottom(
position.distance,
stringResource(R.string.radar_dist_text),
false
)
}
}
} }
} }
ElevatedCard(modifier = Modifier.fillMaxSize()) { ElevatedCard(modifier = Modifier.fillMaxSize()) {
@@ -96,6 +136,26 @@ private fun RadarScreen(uiState: RadarState, navigateBack: () -> Unit) {
} }
} }
@Composable
private fun RadarTextTop(value: Double, text: String, isLeft: Boolean) {
val alignment = if (isLeft) Alignment.Start else Alignment.End
val degValue = stringResource(R.string.radar_az_value, value.toDegrees())
Column(horizontalAlignment = alignment) {
Text(text = degValue, fontSize = 18.sp)
Text(text = text, fontSize = 15.sp)
}
}
@Composable
private fun RadarTextBottom(value: Double, text: String, isLeft: Boolean) {
val alignment = if (isLeft) Alignment.Start else Alignment.End
val degValue = stringResource(R.string.radar_alt_value, value)
Column(horizontalAlignment = alignment) {
Text(text = text, fontSize = 15.sp)
Text(text = degValue, fontSize = 18.sp)
}
}
@Composable @Composable
private fun TransmittersList(transmitters: List<SatRadio>) { private fun TransmittersList(transmitters: List<SatRadio>) {
LazyColumn(modifier = Modifier.fillMaxSize()) { LazyColumn(modifier = Modifier.fillMaxSize()) {
@@ -120,19 +180,19 @@ private fun TransmitterItem(radio: SatRadio) {
Surface(color = MaterialTheme.colorScheme.background) { Surface(color = MaterialTheme.colorScheme.background) {
Surface(modifier = Modifier.padding(bottom = 2.dp)) { Surface(modifier = Modifier.padding(bottom = 2.dp)) {
Column( Column(
verticalArrangement = Arrangement.spacedBy(2.dp), verticalArrangement = Arrangement.spacedBy(4.dp),
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colorScheme.surface) .background(MaterialTheme.colorScheme.surface)
.padding(6.dp) .padding(horizontal = 6.dp, vertical = 8.dp)
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Icon( Icon(
painter = painterResource(id = R.drawable.ic_back), painter = painterResource(id = R.drawable.ic_arrow),
tint = Color.Green, tint = Color.Green,
contentDescription = null, modifier = Modifier.rotate(-90f) contentDescription = null, modifier = Modifier.rotate(90f).weight(0.15f)
) )
Text( Text(
text = if (radio.isInverted) "INVERTED: ${radio.info} " else "${radio.info} ", text = if (radio.isInverted) "INVERTED: ${radio.info} " else "${radio.info} ",
@@ -140,14 +200,14 @@ private fun TransmitterItem(radio: SatRadio) {
modifier = Modifier modifier = Modifier
.basicMarquee( .basicMarquee(
iterations = Int.MAX_VALUE, iterations = Int.MAX_VALUE,
spacing = MarqueeSpacing(0.dp) spacing = MarqueeSpacing(16.dp)
) )
.weight(1f) .weight(0.7f)
) )
Icon( Icon(
painter = painterResource(id = R.drawable.ic_back), painter = painterResource(id = R.drawable.ic_arrow),
tint = Color.Red, tint = Color.Red,
contentDescription = null, modifier = Modifier.rotate(90f) contentDescription = null, modifier = Modifier.rotate(-90f).weight(0.15f)
) )
} }
FrequencyRow(satRadio = radio) FrequencyRow(satRadio = radio)
@@ -185,7 +245,6 @@ private fun RowScope.ModeText(mode: String?) {
Text( Text(
text = mode ?: "- - : - -", text = mode ?: "- - : - -",
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
fontSize = 15.sp,
modifier = Modifier.weight(0.15f) modifier = Modifier.weight(0.15f)
) )
} }
@@ -203,53 +262,3 @@ private fun FrequencyText(frequency: Long?) {
color = MaterialTheme.colorScheme.primary color = MaterialTheme.colorScheme.primary
) )
} }
//private val divider = 1000000f
//radioDownlink.text = String.format(Locale.ENGLISH, link, downlink / divider)
//radioUplink.text = String.format(Locale.ENGLISH, link, uplink / divider)
//private fun setupObservers() {
// viewModel.getPass(45000, System.currentTimeMillis()).observe(viewLifecycleOwner) { pass ->
// binding?.run {
// radarView = RadarView(requireContext()).apply {
// setShowAim(viewModel.getUseCompass())
// setScanning(viewModel.getShowSweep())
// }
// viewModel.radarData.observe(viewLifecycleOwner) { passData ->
// setPassText(pass, passData.satPos)
// }
// }
// }
//}
//
//private fun setPassText(satPass: SatPass, satPos: SatPos) {
// binding?.run {
// val timeNow = System.currentTimeMillis()
// val radarAzim = getString(R.string.radar_az_value)
// val radarElev = getString(R.string.radar_el_value)
// val radarAlt = getString(R.string.radar_alt_value)
// val radarDist = getString(R.string.radar_dist_value)
// radarAzValue.text = String.format(radarAzim, satPos.azimuth.toDegrees())
// radarElValue.text = String.format(radarElev, satPos.elevation.toDegrees())
// radarAltValue.text = String.format(radarAlt, satPos.altitude)
// radarDstValue.text = String.format(radarDist, satPos.distance)
// if (satPos.eclipsed) {
// radarVisibility.text = getText(R.string.radar_eclipsed)
// } else {
// radarVisibility.text = getText(R.string.radar_visible)
// }
// if (!satPass.isDeepSpace) {
// if (timeNow < satPass.aosTime) {
// val millisBeforeStart = satPass.aosTime.minus(timeNow)
// radarTimer.text = millisBeforeStart.toTimerString()
// } else {
// val millisBeforeEnd = satPass.losTime.minus(timeNow)
// radarTimer.text = millisBeforeEnd.toTimerString()
// if (timeNow > satPass.losTime) {
// radarTimer.text = 0L.toTimerString()
//// findNavController().navigateUp()
// }
// }
// } else radarTimer.text = 0L.toTimerString()
// }
//}
@@ -195,6 +195,7 @@ private fun TypeCard(types: List<String>, onClick: () -> Unit, modifier: Modifie
fontSize = 16.sp, fontSize = 16.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
modifier = Modifier modifier = Modifier
.weight(1f)
.basicMarquee(iterations = Int.MAX_VALUE, spacing = MarqueeSpacing(16.dp)) .basicMarquee(iterations = Int.MAX_VALUE, spacing = MarqueeSpacing(16.dp))
) )
} }