diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/MainScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/MainScreen.kt index 24019e01..ff7dd8a8 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/MainScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/MainScreen.kt @@ -1,115 +1,32 @@ -@file:OptIn(ExperimentalSharedTransitionApi::class) - package com.rtbishop.look4sat.presentation -import android.annotation.SuppressLint -import android.util.Log -import androidx.compose.animation.AnimatedVisibilityScope -import androidx.compose.animation.ExperimentalSharedTransitionApi -import androidx.compose.animation.SharedTransitionLayout -import androidx.compose.animation.SharedTransitionScope -import androidx.compose.material3.Icon -import androidx.compose.material3.NavigationBar -import androidx.compose.material3.NavigationBarItem -import androidx.compose.material3.Text +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.compositionLocalOf 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.rememberNavController -import androidx.navigation.navigation -import com.rtbishop.look4sat.R -import com.rtbishop.look4sat.presentation.info.infoDestination 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 Satellites : Screen("Satellites", R.drawable.ic_sputnik, "satellites") - data object PassesGraph : Screen("Passes", R.drawable.ic_passes, "passesGraph") - data object Passes : Screen("Passes", R.drawable.ic_passes, "passes") - data object Radar : Screen("Radar", R.drawable.ic_sputnik, "radar") - data object Map : Screen("Map", R.drawable.ic_map, "map") - data object Settings : Screen("Settings", R.drawable.ic_settings, "settings") - data object Info : Screen("Info", R.drawable.ic_info, "info") -} - -val LocalSharedTransitionScope = compositionLocalOf { null } -val LocalNavAnimatedVisibilityScope = compositionLocalOf { null } - @Composable fun MainScreen() { val navController: NavHostController = rememberNavController() - val navigateBack: () -> Unit = { navController.navigateUp() } - val navigateToRadar = { catNum: Int, aosTime: Long -> - val routeWithParams = "${Screen.Radar.route}?catNum=${catNum}&aosTime=${aosTime}" - navController.navigate(routeWithParams) - } - SharedTransitionLayout { - CompositionLocalProvider(LocalSharedTransitionScope provides this) { - NavHost(navController = navController, startDestination = Screen.PassesGraph.route) { - satellitesDestination(navController, navigateBack) - passesGraph(navController, navigateBack, navigateToRadar) - radarDestination(navigateBack) - mapDestination(navController) - settingsDestination(navController) - infoDestination(navController) - } - } - } -} - -private fun NavGraphBuilder.passesGraph( - navController: NavHostController, - navigateBack: () -> Unit, - navigateToRadar: (Int, Long) -> Unit -) { - navigation(route = Screen.PassesGraph.route, startDestination = Screen.Passes.route) { - passesDestination(navController, navigateToRadar) - radarDestination(navigateBack) - } -} - -@SuppressLint("RestrictedApi", "StateFlowValueCalledInComposition") -@Composable -fun MainNavBar(navController: NavController) { - val sharedTransitionScope = LocalSharedTransitionScope.current - ?: throw IllegalStateException("No SharedElementScope found") - val animatedVisibilityScope = LocalNavAnimatedVisibilityScope.current - ?: throw IllegalStateException("No SharedElementScope found") - val sharedTransitionState = sharedTransitionScope.rememberSharedContentState("bottomNav") - val items = listOf(Screen.Satellites, Screen.Passes, Screen.Map, Screen.Settings, Screen.Info) - val stack = navController.currentBackStack.value.map { it.destination.route } - Log.d("NavBar", "NavStack: $stack") - with(sharedTransitionScope) { - NavigationBar( - modifier = Modifier.sharedElement(sharedTransitionState, animatedVisibilityScope) + Scaffold { innerPadding -> + NavHost( + navController = navController, + startDestination = "passes", + modifier = Modifier.padding(innerPadding) ) { - items.forEach { item -> - NavigationBarItem( - icon = { Icon(painterResource(item.icon), item.title) }, - label = { Text(item.title) }, - selected = item.route == navController.currentDestination?.route, - onClick = { - if (item.route == navController.currentDestination?.route) { - // selecting the same tab - } else { - navController.navigate(item.route) { - popUpTo(Screen.Passes.route) { saveState = false } - launchSingleTop = true - restoreState = false - } - } - } - ) - } + satellitesDestination(navController) + passesDestination(navController) + radarDestination(navController) + mapDestination(navController) + settingsDestination(navController) } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/components/Common.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/components/Common.kt index 69fc1d29..31a11091 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/components/Common.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/components/Common.kt @@ -140,12 +140,6 @@ fun NextPassRow(pass: OrbitalPass) { horizontalArrangement = Arrangement.Start, verticalAlignment = Alignment.CenterVertically ) { - Icon( - painter = painterResource(id = R.drawable.ic_time), - contentDescription = null, - modifier = Modifier.size(16.dp) - ) - Spacer(modifier = Modifier.width(4.dp)) Text( text = sdfTime.format(Date(pass.aosTime)), fontSize = 15.sp, @@ -173,12 +167,6 @@ fun NextPassRow(pass: OrbitalPass) { horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically ) { - Icon( - painter = painterResource(id = R.drawable.ic_direction), - contentDescription = null, - modifier = Modifier.size(16.dp) - ) - Spacer(modifier = Modifier.width(4.dp)) Text( text = stringResource( id = R.string.pass_aosLos, diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/info/InfoScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/info/InfoScreen.kt deleted file mode 100644 index 7f48cdbe..00000000 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/info/InfoScreen.kt +++ /dev/null @@ -1,105 +0,0 @@ -package com.rtbishop.look4sat.presentation.info - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material3.ElevatedCard -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.navigation.NavGraphBuilder -import androidx.navigation.NavHostController -import androidx.navigation.compose.composable -import com.rtbishop.look4sat.R -import com.rtbishop.look4sat.presentation.LocalNavAnimatedVisibilityScope -import com.rtbishop.look4sat.presentation.MainNavBar -import com.rtbishop.look4sat.presentation.MainTheme -import com.rtbishop.look4sat.presentation.Screen -import com.rtbishop.look4sat.presentation.components.CardButton - -private const val POLICY_URL = "https://sites.google.com/view/look4sat-privacy-policy/home" -private const val LICENSE_URL = "https://www.gnu.org/licenses/gpl-3.0.html" - -fun NavGraphBuilder.infoDestination(navController: NavHostController) { - composable(Screen.Info.route) { - CompositionLocalProvider(LocalNavAnimatedVisibilityScope provides this@composable) { - Scaffold(bottomBar = { MainNavBar(navController) }) { innerPadding -> - Box(Modifier.padding(innerPadding)) { - InfoScreen() - } - } - } - } -} - -@Composable -private fun InfoScreen() { - LazyColumn(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) { - item { CardCredits() } - } -} - -@Preview(showBackground = true) -@Composable -private fun CardCreditsPreview() = MainTheme { CardCredits() } - -@Composable -private fun CardCredits(modifier: Modifier = Modifier) { - val uriHandler = LocalUriHandler.current - ElevatedCard(modifier = modifier.fillMaxWidth()) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp) - ) { - Text( - text = stringResource(id = R.string.outro_title), - fontSize = 18.sp, - fontWeight = FontWeight.Medium, - color = MaterialTheme.colorScheme.primary, - modifier = modifier.padding(6.dp) - ) - Text( - text = stringResource( - id = R.string.outro_thanks - ), fontSize = 16.sp, textAlign = TextAlign.Center - ) - Text( - text = stringResource(id = R.string.outro_license), - fontSize = 18.sp, - fontWeight = FontWeight.Medium, - color = MaterialTheme.colorScheme.primary, - modifier = modifier.padding(6.dp) - ) - Row(horizontalArrangement = Arrangement.SpaceEvenly) { - CardButton( - onClick = { uriHandler.openUri(LICENSE_URL) }, - text = stringResource(id = R.string.btn_license), - modifier = Modifier.weight(1f) - ) - Spacer(modifier = Modifier.width(6.dp)) - CardButton( - onClick = { uriHandler.openUri(POLICY_URL) }, - text = stringResource(id = R.string.btn_privacy), - modifier = Modifier.weight(1f) - ) - } - } - } -} diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/map/MapScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/map/MapScreen.kt index 33cfc87a..b4c7048f 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/map/MapScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/map/MapScreen.kt @@ -15,10 +15,8 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.ElevatedCard import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.State @@ -45,9 +43,6 @@ import com.rtbishop.look4sat.R import com.rtbishop.look4sat.domain.predict.GeoPos import com.rtbishop.look4sat.domain.predict.OrbitalObject import com.rtbishop.look4sat.domain.predict.OrbitalPos -import com.rtbishop.look4sat.presentation.LocalNavAnimatedVisibilityScope -import com.rtbishop.look4sat.presentation.MainNavBar -import com.rtbishop.look4sat.presentation.Screen import com.rtbishop.look4sat.presentation.components.CardIcon import com.rtbishop.look4sat.presentation.components.NextPassRow import com.rtbishop.look4sat.presentation.components.TimerBar @@ -86,17 +81,11 @@ private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { private val labelRect = Rect() fun NavGraphBuilder.mapDestination(navController: NavHostController) { - composable(Screen.Map.route) { + composable("map") { val viewModel = viewModel(MapViewModel::class.java, factory = MapViewModel.Factory) val uiState = viewModel.uiState.collectAsStateWithLifecycle() val mapView = rememberMapViewWithLifecycle() - CompositionLocalProvider(LocalNavAnimatedVisibilityScope provides this@composable) { - Scaffold(bottomBar = { MainNavBar(navController) }) { innerPadding -> - Box(modifier = Modifier.padding(innerPadding)) { - MapScreen(uiState, mapView) - } - } - } + MapScreen(uiState, mapView) } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesScreen.kt index 94c5f9eb..ab75401a 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesScreen.kt @@ -3,7 +3,6 @@ package com.rtbishop.look4sat.presentation.passes import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -19,14 +18,12 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource @@ -46,15 +43,13 @@ import com.rtbishop.look4sat.domain.predict.DeepSpaceObject import com.rtbishop.look4sat.domain.predict.NearEarthObject import com.rtbishop.look4sat.domain.predict.OrbitalData import com.rtbishop.look4sat.domain.predict.OrbitalPass -import com.rtbishop.look4sat.presentation.LocalNavAnimatedVisibilityScope -import com.rtbishop.look4sat.presentation.MainNavBar import com.rtbishop.look4sat.presentation.MainTheme -import com.rtbishop.look4sat.presentation.Screen import com.rtbishop.look4sat.presentation.components.CardIcon import com.rtbishop.look4sat.presentation.components.InfoDialog import com.rtbishop.look4sat.presentation.components.NextPassRow import com.rtbishop.look4sat.presentation.components.TimerBar import com.rtbishop.look4sat.presentation.components.TimerRow +import com.rtbishop.look4sat.presentation.radar.navigateToRadar import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -62,20 +57,17 @@ import java.util.Locale private val sdfDate = SimpleDateFormat("EEE dd MMM", Locale.ENGLISH) private val sdfTime = SimpleDateFormat("HH:mm:ss", Locale.ENGLISH) -fun NavGraphBuilder.passesDestination(navController: NavHostController, navigateToRadar: (Int, Long) -> Unit) { - composable(Screen.Passes.route) { +fun NavGraphBuilder.passesDestination(navController: NavHostController) { + composable("passes") { val viewModel = viewModel( modelClass = PassesViewModel::class.java, factory = PassesViewModel.Factory ) val uiState = viewModel.uiState.collectAsStateWithLifecycle().value - CompositionLocalProvider(LocalNavAnimatedVisibilityScope provides this@composable) { - Scaffold(bottomBar = { MainNavBar(navController) }) { innerPadding -> - Box(modifier = Modifier.padding(innerPadding)) { - PassesScreen(uiState, navigateToRadar) - } - } + val navigateToRadar = { catNum: Int, aosTime: Long -> + navController.navigateToRadar(catNum, aosTime) } + PassesScreen(uiState, navigateToRadar) } } @@ -222,12 +214,6 @@ private fun DeepSpacePass( horizontalArrangement = Arrangement.Start, verticalAlignment = Alignment.CenterVertically ) { - Icon( - painter = painterResource(id = R.drawable.ic_arrow), - contentDescription = null, - modifier = Modifier.size(16.dp) - ) - Spacer(modifier = Modifier.width(4.dp)) Text( text = "DeepSpace", fontSize = 15.sp @@ -254,12 +240,6 @@ private fun DeepSpacePass( horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically ) { - Icon( - painter = painterResource(id = R.drawable.ic_direction), - contentDescription = null, - modifier = Modifier.size(16.dp) - ) - Spacer(modifier = Modifier.width(4.dp)) Text( text = stringResource( id = R.string.pass_aosLos, @@ -339,12 +319,6 @@ private fun NearEarthPass( horizontalArrangement = Arrangement.Start, verticalAlignment = Alignment.CenterVertically ) { - Icon( - painter = painterResource(id = R.drawable.ic_calendar), - contentDescription = null, - modifier = Modifier.size(16.dp) - ) - Spacer(modifier = Modifier.width(4.dp)) Text( text = sdfDate.format(Date(pass.aosTime)), fontSize = 15.sp @@ -371,12 +345,6 @@ private fun NearEarthPass( horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically ) { - Icon( - painter = painterResource(id = R.drawable.ic_direction), - contentDescription = null, - modifier = Modifier.size(16.dp) - ) - Spacer(modifier = Modifier.width(4.dp)) Text( text = stringResource( id = R.string.pass_aosLos, diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarScreen.kt index a1f2d6ac..e6655fea 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarScreen.kt @@ -27,11 +27,9 @@ 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 -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -47,22 +45,21 @@ import androidx.compose.ui.unit.sp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavHostController import androidx.navigation.compose.composable import androidx.navigation.navArgument import com.rtbishop.look4sat.R import com.rtbishop.look4sat.domain.model.SatRadio import com.rtbishop.look4sat.domain.utility.toDegrees -import com.rtbishop.look4sat.presentation.LocalNavAnimatedVisibilityScope import com.rtbishop.look4sat.presentation.MainTheme -import com.rtbishop.look4sat.presentation.Screen import com.rtbishop.look4sat.presentation.components.CardIcon import com.rtbishop.look4sat.presentation.components.NextPassRow import com.rtbishop.look4sat.presentation.components.TimerBar import com.rtbishop.look4sat.presentation.components.TimerRow import com.rtbishop.look4sat.presentation.components.getDefaultPass -fun NavGraphBuilder.radarDestination(navigateBack: () -> Unit) { - val radarRoute = "${Screen.Radar.route}?catNum={catNum}&aosTime={aosTime}" +fun NavGraphBuilder.radarDestination(navController: NavHostController) { + val radarRoute = "radar?catNum={catNum}&aosTime={aosTime}" val radarArgs = listOf( navArgument("catNum") { defaultValue = 0 }, navArgument("aosTime") { defaultValue = 0L } @@ -70,12 +67,14 @@ fun NavGraphBuilder.radarDestination(navigateBack: () -> Unit) { composable(radarRoute, radarArgs) { val viewModel = viewModel(RadarViewModel::class.java, factory = RadarViewModel.Factory) val uiState = viewModel.uiState.collectAsStateWithLifecycle().value - CompositionLocalProvider(LocalNavAnimatedVisibilityScope provides this@composable) { - RadarScreen(uiState, navigateBack) - } + RadarScreen(uiState) { navController.navigateUp() } } } +fun NavHostController.navigateToRadar(catNum: Int, aosTime: Long) { + navigate("radar?catNum=${catNum}&aosTime=${aosTime}") +} + @Composable private fun RadarScreen(uiState: RadarState, navigateBack: () -> Unit) { // BluetoothCIV.init(LocalContext.current) @@ -85,94 +84,91 @@ private fun RadarScreen(uiState: RadarState, navigateBack: () -> Unit) { 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) - ) { - TimerRow { - CardIcon(onClick = navigateBack, iconId = R.drawable.ic_back) - TimerBar(timeString = uiState.currentTime, isTimeAos = uiState.isCurrentTimeAos) - CardIcon(onClick = addToCalendar, iconId = R.drawable.ic_calendar) - } - NextPassRow(pass = uiState.currentPass ?: getDefaultPass()) - Box(contentAlignment = Alignment.BottomCenter, modifier = Modifier.aspectRatio(1f)) { - uiState.orbitalPos?.let { position -> - ElevatedCard { - RadarViewCompose( - item = position, - items = uiState.satTrack, - azimElev = uiState.orientationValues, - shouldShowSweep = uiState.shouldShowSweep, - shouldUseCompass = uiState.shouldUseCompass + Column( + modifier = Modifier.padding(6.dp), + verticalArrangement = Arrangement.spacedBy(6.dp) + ) { + TimerRow { + CardIcon(onClick = navigateBack, iconId = R.drawable.ic_back) + TimerBar(timeString = uiState.currentTime, isTimeAos = uiState.isCurrentTimeAos) + CardIcon(onClick = addToCalendar, iconId = R.drawable.ic_calendar) + } + NextPassRow(pass = uiState.currentPass ?: getDefaultPass()) + Box(contentAlignment = Alignment.BottomCenter, modifier = Modifier.aspectRatio(1f)) { + uiState.orbitalPos?.let { position -> + ElevatedCard { + RadarViewCompose( + item = position, + items = uiState.satTrack, + azimElev = uiState.orientationValues, + 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 ) } - Column( - verticalArrangement = Arrangement.SpaceBetween, - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 6.dp, vertical = 4.dp) + Row( + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier.fillMaxWidth() ) { - 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 - ) - } + RadarTextBottom( + position.altitude, + stringResource(R.string.radar_alt_text), + true + ) + RadarTextBottom( + position.distance, + stringResource(R.string.radar_dist_text), + false + ) } } } - ElevatedCard(modifier = Modifier.fillMaxSize()) { - 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() - } + } + ElevatedCard(modifier = Modifier.fillMaxSize()) { + 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() } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesScreen.kt index da6b5699..52454537 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesScreen.kt @@ -22,11 +22,9 @@ import androidx.compose.material3.ElevatedCard import androidx.compose.material3.Icon import androidx.compose.material3.IconButton 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 -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment @@ -47,28 +45,19 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.composable import com.rtbishop.look4sat.R import com.rtbishop.look4sat.domain.model.SatItem -import com.rtbishop.look4sat.presentation.LocalNavAnimatedVisibilityScope -import com.rtbishop.look4sat.presentation.MainNavBar import com.rtbishop.look4sat.presentation.MainTheme -import com.rtbishop.look4sat.presentation.Screen import com.rtbishop.look4sat.presentation.components.CardIcon import com.rtbishop.look4sat.presentation.components.CardLoadingIndicator import com.rtbishop.look4sat.presentation.components.InfoDialog -fun NavGraphBuilder.satellitesDestination(navController: NavHostController, navigateToPasses: () -> Unit) { - composable(Screen.Satellites.route) { +fun NavGraphBuilder.satellitesDestination(navController: NavHostController) { + composable("satellites") { val viewModel = viewModel( modelClass = SatellitesViewModel::class.java, factory = SatellitesViewModel.Factory ) val uiState = viewModel.uiState.collectAsStateWithLifecycle().value - CompositionLocalProvider(LocalNavAnimatedVisibilityScope provides this@composable) { - Scaffold(bottomBar = { MainNavBar(navController) }) { innerPadding -> - Box(modifier = Modifier.padding(innerPadding)) { - SatellitesScreen(uiState, navigateToPasses) - } - } - } + SatellitesScreen(uiState) { navController.navigateUp() } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsScreen.kt index 8160d23e..484fbfe0 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsScreen.kt @@ -5,7 +5,6 @@ import android.os.Build import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -19,18 +18,18 @@ import androidx.compose.material3.ElevatedCard import androidx.compose.material3.Icon import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -43,30 +42,23 @@ import androidx.navigation.compose.composable import com.rtbishop.look4sat.R import com.rtbishop.look4sat.domain.model.OtherSettings import com.rtbishop.look4sat.domain.predict.GeoPos -import com.rtbishop.look4sat.presentation.LocalNavAnimatedVisibilityScope -import com.rtbishop.look4sat.presentation.MainNavBar import com.rtbishop.look4sat.presentation.MainTheme -import com.rtbishop.look4sat.presentation.Screen import com.rtbishop.look4sat.presentation.components.CardButton -import org.osmdroid.library.BuildConfig import java.text.SimpleDateFormat import java.util.Date import java.util.Locale +private const val POLICY_URL = "https://sites.google.com/view/look4sat-privacy-policy/home" +private const val LICENSE_URL = "https://www.gnu.org/licenses/gpl-3.0.html" + fun NavGraphBuilder.settingsDestination(navController: NavHostController) { - composable(Screen.Settings.route) { + composable("settings") { val viewModel = viewModel( modelClass = SettingsViewModel::class.java, factory = SettingsViewModel.Factory ) val uiState = viewModel.uiState.collectAsStateWithLifecycle().value - CompositionLocalProvider(LocalNavAnimatedVisibilityScope provides this@composable) { - Scaffold(bottomBar = { MainNavBar(navController) }) { innerPadding -> - Box(modifier = Modifier.padding(innerPadding)) { - SettingsScreen(uiState) - } - } - } + SettingsScreen(uiState) } } @@ -164,6 +156,7 @@ private fun SettingsScreen(uiState: SettingsState) { toggleLightTheme ) } + item { CardCredits() } } } @@ -468,18 +461,16 @@ private fun OtherCard( Text(text = stringResource(id = R.string.other_switch_sensors)) Switch(checked = settings.stateOfSensors, onCheckedChange = { toggleSensor(it) }) } - if (BuildConfig.DEBUG) { - 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) } + ) } } } @@ -506,3 +497,51 @@ private fun UpdateIndicator(isUpdating: Boolean, modifier: Modifier = Modifier) modifier = modifier.padding(start = 6.dp) ) } + +@Preview(showBackground = true) +@Composable +private fun CardCreditsPreview() = MainTheme { CardCredits() } + +@Composable +private fun CardCredits(modifier: Modifier = Modifier) { + val uriHandler = LocalUriHandler.current + ElevatedCard(modifier = modifier.fillMaxWidth()) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp) + ) { + Text( + text = stringResource(id = R.string.outro_title), + fontSize = 18.sp, + fontWeight = FontWeight.Medium, + color = MaterialTheme.colorScheme.primary, + modifier = modifier.padding(6.dp) + ) + Text( + text = stringResource( + id = R.string.outro_thanks + ), fontSize = 16.sp, textAlign = TextAlign.Center + ) + Text( + text = stringResource(id = R.string.outro_license), + fontSize = 18.sp, + fontWeight = FontWeight.Medium, + color = MaterialTheme.colorScheme.primary, + modifier = modifier.padding(6.dp) + ) + Row(horizontalArrangement = Arrangement.SpaceEvenly) { + CardButton( + onClick = { uriHandler.openUri(LICENSE_URL) }, + text = stringResource(id = R.string.btn_license), + modifier = Modifier.weight(1f) + ) + Spacer(modifier = Modifier.width(6.dp)) + CardButton( + onClick = { uriHandler.openUri(POLICY_URL) }, + text = stringResource(id = R.string.btn_privacy), + modifier = Modifier.weight(1f) + ) + } + } + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3c1668b1..9fea7704 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -89,7 +89,7 @@ %s Id:%05d AOS - %.1f° - %03d° -> %03d° + %03d° - %03d° Elevation: %.1f° %.1f° - LOS Altitude: %d km