kopia lustrzana https://github.com/rt-bishop/Look4Sat
Set up more screens with portrait/landscape TopBar
rodzic
761506d2a3
commit
99a63a2a1d
|
@ -1,94 +1,75 @@
|
|||
package com.rtbishop.look4sat.presentation
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.NavigationBar
|
||||
import androidx.compose.material3.NavigationBarItem
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteDefaults
|
||||
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold
|
||||
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteType
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.presentation.common.isVerticalLayout
|
||||
import com.rtbishop.look4sat.presentation.map.mapDestination
|
||||
import com.rtbishop.look4sat.presentation.passes.passesDestination
|
||||
import com.rtbishop.look4sat.presentation.radar.radarDestination
|
||||
import com.rtbishop.look4sat.presentation.satellites.satellitesDestination
|
||||
import com.rtbishop.look4sat.presentation.settings.settingsDestination
|
||||
|
||||
sealed class Screen(var title: String, var icon: Int, var route: String) {
|
||||
data object Main : Screen("Main", R.drawable.ic_sputnik, "main")
|
||||
data object Radar : Screen("Radar", R.drawable.ic_sputnik, "radar")
|
||||
sealed class Screen(val title: String, val icon: Int, val route: String) {
|
||||
data object Satellites : Screen("Satellites", R.drawable.ic_sputnik, "satellites")
|
||||
data object Passes : Screen("Passes", R.drawable.ic_passes, "passes")
|
||||
data object Radar : Screen("Radar", R.drawable.ic_satellite, "radar")
|
||||
data object Map : Screen("Map", R.drawable.ic_map, "map")
|
||||
data object Settings : Screen("Settings", R.drawable.ic_settings, "settings")
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MainScreen() {
|
||||
val outerNavController: NavHostController = rememberNavController()
|
||||
val navigateToRadar = { catNum: Int, aosTime: Long ->
|
||||
val routeWithParams = "${Screen.Radar.route}?catNum=${catNum}&aosTime=${aosTime}"
|
||||
outerNavController.navigate(routeWithParams)
|
||||
}
|
||||
NavHost(navController = outerNavController, startDestination = Screen.Main.route) {
|
||||
mainDestination(navigateToRadar)
|
||||
radarDestination { outerNavController.navigateUp() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun NavGraphBuilder.mainDestination(navigateToRadar: (Int, Long) -> Unit) {
|
||||
composable(Screen.Main.route) { NavBarScreen(navigateToRadar) }
|
||||
}
|
||||
private val startDestination = Screen.Passes.route
|
||||
|
||||
@Composable
|
||||
private fun NavBarScreen(navigateToRadar: (Int, Long) -> Unit) {
|
||||
val innerNavController: NavHostController = rememberNavController()
|
||||
val navigateToPasses = { innerNavController.navigate(Screen.Passes.route) }
|
||||
Scaffold(bottomBar = { MainNavBar(innerNavController) }) { innerPadding ->
|
||||
NavHost(
|
||||
navController = innerNavController,
|
||||
startDestination = Screen.Passes.route,
|
||||
modifier = Modifier.padding(innerPadding)
|
||||
) {
|
||||
satellitesDestination(navigateToPasses)
|
||||
passesDestination(navigateToRadar)
|
||||
mapDestination()
|
||||
settingsDestination()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MainNavBar(navController: NavController) {
|
||||
val items = listOf(Screen.Satellites, Screen.Passes, Screen.Map, Screen.Settings)
|
||||
fun MainScreen(navController: NavHostController = rememberNavController()) {
|
||||
val items = listOf(Screen.Satellites, Screen.Passes, Screen.Radar, Screen.Map, Screen.Settings)
|
||||
val destinationRoute = navController.currentBackStackEntryAsState().value?.destination?.route
|
||||
NavigationBar {
|
||||
items.forEach { item ->
|
||||
NavigationBarItem(
|
||||
icon = { Icon(painterResource(item.icon), item.title) },
|
||||
label = { Text(item.title) },
|
||||
selected = item.route == destinationRoute,
|
||||
onClick = {
|
||||
if (item.route == destinationRoute) {
|
||||
// reselecting the same tab
|
||||
} else {
|
||||
navController.navigate(item.route) {
|
||||
popUpTo(Screen.Passes.route) { saveState = false }
|
||||
NavigationSuiteScaffold(
|
||||
navigationSuiteItems = {
|
||||
items.forEach {
|
||||
item(
|
||||
icon = { Icon(painterResource(it.icon), it.title) },
|
||||
label = { Text(it.title) },
|
||||
selected = destinationRoute?.contains(it.route) ?: false,
|
||||
onClick = {
|
||||
if (destinationRoute?.contains(it.route) ?: false) return@item
|
||||
navController.navigate(it.route) {
|
||||
popUpTo(startDestination) { saveState = false }
|
||||
launchSingleTop = true
|
||||
restoreState = false
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
}, navigationSuiteColors = NavigationSuiteDefaults.colors(
|
||||
navigationRailContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
||||
), layoutType = when {
|
||||
isVerticalLayout() -> NavigationSuiteType.NavigationBar
|
||||
else -> NavigationSuiteType.NavigationRail
|
||||
}
|
||||
) { MainNavHost(navController) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MainNavHost(navController: NavHostController) {
|
||||
val navigateToRadar = { catNum: Int, aosTime: Long ->
|
||||
val routeWithParams = "${Screen.Radar.route}?catNum=${catNum}&aosTime=${aosTime}"
|
||||
navController.navigate(routeWithParams)
|
||||
}
|
||||
NavHost(navController = navController, startDestination = startDestination) {
|
||||
satellitesDestination { navController.navigateUp() }
|
||||
passesDestination(navigateToRadar)
|
||||
radarDestination { navController.navigateUp() }
|
||||
mapDestination()
|
||||
settingsDestination()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ private val darkScheme = darkColorScheme(
|
|||
// outlineVariant = Color(0xFF121212),
|
||||
scrim = Color(0xFF000000),
|
||||
// surfaceBright = Color(0xFF121212),
|
||||
surfaceContainer = Color(0xFF242424), // navBar background
|
||||
surfaceContainer = Color(0xFF121212), // navBar background
|
||||
// surfaceContainerHigh = Color(0xFF121212),
|
||||
surfaceContainerHighest = Color(0xFF242424), // filled card background
|
||||
surfaceContainerLow = Color(0xFF242424), // elevated card background
|
||||
|
|
|
@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
|
@ -283,3 +284,13 @@ fun isVerticalLayout(): Boolean {
|
|||
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
|
||||
return windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Modifier.layoutPadding(): Modifier {
|
||||
val statusBarMod = this.statusBarsPadding()
|
||||
val spacing = LocalSpacing.current.small
|
||||
return when {
|
||||
isVerticalLayout() -> statusBarMod.padding(horizontal = spacing)
|
||||
else -> statusBarMod.padding(start = 0.dp, top = 0.dp, end = spacing, bottom = spacing)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@ import org.osmdroid.views.overlay.Polyline
|
|||
import androidx.core.graphics.toColorInt
|
||||
import androidx.core.graphics.createBitmap
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import com.rtbishop.look4sat.presentation.common.isVerticalLayout
|
||||
import com.rtbishop.look4sat.presentation.common.layoutPadding
|
||||
|
||||
private val minLat = MapView.getTileSystem().minLatitude
|
||||
private val maxLat = MapView.getTileSystem().maxLatitude
|
||||
|
@ -98,13 +100,22 @@ private fun MapScreen(uiState: State<MapState>, mapView: MapView) {
|
|||
val timeString = uiState.value.mapData?.aosTime ?: "00:00:00"
|
||||
val isTimeAos = uiState.value.mapData?.isTimeAos ?: true
|
||||
val osmInfo = "© OpenStreetMap contributors"
|
||||
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
TopBar {
|
||||
IconCard(onClick = selectPrev, iconId = R.drawable.ic_arrow, modifier = rotateMod)
|
||||
TimerRow(timeString = timeString, isTimeAos = isTimeAos)
|
||||
IconCard(onClick = selectNext, iconId = R.drawable.ic_arrow)
|
||||
Column(modifier = Modifier.layoutPadding(), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
if (isVerticalLayout()) {
|
||||
TopBar {
|
||||
IconCard(onClick = selectPrev, iconId = R.drawable.ic_arrow, modifier = rotateMod)
|
||||
TimerRow(timeString = timeString, isTimeAos = isTimeAos)
|
||||
IconCard(onClick = selectNext, iconId = R.drawable.ic_arrow)
|
||||
}
|
||||
NextPassRow(pass = uiState.value.orbitalPass)
|
||||
} else {
|
||||
TopBar {
|
||||
IconCard(onClick = selectPrev, iconId = R.drawable.ic_arrow, modifier = rotateMod)
|
||||
TimerRow(timeString = timeString, isTimeAos = isTimeAos)
|
||||
NextPassRow(pass = uiState.value.orbitalPass, modifier = Modifier.weight(1f))
|
||||
IconCard(onClick = selectNext, iconId = R.drawable.ic_arrow)
|
||||
}
|
||||
}
|
||||
NextPassRow(pass = uiState.value.orbitalPass)
|
||||
ElevatedCard(modifier = Modifier.weight(1f)) {
|
||||
Box(contentAlignment = Alignment.BottomCenter) {
|
||||
LaunchedEffect(uiState.value.track) {
|
||||
|
|
|
@ -11,8 +11,9 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
|
@ -50,6 +51,7 @@ import com.rtbishop.look4sat.presentation.common.NextPassRow
|
|||
import com.rtbishop.look4sat.presentation.common.TimerRow
|
||||
import com.rtbishop.look4sat.presentation.common.TopBar
|
||||
import com.rtbishop.look4sat.presentation.common.isVerticalLayout
|
||||
import com.rtbishop.look4sat.presentation.common.layoutPadding
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
@ -91,7 +93,7 @@ private fun PassesScreen(uiState: PassesState, navigateToRadar: (Int, Long) -> U
|
|||
uiState.takeAction(PassesAction.DismissWelcome)
|
||||
}
|
||||
}
|
||||
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
Column(modifier = Modifier.layoutPadding(), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
if (isVerticalLayout()) {
|
||||
TopBar {
|
||||
IconCard(onClick = { showPassesDialog() }, iconId = R.drawable.ic_filter)
|
||||
|
@ -135,21 +137,16 @@ private fun PassesList(
|
|||
)
|
||||
}
|
||||
) {
|
||||
LazyColumn(modifier = Modifier.fillMaxSize()) {
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Adaptive(320.dp),
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
items(items = passes, key = { item -> item.catNum + item.aosTime }) { pass ->
|
||||
if (pass.isDeepSpace) {
|
||||
DeepSpacePass(
|
||||
pass = pass,
|
||||
navigateToRadar = navigateToRadar,
|
||||
modifier = Modifier.animateItem()
|
||||
)
|
||||
} else {
|
||||
NearEarthPass(
|
||||
pass = pass,
|
||||
navigateToRadar = navigateToRadar,
|
||||
modifier = Modifier.animateItem()
|
||||
)
|
||||
}
|
||||
NearEarthPass(
|
||||
pass = pass,
|
||||
navigateToRadar = navigateToRadar,
|
||||
modifier = Modifier.animateItem()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -159,114 +156,16 @@ private fun PassesList(
|
|||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun DeepSpacePassPreview() {
|
||||
val data = OrbitalData(
|
||||
"Satellite", 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 45000, 0.0
|
||||
)
|
||||
val data = OrbitalData("Satellite", 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 45000, 0.0)
|
||||
val satellite = DeepSpaceObject(data)
|
||||
val pass = OrbitalPass(1L, 180.0, 10L, 360.0, 36650, 45.0, satellite, 0.5f)
|
||||
MainTheme { DeepSpacePass(pass = pass, { _, _ -> }) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DeepSpacePass(
|
||||
pass: OrbitalPass,
|
||||
navigateToRadar: (Int, Long) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val passSatId = stringResource(id = R.string.pass_satId, pass.catNum)
|
||||
Surface(color = MaterialTheme.colorScheme.background, modifier = modifier) {
|
||||
Surface(modifier = Modifier
|
||||
.padding(bottom = 2.dp)
|
||||
.clickable { navigateToRadar(pass.catNum, pass.aosTime) }) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(1.dp),
|
||||
modifier = Modifier
|
||||
.background(color = MaterialTheme.colorScheme.surface)
|
||||
.padding(horizontal = 6.dp, vertical = 4.dp)
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(
|
||||
text = "$passSatId - ",
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
Text(
|
||||
text = pass.name,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(end = 6.dp),
|
||||
fontWeight = FontWeight.Medium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_elevation),
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text(
|
||||
text = "${pass.maxElevation}°",
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.weight(1f),
|
||||
horizontalArrangement = Arrangement.Start,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = "DeepSpace",
|
||||
fontSize = 15.sp
|
||||
)
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier.weight(1f),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_altitude),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text(
|
||||
text = "${pass.altitude} km",
|
||||
fontSize = 15.sp
|
||||
)
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier.weight(1f),
|
||||
horizontalArrangement = Arrangement.End,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(
|
||||
id = R.string.pass_aosLos,
|
||||
pass.aosAzimuth.toInt(),
|
||||
pass.losAzimuth.toInt()
|
||||
),
|
||||
fontSize = 15.sp
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MainTheme { NearEarthPass(pass = pass, { _, _ -> }) }
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun NearEarthPassPreview() {
|
||||
val data = OrbitalData(
|
||||
"Satellite", 0.0, 15.0, 0.0, 0.0, 0.0, 0.0, 0.0, 45000, 0.0
|
||||
)
|
||||
val data = OrbitalData("Satellite", 0.0, 15.0, 0.0, 0.0, 0.0, 0.0, 0.0, 45000, 0.0)
|
||||
val satellite = NearEarthObject(data)
|
||||
val pass = OrbitalPass(1L, 180.0, 10L, 360.0, 36650, 45.0, satellite, 0.5f)
|
||||
MainTheme { NearEarthPass(pass = pass, { _, _ -> }) }
|
||||
|
@ -281,7 +180,7 @@ private fun NearEarthPass(
|
|||
val passSatId = stringResource(id = R.string.pass_satId, pass.catNum)
|
||||
Surface(color = MaterialTheme.colorScheme.background, modifier = modifier) {
|
||||
Surface(modifier = Modifier
|
||||
.padding(bottom = 2.dp)
|
||||
.padding(bottom = 2.dp, start = 1.dp, end = 1.dp)
|
||||
.clickable { navigateToRadar(pass.catNum, pass.aosTime) }) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(1.dp),
|
||||
|
@ -325,10 +224,14 @@ private fun NearEarthPass(
|
|||
horizontalArrangement = Arrangement.Start,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = sdfDate.format(Date(pass.aosTime)),
|
||||
fontSize = 15.sp
|
||||
)
|
||||
if (pass.isDeepSpace) {
|
||||
Text(text = "DeepSpace", fontSize = 15.sp)
|
||||
} else {
|
||||
Text(
|
||||
text = sdfDate.format(Date(pass.aosTime)),
|
||||
fontSize = 15.sp
|
||||
)
|
||||
}
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier.weight(1f),
|
||||
|
|
|
@ -27,7 +27,6 @@ import androidx.compose.foundation.lazy.items
|
|||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
|
@ -58,8 +57,10 @@ import com.rtbishop.look4sat.presentation.common.NextPassRow
|
|||
import com.rtbishop.look4sat.presentation.common.TimerRow
|
||||
import com.rtbishop.look4sat.presentation.common.TopBar
|
||||
import com.rtbishop.look4sat.presentation.common.getDefaultPass
|
||||
import com.rtbishop.look4sat.presentation.common.isVerticalLayout
|
||||
import com.rtbishop.look4sat.presentation.common.layoutPadding
|
||||
|
||||
fun NavGraphBuilder.radarDestination(navigateBack: () -> Unit) {
|
||||
fun NavGraphBuilder.radarDestination(navigateUp: () -> Unit) {
|
||||
val radarRoute = "${Screen.Radar.route}?catNum={catNum}&aosTime={aosTime}"
|
||||
val radarArgs = listOf(
|
||||
navArgument("catNum") { defaultValue = 0 },
|
||||
|
@ -68,31 +69,36 @@ fun NavGraphBuilder.radarDestination(navigateBack: () -> Unit) {
|
|||
composable(radarRoute, radarArgs) {
|
||||
val viewModel = viewModel(RadarViewModel::class.java, factory = RadarViewModel.Factory)
|
||||
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
|
||||
RadarScreen(uiState, navigateBack)
|
||||
RadarScreen(uiState, navigateUp)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RadarScreen(uiState: RadarState, navigateBack: () -> Unit) {
|
||||
private fun RadarScreen(uiState: RadarState, navigateUp: () -> Unit) {
|
||||
// BluetoothCIV.init(LocalContext.current)
|
||||
|
||||
val addToCalendar: () -> Unit = {
|
||||
uiState.currentPass?.let { pass ->
|
||||
uiState.sendAction(RadarAction.AddToCalendar(pass.name, pass.aosTime, pass.losTime))
|
||||
}
|
||||
}
|
||||
Scaffold { innerPadding ->
|
||||
val paddingMod = Modifier.padding(innerPadding)
|
||||
Column(
|
||||
modifier = paddingMod.padding(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(6.dp)
|
||||
) {
|
||||
val upcomingPass = uiState.currentPass ?: getDefaultPass()
|
||||
Column(modifier = Modifier.layoutPadding(), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
if (isVerticalLayout()) {
|
||||
TopBar {
|
||||
IconCard(onClick = navigateBack, iconId = R.drawable.ic_back)
|
||||
IconCard(onClick = navigateUp, iconId = R.drawable.ic_back)
|
||||
TimerRow(timeString = uiState.currentTime, isTimeAos = uiState.isCurrentTimeAos)
|
||||
IconCard(onClick = addToCalendar, iconId = R.drawable.ic_calendar)
|
||||
}
|
||||
NextPassRow(pass = uiState.currentPass ?: getDefaultPass())
|
||||
NextPassRow(pass = upcomingPass)
|
||||
} else {
|
||||
TopBar {
|
||||
IconCard(onClick = navigateUp, iconId = R.drawable.ic_back)
|
||||
TimerRow(timeString = uiState.currentTime, isTimeAos = uiState.isCurrentTimeAos)
|
||||
NextPassRow(pass = upcomingPass, modifier = Modifier.weight(1f))
|
||||
IconCard(onClick = addToCalendar, iconId = R.drawable.ic_calendar)
|
||||
}
|
||||
}
|
||||
if(isVerticalLayout()) {
|
||||
Box(contentAlignment = Alignment.BottomCenter, modifier = Modifier.aspectRatio(1f)) {
|
||||
uiState.orbitalPos?.let { position ->
|
||||
ElevatedCard {
|
||||
|
@ -172,6 +178,88 @@ private fun RadarScreen(uiState: RadarState, navigateBack: () -> Unit) {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
Box(contentAlignment = Alignment.BottomCenter, modifier = Modifier.weight(1f)) {
|
||||
uiState.orbitalPos?.let { position ->
|
||||
ElevatedCard {
|
||||
RadarViewCompose(
|
||||
item = position,
|
||||
items = uiState.satTrack,
|
||||
azimElev = uiState.orientationValues,
|
||||
shouldShowSweep = uiState.shouldShowSweep,
|
||||
shouldUseCompass = false
|
||||
)
|
||||
}
|
||||
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().weight(1f)) {
|
||||
if (uiState.transmitters.isEmpty()) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_satellite),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(64.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text(
|
||||
text = "This satellite doesn't have any known transcievers...",
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = 18.sp,
|
||||
modifier = Modifier.padding(16.dp)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
TransmittersList(transmitters = uiState.transmitters)
|
||||
if (uiState.orbitalPos?.eclipsed == true) {
|
||||
EclipsedIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,9 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.material3.CardDefaults
|
||||
|
@ -46,23 +49,25 @@ import com.rtbishop.look4sat.R
|
|||
import com.rtbishop.look4sat.domain.model.SatItem
|
||||
import com.rtbishop.look4sat.presentation.MainTheme
|
||||
import com.rtbishop.look4sat.presentation.Screen
|
||||
import com.rtbishop.look4sat.presentation.common.IconCard
|
||||
import com.rtbishop.look4sat.presentation.common.CardLoadingIndicator
|
||||
import com.rtbishop.look4sat.presentation.common.IconCard
|
||||
import com.rtbishop.look4sat.presentation.common.InfoDialog
|
||||
import com.rtbishop.look4sat.presentation.common.TopBar
|
||||
import com.rtbishop.look4sat.presentation.common.isVerticalLayout
|
||||
import com.rtbishop.look4sat.presentation.common.layoutPadding
|
||||
|
||||
fun NavGraphBuilder.satellitesDestination(navigateToPasses: () -> Unit) {
|
||||
fun NavGraphBuilder.satellitesDestination(navigateUp: () -> Unit) {
|
||||
composable(Screen.Satellites.route) {
|
||||
val viewModel = viewModel(
|
||||
modelClass = SatellitesViewModel::class.java,
|
||||
factory = SatellitesViewModel.Factory
|
||||
modelClass = SatellitesViewModel::class.java, factory = SatellitesViewModel.Factory
|
||||
)
|
||||
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
|
||||
SatellitesScreen(uiState, navigateToPasses)
|
||||
SatellitesScreen(uiState, navigateUp)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SatellitesScreen(uiState: SatellitesState, navigateToPasses: () -> Unit) {
|
||||
private fun SatellitesScreen(uiState: SatellitesState, navigateUp: () -> Unit) {
|
||||
val toggleDialog = { uiState.takeAction(SatellitesAction.ToggleTypesDialog) }
|
||||
if (uiState.isDialogShown) {
|
||||
MultiTypesDialog(allTypes = uiState.typesList, types = uiState.currentTypes, toggleDialog) {
|
||||
|
@ -79,14 +84,28 @@ private fun SatellitesScreen(uiState: SatellitesState, navigateToPasses: () -> U
|
|||
}
|
||||
val unselectAll = { uiState.takeAction(SatellitesAction.UnselectAll) }
|
||||
val selectAll = { uiState.takeAction(SatellitesAction.SelectAll) }
|
||||
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
TopBar(setQuery = { newQuery: String ->
|
||||
uiState.takeAction(SatellitesAction.SearchFor(newQuery))
|
||||
}, saveSelection = {
|
||||
uiState.takeAction(SatellitesAction.SaveSelection)
|
||||
navigateToPasses()
|
||||
})
|
||||
MiddleBar(uiState.currentTypes, { toggleDialog() }, { unselectAll() }, { selectAll() })
|
||||
val setQuery = { newQuery: String -> uiState.takeAction(SatellitesAction.SearchFor(newQuery)) }
|
||||
val saveSelection = { uiState.takeAction(SatellitesAction.SaveSelection).also { navigateUp() } }
|
||||
Column(modifier = Modifier.layoutPadding(), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
if (isVerticalLayout()) {
|
||||
TopBar {
|
||||
TypeCard(types = uiState.currentTypes, toggleDialog, modifier = Modifier.weight(1f))
|
||||
SaveButton(saveSelection = saveSelection, modifier = Modifier.height(48.dp))
|
||||
}
|
||||
TopBar {
|
||||
SearchBar(setQuery = { setQuery(it) }, modifier = Modifier.weight(1f))
|
||||
IconCard(onClick = unselectAll, iconId = R.drawable.ic_check_off)
|
||||
IconCard(onClick = selectAll, iconId = R.drawable.ic_check_on)
|
||||
}
|
||||
} else {
|
||||
TopBar {
|
||||
SaveButton(saveSelection = saveSelection, modifier = Modifier.height(48.dp))
|
||||
TypeCard(types = uiState.currentTypes, toggleDialog, modifier = Modifier.weight(1f))
|
||||
SearchBar(setQuery = { setQuery(it) }, modifier = Modifier.weight(1f))
|
||||
IconCard(onClick = unselectAll, iconId = R.drawable.ic_check_off)
|
||||
IconCard(onClick = selectAll, iconId = R.drawable.ic_check_on)
|
||||
}
|
||||
}
|
||||
ElevatedCard(modifier = Modifier.fillMaxSize()) {
|
||||
if (uiState.isLoading) {
|
||||
CardLoadingIndicator()
|
||||
|
@ -99,18 +118,6 @@ private fun SatellitesScreen(uiState: SatellitesState, navigateToPasses: () -> U
|
|||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun TopBarPreview() = MainTheme { TopBar({}, {}) }
|
||||
|
||||
@Composable
|
||||
private fun TopBar(setQuery: (String) -> Unit, saveSelection: () -> Unit) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(6.dp), modifier = Modifier.height(48.dp)) {
|
||||
SearchBar(setQuery = { setQuery(it) }, modifier = Modifier.weight(1f))
|
||||
SaveButton(saveSelection = { saveSelection() }, modifier = Modifier.height(48.dp))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SearchBar(setQuery: (String) -> Unit, modifier: Modifier = Modifier) {
|
||||
val currentQuery = rememberSaveable { mutableStateOf("") }
|
||||
|
@ -168,26 +175,12 @@ private fun SaveButton(saveSelection: () -> Unit, modifier: Modifier = Modifier)
|
|||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun MiddleBarPreview() = MainTheme { MiddleBar(listOf("Amateur"), {}, {}, {}) }
|
||||
|
||||
@Composable
|
||||
private fun MiddleBar(
|
||||
types: List<String>, navigate: () -> Unit, uncheck: () -> Unit, check: () -> Unit
|
||||
) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(6.dp), modifier = Modifier.height(48.dp)) {
|
||||
TypeCard(types = types, { navigate() }, modifier = Modifier.weight(1f))
|
||||
IconCard(onClick = { uncheck() }, iconId = R.drawable.ic_check_off)
|
||||
IconCard(onClick = { check() }, iconId = R.drawable.ic_check_on)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TypeCard(types: List<String>, onClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
val typesText = if (types.isEmpty()) "All" else types.joinToString(", ")
|
||||
ElevatedCard(modifier = modifier) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.height(48.dp)
|
||||
|
@ -221,7 +214,8 @@ private fun SatellitePreview() {
|
|||
@Composable
|
||||
private fun Satellite(item: SatItem, onSelected: (Int, Boolean) -> Unit, modifier: Modifier) {
|
||||
val passSatId = stringResource(id = R.string.pass_satId, item.catnum)
|
||||
Surface(color = MaterialTheme.colorScheme.background,
|
||||
Surface(
|
||||
color = MaterialTheme.colorScheme.background,
|
||||
modifier = modifier.clickable { onSelected(item.catnum, item.isSelected) }) {
|
||||
Surface(modifier = Modifier.padding(bottom = 1.dp)) {
|
||||
Row(
|
||||
|
@ -263,7 +257,7 @@ private fun SatellitesPreview() {
|
|||
|
||||
@Composable
|
||||
fun SatellitesCard(items: List<SatItem>, onSelected: (Int, Boolean) -> Unit) {
|
||||
LazyColumn {
|
||||
LazyVerticalGrid(columns = GridCells.Adaptive(320.dp)) {
|
||||
items(items = items, key = { item -> item.catnum }) { entry ->
|
||||
Satellite(entry, onSelected, Modifier.animateItem())
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
|
@ -44,6 +46,7 @@ import com.rtbishop.look4sat.domain.predict.GeoPos
|
|||
import com.rtbishop.look4sat.presentation.MainTheme
|
||||
import com.rtbishop.look4sat.presentation.Screen
|
||||
import com.rtbishop.look4sat.presentation.common.CardButton
|
||||
import com.rtbishop.look4sat.presentation.common.layoutPadding
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
@ -130,8 +133,10 @@ private fun SettingsScreen(uiState: SettingsState) {
|
|||
}
|
||||
|
||||
// Screen setup
|
||||
LazyColumn(
|
||||
modifier = Modifier.padding(6.dp),
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Adaptive(320.dp),
|
||||
modifier = Modifier.layoutPadding(),
|
||||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(6.dp)
|
||||
) {
|
||||
item { CardAbout(uiState.appVersionName, uiState.sendSystemAction) }
|
||||
|
@ -461,17 +466,17 @@ private fun OtherCard(
|
|||
Text(text = stringResource(id = R.string.other_switch_sensors))
|
||||
Switch(checked = settings.stateOfSensors, onCheckedChange = { toggleSensor(it) })
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.other_switch_light_theme))
|
||||
Switch(
|
||||
checked = settings.stateOfLightTheme,
|
||||
onCheckedChange = { toggleLightTheme(it) }
|
||||
)
|
||||
}
|
||||
// Row(
|
||||
// horizontalArrangement = Arrangement.SpaceBetween,
|
||||
// verticalAlignment = Alignment.CenterVertically,
|
||||
// modifier = Modifier.fillMaxWidth()
|
||||
// ) {
|
||||
// Text(text = stringResource(id = R.string.other_switch_light_theme))
|
||||
// Switch(
|
||||
// checked = settings.stateOfLightTheme,
|
||||
// onCheckedChange = { toggleLightTheme(it) }
|
||||
// )
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,24 +158,24 @@
|
|||
<string name="BTremote_output_hint">Формат данных</string>
|
||||
<string name="BTremote_perm_error">Нет разрешения использовать bluetooth</string>
|
||||
|
||||
<string name="other_switch_utc">• Показывать время по UTC</string>
|
||||
<string name="other_switch_update">• Обновлять данные автоматически</string>
|
||||
<string name="other_switch_sweep">• Показывать анимацию радара</string>
|
||||
<string name="other_switch_sensors">• Использовать сенсоры устройства</string>
|
||||
<string name="other_switch_light_theme">• Использовать светлую тему</string>
|
||||
<string name="other_switch_utc">Показывать время по UTC</string>
|
||||
<string name="other_switch_update">Обновлять данные автоматически</string>
|
||||
<string name="other_switch_sweep">Показывать анимацию радара</string>
|
||||
<string name="other_switch_sensors">Использовать сенсоры устройства</string>
|
||||
<string name="other_switch_light_theme">Использовать светлую тему</string>
|
||||
|
||||
<string name="outro_title">Я хотел бы сказать спасибо:</string>
|
||||
<string name="outro_thanks">• Вам за использование этого приложения! \nЖелаю всегда чистого неба над головой!
|
||||
\n• <a href="https://github.com/g4dpz">David A. B. Johnson</a> и
|
||||
<string name="outro_thanks">Вам за использование этого приложения! \nЖелаю всегда чистого неба над головой!
|
||||
\n<a href="https://github.com/g4dpz">David A. B. Johnson</a> и
|
||||
<a href="https://github.com/davidmoten">Dave Moten</a> за работу над predict4java и доступ
|
||||
к ней по <a href="https://gnu.org/licenses/old-licenses/gpl-2.0.en.html">GNU GPLv2</a>
|
||||
\n• <a href="https://github.com/csete">Alexandru Csete</a> за его программу
|
||||
\n<a href="https://github.com/csete">Alexandru Csete</a> за его программу
|
||||
Gpredict, которая послужила для меня вдохновением.
|
||||
\n• <a href="https://celestrak.com/webmaster.php">Доктору T.S. Kelso</a> за его сайт
|
||||
\n<a href="https://celestrak.com/webmaster.php">Доктору T.S. Kelso</a> за его сайт
|
||||
<a href="https://celestrak.com/">Celestrak</a> и доступ к файлам орбит Two-Line Element.
|
||||
\n• <a href="https://libre.space/">Libre Space Foundation</a> за проект
|
||||
\n<a href="https://libre.space/">Libre Space Foundation</a> за проект
|
||||
<a href="https://db.satnogs.org/">SatNOGS</a>, API и базу данных с информацией о спутниках.
|
||||
\n• <a href="https://appoftheday.downloadastro.com/app/look4sat-satellite-tracker/">DownloadAstro</a>
|
||||
\n<a href="https://appoftheday.downloadastro.com/app/look4sat-satellite-tracker/">DownloadAstro</a>
|
||||
за интерес к приложению и публикацию интервью на сайте.
|
||||
</string>
|
||||
<string name="outro_license">Это ПО поставляется без гарантий.</string>
|
||||
|
|
|
@ -158,22 +158,22 @@
|
|||
<string name="BTremote_output_hint">දත්ත අකාරය</string>
|
||||
<string name="BTremote_perm_error">Bluetooth අවසර පරික්ෂා ක°</string>
|
||||
|
||||
<string name="other_switch_utc">• පසුකර වේලාවන් UTC මගින්</string>
|
||||
<string name="other_switch_update">• ස්වයං දත්ත යාවත්කාලීනය</string>
|
||||
<string name="other_switch_sweep">• radar sweep සජීවිකරණය සබල කරන්න</string>
|
||||
<string name="other_switch_sensors">• Radar දර්ශනය කරකැවීමට සංවේදක භාවිතා කරන්න </string>
|
||||
<string name="other_switch_light_theme">• සැහැල්ලු තේමාව භාවිතා කරන්න</string>
|
||||
<string name="other_switch_utc">පසුකර වේලාවන් UTC මගින්</string>
|
||||
<string name="other_switch_update">ස්වයං දත්ත යාවත්කාලීනය</string>
|
||||
<string name="other_switch_sweep">radar sweep සජීවිකරණය සබල කරන්න</string>
|
||||
<string name="other_switch_sensors">Radar දර්ශනය කරකැවීමට සංවේදක භාවිතා කරන්න </string>
|
||||
<string name="other_switch_light_theme">සැහැල්ලු තේමාව භාවිතා කරන්න</string>
|
||||
|
||||
<string name="outro_title">මම ස්තුති කිරීමට කැමති:</string>
|
||||
<string name="outro_thanks">• බාගෙන භාවිතා කළ ඔබට! \nඅහස සදා ඔබ වෙනුවෙන් පැහැදිලියි!
|
||||
\n• <a href="https://github.com/g4dpz">David A. B. Johnson</a>
|
||||
<string name="outro_thanks">බාගෙන භාවිතා කළ ඔබට! \nඅහස සදා ඔබ වෙනුවෙන් පැහැදිලියි!
|
||||
\n<a href="https://github.com/g4dpz">David A. B. Johnson</a>
|
||||
සහ <a href="https://github.com/davidmoten">Dave Moten</a>ඔවුනට ප්රයෝජනවත් predict4java පුස්තකාලය නිර්මාණයට.
|
||||
\n• සහ <a href="https://github.com/csete">Alexandru Csete</a> සඳහා Gpredict නිර්මාණයට සහ
|
||||
\nසහ <a href="https://github.com/csete">Alexandru Csete</a> සඳහා Gpredict නිර්මාණයට සහ
|
||||
Look4Sat නිර්මාණයට පෙළඹවීමට.
|
||||
\n• <a href="https://celestrak.com/webmaster.php">Dr T.S. Kelso</a>ට TLE දත්ත සැපයීමට, ඔහුගේ නඩත්තුවෙන් ක්රියාත්මක WEB අඩවිට ප්රවේශය සැපයීම වෙනුවෙන්
|
||||
\n<a href="https://celestrak.com/webmaster.php">Dr T.S. Kelso</a>ට TLE දත්ත සැපයීමට, ඔහුගේ නඩත්තුවෙන් ක්රියාත්මක WEB අඩවිට ප්රවේශය සැපයීම වෙනුවෙන්
|
||||
<a href="https://celestrak.com/"> (Celestrak)</a>.
|
||||
\n• <a href="https://libre.space/">Libre Space Foundation</a>ට ඔවුන්ගේ
|
||||
\n<a href="https://libre.space/">Libre Space Foundation</a>ට ඔවුන්ගේ
|
||||
<a href="https://db.satnogs.org/">SatNOGS</a>Web අඩවියට API හා DB විශාල දත්ත ප්රමාණයක් ලබාදීම සඳහා.
|
||||
\n• <a href="https://appoftheday.downloadastro.com/app/look4sat-satellite-tracker/">DownloadAstro</a> කණ්ඩායමට යෙදුම පිළිබඳ ඔවුන්ගේ උනන්දුව සහ කැපවීම ලැබිම සම්බන්ධයෙන්.</string>
|
||||
\n<a href="https://appoftheday.downloadastro.com/app/look4sat-satellite-tracker/">DownloadAstro</a> කණ්ඩායමට යෙදුම පිළිබඳ ඔවුන්ගේ උනන්දුව සහ කැපවීම ලැබිම සම්බන්ධයෙන්.</string>
|
||||
<string name="outro_license">මෘදුකාංගය වගකීමක් සමග නොලැබේ</string>
|
||||
</resources>
|
||||
|
|
|
@ -158,25 +158,25 @@
|
|||
<string name="BTremote_output_hint">数据格式</string>
|
||||
<string name="BTremote_perm_error">请检查蓝牙权限</string>
|
||||
|
||||
<string name="other_switch_utc">• 以 UTC 时间显示</string>
|
||||
<string name="other_switch_update">• 启用卫星数据自动更新</string>
|
||||
<string name="other_switch_sweep">• 启用雷达扫描动画</string>
|
||||
<string name="other_switch_sensors">• 使用传感器旋转雷达视图</string>
|
||||
<string name="other_switch_light_theme">• 使用旧版配色方案</string>
|
||||
<string name="other_switch_utc">以 UTC 时间显示</string>
|
||||
<string name="other_switch_update">启用卫星数据自动更新</string>
|
||||
<string name="other_switch_sweep">启用雷达扫描动画</string>
|
||||
<string name="other_switch_sensors">使用传感器旋转雷达视图</string>
|
||||
<string name="other_switch_light_theme">使用旧版配色方案</string>
|
||||
|
||||
<string name="outro_title">我要感谢:</string>
|
||||
<string name="outro_thanks">• 感谢下载和使用 Look4Sat!愿你的天空永远晴朗!
|
||||
\n• 简体中文版翻译由 <a href="https://github.com/BA7LWN">BA7LWN</a> 于 2022.5.10 创建。
|
||||
\n• <a href="https://github.com/g4dpz">David A. B. Johnson</a>
|
||||
<string name="outro_thanks">感谢下载和使用 Look4Sat!愿你的天空永远晴朗!
|
||||
\n简体中文版翻译由 <a href="https://github.com/BA7LWN">BA7LWN</a> 于 2022.5.10 创建。
|
||||
\n<a href="https://github.com/g4dpz">David A. B. Johnson</a>
|
||||
and <a href="https://github.com/davidmoten">Dave Moten</a> for creating predict4java lib
|
||||
under the <a href="https://gnu.org/licenses/old-licenses/gpl-2.0.en.html">GNU GPLv2</a>.
|
||||
\n• <a href="https://github.com/csete">Alexandru Csete</a> for creating Gpredict
|
||||
\n<a href="https://github.com/csete">Alexandru Csete</a> for creating Gpredict
|
||||
satellite tracker that inspired the creation of Look4Sat.
|
||||
\n• <a href="https://celestrak.com/webmaster.php">Dr T.S. Kelso</a> for maintaining his
|
||||
\n<a href="https://celestrak.com/webmaster.php">Dr T.S. Kelso</a> for maintaining his
|
||||
<a href="https://celestrak.com/">Celestrak</a> website that provides access to the TLE data.
|
||||
\n• <a href="https://libre.space/">Libre Space Foundation</a> for their
|
||||
\n<a href="https://libre.space/">Libre Space Foundation</a> for their
|
||||
<a href="https://db.satnogs.org/">SatNOGS</a> API and DB providing a huge amount of satellite data.
|
||||
\n• <a href="https://appoftheday.downloadastro.com/app/look4sat-satellite-tracker/">DownloadAstro</a>
|
||||
\n<a href="https://appoftheday.downloadastro.com/app/look4sat-satellite-tracker/">DownloadAstro</a>
|
||||
team for their interest to the app and the interview published.
|
||||
</string>
|
||||
<string name="outro_license">该应用程序不提供任何保修.</string>
|
||||
|
|
|
@ -173,23 +173,23 @@
|
|||
<string name="BTremote_output_hint">Data format</string>
|
||||
<string name="BTremote_perm_error">Check your bluetooth permission</string>
|
||||
|
||||
<string name="other_switch_utc">• Show pass time in UTC</string>
|
||||
<string name="other_switch_update">• Enable automatic data update</string>
|
||||
<string name="other_switch_sweep">• Enable radar sweep animation</string>
|
||||
<string name="other_switch_sensors">• Use sensors to rotate radar view</string>
|
||||
<string name="other_switch_light_theme">• Use light theme</string>
|
||||
<string name="other_switch_utc">Show pass time in UTC</string>
|
||||
<string name="other_switch_update">Enable automatic data update</string>
|
||||
<string name="other_switch_sweep">Enable radar sweep animation</string>
|
||||
<string name="other_switch_sensors">Use sensors to rotate radar view</string>
|
||||
<string name="other_switch_light_theme">Use light theme</string>
|
||||
|
||||
<string name="outro_title">I would like to say thanks to:</string>
|
||||
<string name="outro_thanks">• You for downloading and using Look4Sat! \nMay your sky always be clear!
|
||||
\n• <a href="https://github.com/g4dpz">David A. B. Johnson</a>
|
||||
<string name="outro_thanks">You for downloading and using Look4Sat! \nMay your sky always be clear!
|
||||
\n<a href="https://github.com/g4dpz">David A. B. Johnson</a>
|
||||
and <a href="https://github.com/davidmoten">Dave Moten</a> for creating a super useful predict4java library.
|
||||
\n• <a href="https://github.com/csete">Alexandru Csete</a> for creating Gpredict
|
||||
\n<a href="https://github.com/csete">Alexandru Csete</a> for creating Gpredict
|
||||
tracker that inspired the creation of Look4Sat.
|
||||
\n• <a href="https://celestrak.com/webmaster.php">Dr T.S. Kelso</a> for maintaining his
|
||||
\n<a href="https://celestrak.com/webmaster.php">Dr T.S. Kelso</a> for maintaining his
|
||||
<a href="https://celestrak.com/">Celestrak</a> website that provides access to the TLE data.
|
||||
\n• <a href="https://libre.space/">Libre Space Foundation</a> for their
|
||||
\n<a href="https://libre.space/">Libre Space Foundation</a> for their
|
||||
<a href="https://db.satnogs.org/">SatNOGS</a> API and DB providing a huge amount of data.
|
||||
\n• <a href="https://appoftheday.downloadastro.com/app/look4sat-satellite-tracker/">DownloadAstro</a>
|
||||
\n<a href="https://appoftheday.downloadastro.com/app/look4sat-satellite-tracker/">DownloadAstro</a>
|
||||
team for their interest to the app and the interview published.
|
||||
</string>
|
||||
<string name="outro_license">The app comes with no warranty.</string>
|
||||
|
|
|
@ -33,7 +33,7 @@ androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "
|
|||
compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" }
|
||||
compose-animation = { group = "androidx.compose.animation", name = "animation" }
|
||||
compose-material3 = { group = "androidx.compose.material3", name = "material3" }
|
||||
compose-material3-adaptive = { group = "androidx.compose.material3.adaptive", name = "adaptive" }
|
||||
compose-material3-navigation = { group = "androidx.compose.material3", name = "material3-adaptive-navigation-suite" }
|
||||
compose-runtime = { group = "androidx.compose.runtime", name = "runtime" }
|
||||
compose-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
|
||||
|
||||
|
@ -68,7 +68,7 @@ kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
|||
[bundles]
|
||||
composeAll = [
|
||||
"compose-animation", "compose-runtime", "compose-tooling", "compose-activity",
|
||||
"compose-lifecycle", "compose-material3", "compose-material3-adaptive",
|
||||
"compose-lifecycle", "compose-material3", "compose-material3-navigation",
|
||||
"compose-navigation", "compose-viewmodel"
|
||||
]
|
||||
composeDebug = ["compose-debug-manifest", "compose-debug-tooling"]
|
||||
|
|
Ładowanie…
Reference in New Issue