mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Added compose pull to refresh for passes list
This commit is contained in:
1 parent
1ea4da3baf
commit
a08cfc7fb8
11 files changed
+155
-42
No files matched your search
@@ -89,6 +89,7 @@ dependencies {
|
|||||||
implementation "androidx.activity:activity-compose:$activity_compose_version"
|
implementation "androidx.activity:activity-compose:$activity_compose_version"
|
||||||
implementation "androidx.compose.animation:animation:$compose_version"
|
implementation "androidx.compose.animation:animation:$compose_version"
|
||||||
implementation "androidx.compose.compiler:compiler:$compose_compiler_version"
|
implementation "androidx.compose.compiler:compiler:$compose_compiler_version"
|
||||||
|
implementation "androidx.compose.material:material:$material_version"
|
||||||
implementation "androidx.compose.material3:material3:$material3_version"
|
implementation "androidx.compose.material3:material3:$material3_version"
|
||||||
implementation "androidx.compose.runtime:runtime:$compose_version"
|
implementation "androidx.compose.runtime:runtime:$compose_version"
|
||||||
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
|
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
|
||||||
|
|||||||
@@ -11,17 +11,16 @@ import androidx.compose.foundation.clickable
|
|||||||
import androidx.compose.foundation.interaction.Interaction
|
import androidx.compose.foundation.interaction.Interaction
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.material3.ElevatedButton
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.composed
|
import androidx.compose.ui.composed
|
||||||
import androidx.compose.ui.draw.scale
|
import androidx.compose.ui.draw.scale
|
||||||
@@ -40,6 +39,13 @@ fun CardButton(onClick: () -> Unit, text: String, modifier: Modifier = Modifier)
|
|||||||
) { Text(text = text, fontSize = 17.sp) }
|
) { Text(text = text, fontSize = 17.sp) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CardLoadingIndicator() {
|
||||||
|
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) {
|
||||||
|
CircularProgressIndicator(modifier = Modifier.size(80.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RadarPing() {
|
fun RadarPing() {
|
||||||
val pingColor = MaterialTheme.colorScheme.primary
|
val pingColor = MaterialTheme.colorScheme.primary
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||||||
import com.rtbishop.look4sat.R
|
import com.rtbishop.look4sat.R
|
||||||
import com.rtbishop.look4sat.domain.model.DataState
|
import com.rtbishop.look4sat.domain.model.DataState
|
||||||
import com.rtbishop.look4sat.domain.model.SatItem
|
import com.rtbishop.look4sat.domain.model.SatItem
|
||||||
|
import com.rtbishop.look4sat.presentation.CardLoadingIndicator
|
||||||
import com.rtbishop.look4sat.presentation.MainTheme
|
import com.rtbishop.look4sat.presentation.MainTheme
|
||||||
import com.rtbishop.look4sat.presentation.onClick
|
import com.rtbishop.look4sat.presentation.onClick
|
||||||
import com.rtbishop.look4sat.presentation.passesScreen.PassesViewModel
|
import com.rtbishop.look4sat.presentation.passesScreen.PassesViewModel
|
||||||
@@ -229,11 +230,7 @@ fun EntriesCard(state: DataState<List<SatItem>>, onSelected: (List<Int>, Boolean
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> CardLoadingIndicator()
|
||||||
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) {
|
|
||||||
CircularProgressIndicator(modifier = Modifier.size(80.dp))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@file:OptIn(ExperimentalMaterialApi::class)
|
||||||
|
|
||||||
package com.rtbishop.look4sat.presentation.passesScreen
|
package com.rtbishop.look4sat.presentation.passesScreen
|
||||||
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
@@ -5,6 +7,11 @@ import androidx.compose.foundation.background
|
|||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
|
import androidx.compose.material.pullrefresh.PullRefreshIndicator
|
||||||
|
import androidx.compose.material.pullrefresh.PullRefreshState
|
||||||
|
import androidx.compose.material.pullrefresh.pullRefresh
|
||||||
|
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
|
||||||
@@ -16,7 +23,7 @@ import androidx.compose.ui.text.font.FontWeight
|
|||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.*
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import com.rtbishop.look4sat.R
|
import com.rtbishop.look4sat.R
|
||||||
import com.rtbishop.look4sat.domain.model.DataState
|
import com.rtbishop.look4sat.domain.model.DataState
|
||||||
@@ -29,11 +36,52 @@ import java.util.*
|
|||||||
|
|
||||||
private val sdf = SimpleDateFormat("HH:mm:ss", Locale.ENGLISH)
|
private val sdf = SimpleDateFormat("HH:mm:ss", Locale.ENGLISH)
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun PassesScreen(viewModel: PassesViewModel = hiltViewModel()) {
|
fun PassesScreen(viewModel: PassesViewModel = hiltViewModel()) {
|
||||||
val state = viewModel.passes.observeAsState(DataState.Loading)
|
val state = viewModel.passes.observeAsState()
|
||||||
|
val timerText = viewModel.timerText.observeAsState()
|
||||||
|
val isRefreshing = state.value is DataState.Loading
|
||||||
|
val refreshState = rememberPullRefreshState(
|
||||||
|
refreshing = isRefreshing,
|
||||||
|
onRefresh = { viewModel.calculatePasses() })
|
||||||
|
|
||||||
|
val value = state.value
|
||||||
|
var passes = emptyList<SatPass>()
|
||||||
|
if (value is DataState.Success) passes = value.data
|
||||||
|
|
||||||
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||||
PassesCard(state = state.value)
|
ElevatedCard(modifier = Modifier.height(52.dp)) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
modifier = Modifier.fillMaxSize()
|
||||||
|
) {
|
||||||
|
IconButton(onClick = {}) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.ic_filter),
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.SpaceEvenly, modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text(text = timerText.value?.first ?: "Null")
|
||||||
|
Text(text = timerText.value?.second ?: "Null")
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = timerText.value?.third ?: "00:00:00",
|
||||||
|
fontSize = 36.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = MaterialTheme.colorScheme.primary,
|
||||||
|
textAlign = TextAlign.End,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.padding(bottom = 2.dp, end = 8.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PassesCard(refreshState, isRefreshing, passes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +99,7 @@ private fun PassPreview() {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun Pass(pass: SatPass, modifier: Modifier = Modifier) {
|
private fun Pass(pass: SatPass, modifier: Modifier = Modifier) {
|
||||||
Surface(color = MaterialTheme.colorScheme.background, modifier = modifier) {
|
Surface(color = MaterialTheme.colorScheme.background, modifier = modifier) {
|
||||||
Surface(modifier = Modifier.padding(bottom = 1.dp)) {
|
Surface(modifier = Modifier.padding(bottom = 2.dp)) {
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -61,7 +109,7 @@ private fun Pass(pass: SatPass, modifier: Modifier = Modifier) {
|
|||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text(
|
Text(
|
||||||
text = "Id:${pass.catNum} - ",
|
text = "Id:${pass.catNum} - ",
|
||||||
modifier = Modifier.width(90.dp),
|
modifier = Modifier.width(82.dp),
|
||||||
textAlign = TextAlign.End,
|
textAlign = TextAlign.End,
|
||||||
color = MaterialTheme.colorScheme.primary
|
color = MaterialTheme.colorScheme.primary
|
||||||
)
|
)
|
||||||
@@ -91,13 +139,20 @@ private fun Pass(pass: SatPass, modifier: Modifier = Modifier) {
|
|||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(id = R.string.pass_aosAz, pass.aosAzimuth))
|
Text(
|
||||||
|
text = stringResource(id = R.string.pass_aosAz, pass.aosAzimuth),
|
||||||
|
fontSize = 15.sp
|
||||||
|
)
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(id = R.string.pass_altitude, pass.altitude),
|
text = stringResource(id = R.string.pass_altitude, pass.altitude),
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
|
fontSize = 15.sp,
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
Text(text = stringResource(id = R.string.pass_losAz, pass.losAzimuth))
|
Text(
|
||||||
|
text = stringResource(id = R.string.pass_losAz, pass.losAzimuth),
|
||||||
|
fontSize = 15.sp
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
@@ -105,14 +160,22 @@ private fun Pass(pass: SatPass, modifier: Modifier = Modifier) {
|
|||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
val deepTime = stringResource(id = R.string.pass_placeholder)
|
val deepTime = stringResource(id = R.string.pass_placeholder)
|
||||||
Text(text = if (pass.isDeepSpace) deepTime else sdf.format(Date(pass.aosTime)))
|
Text(
|
||||||
|
text = if (pass.isDeepSpace) deepTime else sdf.format(Date(pass.aosTime)),
|
||||||
|
fontSize = 15.sp
|
||||||
|
)
|
||||||
LinearProgressIndicator(
|
LinearProgressIndicator(
|
||||||
progress = pass.progress,
|
progress = if (pass.isDeepSpace) 1f else pass.progress,
|
||||||
modifier = modifier.weight(1f),
|
modifier = modifier
|
||||||
|
.fillMaxWidth(0.75f)
|
||||||
|
.padding(top = 3.dp),
|
||||||
color = MaterialTheme.colorScheme.primary,
|
color = MaterialTheme.colorScheme.primary,
|
||||||
trackColor = MaterialTheme.colorScheme.inverseSurface
|
trackColor = MaterialTheme.colorScheme.inverseSurface
|
||||||
)
|
)
|
||||||
Text(text = if (pass.isDeepSpace) deepTime else sdf.format(Date(pass.losTime)))
|
Text(
|
||||||
|
text = if (pass.isDeepSpace) deepTime else sdf.format(Date(pass.losTime)),
|
||||||
|
fontSize = 15.sp
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,23 +184,22 @@ private fun Pass(pass: SatPass, modifier: Modifier = Modifier) {
|
|||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun PassesCard(state: DataState<List<SatPass>>) {
|
private fun PassesCard(
|
||||||
|
refreshState: PullRefreshState, isRefreshing: Boolean, passes: List<SatPass>
|
||||||
|
) {
|
||||||
ElevatedCard(modifier = Modifier.fillMaxSize()) {
|
ElevatedCard(modifier = Modifier.fillMaxSize()) {
|
||||||
when (state) {
|
Box(Modifier.pullRefresh(refreshState)) {
|
||||||
is DataState.Success -> {
|
LazyColumn(modifier = Modifier.fillMaxSize()) {
|
||||||
LazyColumn {
|
items(items = passes, key = { item -> item.catNum + item.aosTime }) { pass ->
|
||||||
items(
|
|
||||||
items = state.data,
|
|
||||||
key = { item -> item.catNum + item.aosTime }) { pass ->
|
|
||||||
Pass(pass, Modifier.animateItemPlacement())
|
Pass(pass, Modifier.animateItemPlacement())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
PullRefreshIndicator(
|
||||||
else -> {
|
refreshing = isRefreshing,
|
||||||
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) {
|
state = refreshState,
|
||||||
CircularProgressIndicator(modifier = Modifier.size(80.dp))
|
modifier = Modifier.align(Alignment.TopCenter),
|
||||||
}
|
backgroundColor = MaterialTheme.colorScheme.primary
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+31
-5
@@ -23,6 +23,7 @@ import com.rtbishop.look4sat.domain.ISatelliteManager
|
|||||||
import com.rtbishop.look4sat.domain.ISettingsManager
|
import com.rtbishop.look4sat.domain.ISettingsManager
|
||||||
import com.rtbishop.look4sat.domain.model.DataState
|
import com.rtbishop.look4sat.domain.model.DataState
|
||||||
import com.rtbishop.look4sat.domain.predict.SatPass
|
import com.rtbishop.look4sat.domain.predict.SatPass
|
||||||
|
import com.rtbishop.look4sat.utility.toTimerString
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -34,10 +35,13 @@ class PassesViewModel @Inject constructor(
|
|||||||
private val settings: ISettingsManager
|
private val settings: ISettingsManager
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
|
private val _passes = MutableLiveData<DataState<List<SatPass>>>()
|
||||||
|
private val timerData = Triple("Next - Id:Null", "Name: Null", "00:00:00")
|
||||||
|
private val _timerText = MutableLiveData<Triple<String, String, String>>()
|
||||||
private var passesProcessing: Job? = null
|
private var passesProcessing: Job? = null
|
||||||
private val _passes = MutableLiveData<DataState<List<SatPass>>>(DataState.Loading)
|
|
||||||
val passes: LiveData<DataState<List<SatPass>>> = _passes
|
|
||||||
val entriesTotal: LiveData<Int> = repository.getEntriesTotal().asLiveData()
|
val entriesTotal: LiveData<Int> = repository.getEntriesTotal().asLiveData()
|
||||||
|
val passes: LiveData<DataState<List<SatPass>>> = _passes
|
||||||
|
val timerText: LiveData<Triple<String, String, String>> = _timerText
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
@@ -45,8 +49,27 @@ class PassesViewModel @Inject constructor(
|
|||||||
passesProcessing?.cancelAndJoin()
|
passesProcessing?.cancelAndJoin()
|
||||||
passesProcessing = viewModelScope.launch {
|
passesProcessing = viewModelScope.launch {
|
||||||
while (isActive) {
|
while (isActive) {
|
||||||
val time = System.currentTimeMillis()
|
val timeNow = System.currentTimeMillis()
|
||||||
val newPasses = satelliteManager.processPasses(passes, time)
|
val newPasses = satelliteManager.processPasses(passes, timeNow)
|
||||||
|
|
||||||
|
if (newPasses.isNotEmpty()) {
|
||||||
|
try {
|
||||||
|
val nextPass = newPasses.first { it.aosTime.minus(timeNow) > 0 }
|
||||||
|
val catNum = nextPass.catNum
|
||||||
|
val name = nextPass.name
|
||||||
|
val millisBeforeStart = nextPass.aosTime.minus(timeNow)
|
||||||
|
val timerString = millisBeforeStart.toTimerString()
|
||||||
|
_timerText.postValue(Triple("Next - Id:$catNum", name, timerString))
|
||||||
|
} catch (e: NoSuchElementException) {
|
||||||
|
val lastPass = newPasses.last()
|
||||||
|
val catNum = lastPass.catNum
|
||||||
|
val name = lastPass.name
|
||||||
|
val millisBeforeEnd = lastPass.losTime.minus(timeNow)
|
||||||
|
val timerString = millisBeforeEnd.toTimerString()
|
||||||
|
_timerText.postValue(Triple("Next - Id:$catNum", name, timerString))
|
||||||
|
}
|
||||||
|
} else _timerText.postValue(timerData)
|
||||||
|
|
||||||
_passes.postValue(DataState.Success(newPasses))
|
_passes.postValue(DataState.Success(newPasses))
|
||||||
delay(1000)
|
delay(1000)
|
||||||
}
|
}
|
||||||
@@ -71,6 +94,7 @@ class PassesViewModel @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
_passes.postValue(DataState.Loading)
|
_passes.postValue(DataState.Loading)
|
||||||
|
// _timerText.postValue(timerDefaultText)
|
||||||
passesProcessing?.cancelAndJoin()
|
passesProcessing?.cancelAndJoin()
|
||||||
selection?.let { items -> settings.saveEntriesSelection(items) }
|
selection?.let { items -> settings.saveEntriesSelection(items) }
|
||||||
settings.setHoursAhead(hoursAhead)
|
settings.setHoursAhead(hoursAhead)
|
||||||
@@ -78,7 +102,9 @@ class PassesViewModel @Inject constructor(
|
|||||||
val stationPos = settings.loadStationPosition()
|
val stationPos = settings.loadStationPosition()
|
||||||
val selectedIds = settings.loadEntriesSelection()
|
val selectedIds = settings.loadEntriesSelection()
|
||||||
val satellites = repository.getEntriesWithIds(selectedIds)
|
val satellites = repository.getEntriesWithIds(selectedIds)
|
||||||
satelliteManager.calculatePasses(satellites, stationPos, timeRef, hoursAhead, minElevation)
|
satelliteManager.calculatePasses(
|
||||||
|
satellites, stationPos, timeRef, hoursAhead, minElevation
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="#000000"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z" />
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="#000000"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M4.25,5.61C6.27,8.2 10,13 10,13v6c0,0.55 0.45,1 1,1h2c0.55,0 1,-0.45 1,-1v-6c0,0 3.72,-4.8 5.74,-7.39C20.25,4.95 19.78,4 18.95,4H5.04C4.21,4 3.74,4.95 4.25,5.61z" />
|
||||||
|
</vector>
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
<string name="pass_elevation">Элевация: %.1f°</string>
|
<string name="pass_elevation">Элевация: %.1f°</string>
|
||||||
<string name="pass_losAz">%.1f° - КПС</string>
|
<string name="pass_losAz">%.1f° - КПС</string>
|
||||||
<string name="pass_altitude">Высота: %d км</string>
|
<string name="pass_altitude">Высота: %d км</string>
|
||||||
<string name="pass_placeholder"> - - : - - </string>
|
<string name="pass_placeholder"> -- : -- : -- </string>
|
||||||
<string name="pass_startTime">HH:mm:ss - EEE</string>
|
<string name="pass_startTime">HH:mm:ss - EEE</string>
|
||||||
<string name="pass_endTime">EEE - HH:mm:ss</string>
|
<string name="pass_endTime">EEE - HH:mm:ss</string>
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@
|
|||||||
<string name="pass_elevation">仰角:%.1f°</string>
|
<string name="pass_elevation">仰角:%.1f°</string>
|
||||||
<string name="pass_losAz">%.1f° - 出境</string>
|
<string name="pass_losAz">%.1f° - 出境</string>
|
||||||
<string name="pass_altitude">高度:%d km</string>
|
<string name="pass_altitude">高度:%d km</string>
|
||||||
<string name="pass_placeholder">" - - : - - "</string>
|
<string name="pass_placeholder"> -- : -- : -- </string>
|
||||||
<string name="pass_startTime">HH:mm:ss - EEE</string>
|
<string name="pass_startTime">HH:mm:ss - EEE</string>
|
||||||
<string name="pass_endTime">EEE - HH:mm:ss</string>
|
<string name="pass_endTime">EEE - HH:mm:ss</string>
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@
|
|||||||
<string name="pass_elevation">Elevation: %.1f°</string>
|
<string name="pass_elevation">Elevation: %.1f°</string>
|
||||||
<string name="pass_losAz">%.1f° - LOS</string>
|
<string name="pass_losAz">%.1f° - LOS</string>
|
||||||
<string name="pass_altitude">Altitude: %d km</string>
|
<string name="pass_altitude">Altitude: %d km</string>
|
||||||
<string name="pass_placeholder"> - - : - - </string>
|
<string name="pass_placeholder"> -- : -- : -- </string>
|
||||||
<string name="pass_startTime">HH:mm:ss - EEE</string>
|
<string name="pass_startTime">HH:mm:ss - EEE</string>
|
||||||
<string name="pass_endTime">EEE - HH:mm:ss</string>
|
<string name="pass_endTime">EEE - HH:mm:ss</string>
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -16,8 +16,9 @@ buildscript {
|
|||||||
osmdroid_version = '6.1.14'
|
osmdroid_version = '6.1.14'
|
||||||
json_version = '20220924'
|
json_version = '20220924'
|
||||||
compose_version = '1.3.3'
|
compose_version = '1.3.3'
|
||||||
compose_compiler_version = '1.4.2'
|
compose_compiler_version = '1.4.3'
|
||||||
activity_compose_version = '1.6.1'
|
activity_compose_version = '1.6.1'
|
||||||
|
material_version = '1.3.1'
|
||||||
material3_version = '1.0.1'
|
material3_version = '1.0.1'
|
||||||
leakcanary_version = '2.10'
|
leakcanary_version = '2.10'
|
||||||
junit_version = '4.13.2'
|
junit_version = '4.13.2'
|
||||||
|
|||||||
Reference in new issue
Block a user