Tried using floating app bar layout for screen navigation

This commit is contained in:
Arty Bishop committed 2025-12-27 15:01:47 +00:00
1 parent 82f41940c7
commit 42aa4deb0d
11 files changed
+137 -146

No files matched your search

@@ -1,75 +1,53 @@
package com.rtbishop.look4sat.presentation package com.rtbishop.look4sat.presentation
import androidx.compose.material3.Icon import androidx.compose.foundation.background
import androidx.compose.material3.MaterialTheme 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.runtime.Composable
import androidx.compose.ui.res.painterResource import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController 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.map.mapDestination
import com.rtbishop.look4sat.presentation.passes.passesDestination import com.rtbishop.look4sat.presentation.passes.passesDestination
import com.rtbishop.look4sat.presentation.radar.radarDestination import com.rtbishop.look4sat.presentation.radar.radarDestination
import com.rtbishop.look4sat.presentation.satellites.satellitesDestination import com.rtbishop.look4sat.presentation.satellites.satellitesDestination
import com.rtbishop.look4sat.presentation.settings.settingsDestination import com.rtbishop.look4sat.presentation.settings.settingsDestination
sealed class Screen(val title: String, val icon: Int, val route: String) { sealed class Screen(val route: String) {
data object Satellites : Screen("Satellites", R.drawable.ic_sputnik, "satellites") data object Satellites : Screen("satellites")
data object Passes : Screen("Passes", R.drawable.ic_passes, "passes") data object Passes : Screen("passes")
data object Radar : Screen("Radar", R.drawable.ic_satellite, "radar") data object Radar : Screen("radar")
data object Map : Screen("Map", R.drawable.ic_map, "map") data object Map : Screen("map")
data object Settings : Screen("Settings", R.drawable.ic_settings, "settings") data object Settings : Screen("settings")
} }
private val startDestination = Screen.Passes.route data class NavActions(
val openSatellites: () -> Unit,
val openRadar: (Int, Long) -> Unit,
val openMap: () -> Unit,
val openSettings: () -> Unit
)
@Composable @Composable
fun MainScreen(navController: NavHostController = rememberNavController()) { fun MainScreen(navController: NavHostController = rememberNavController()) {
val items = listOf(Screen.Satellites, Screen.Passes, Screen.Radar, Screen.Map, Screen.Settings) val navActions = NavActions(
val destinationRoute = navController.currentBackStackEntryAsState().value?.destination?.route openSatellites = { navController.navigate(Screen.Satellites.route) },
NavigationSuiteScaffold( openRadar = { catNum: Int, aosTime: Long ->
navigationSuiteItems = { val routeWithParams = "${Screen.Radar.route}?catNum=${catNum}&aosTime=${aosTime}"
items.forEach { navController.navigate(routeWithParams)
item( },
icon = { Icon(painterResource(it.icon), it.title) }, openMap = { navController.navigate(Screen.Map.route) },
label = { Text(it.title) }, openSettings = { navController.navigate(Screen.Settings.route) }
selected = destinationRoute?.contains(it.route) ?: false, )
onClick = { NavHost(
if (destinationRoute?.contains(it.route) ?: false) return@item navController = navController,
navController.navigate(it.route) { startDestination = Screen.Passes.route,
popUpTo(startDestination) { saveState = false } modifier = Modifier.background(color = MaterialTheme.colorScheme.background)
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() } satellitesDestination { navController.navigateUp() }
passesDestination(navigateToRadar) passesDestination(navActions)
radarDestination { navController.navigateUp() } radarDestination { navController.navigateUp() }
mapDestination() mapDestination { navController.navigateUp() }
settingsDestination() settingsDestination { navController.navigateUp() }
} }
} }
@@ -22,23 +22,14 @@ import androidx.compose.ui.unit.sp
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
val LocalSpacing = compositionLocalOf { Spacing } val LocalSpacing = compositionLocalOf { Spacing }
//val MaterialTheme.spacing: Spacing
// @Composable @ReadOnlyComposable get() = Spacing
data object SpacingDefaults {
internal const val EXTRA_SMALL = 4
internal const val SMALL = 6
internal const val MEDIUM = 8
internal const val LARGE = 12
internal const val EXTRA_LARGE = 16
}
data object Spacing { data object Spacing {
val extraSmall = SpacingDefaults.EXTRA_SMALL.dp val extraExtraSmall = 4.dp
val small = SpacingDefaults.SMALL.dp val extraSmall = 6.dp
val medium = SpacingDefaults.MEDIUM.dp val small = 8.dp
val large = SpacingDefaults.LARGE.dp val medium = 12.dp
val extraLarge = SpacingDefaults.EXTRA_LARGE.dp val large = 16.dp
val extraLarge = 24.dp
} }
@Composable @Composable
@@ -17,21 +17,22 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ElevatedButton import androidx.compose.material3.ElevatedButton
import androidx.compose.material3.ElevatedCard import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.font.FontWeight 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
@@ -56,9 +57,9 @@ private val sdfTime = SimpleDateFormat("HH:mm:ss", Locale.ENGLISH)
@Preview(showBackground = true) @Preview(showBackground = true)
private fun TopBarPreview() = MainTheme { private fun TopBarPreview() = MainTheme {
TopBar { TopBar {
IconCard(onClick = {}, iconId = R.drawable.ic_filter) IconCard(action = {}, resId = R.drawable.ic_filter)
TimerRow(timeString = "88:88:88", isTimeAos = true) TimerRow(timeString = "88:88:88", isTimeAos = true)
IconCard(onClick = {}, iconId = R.drawable.ic_satellite) IconCard(action = {}, resId = R.drawable.ic_satellite)
} }
} }
@@ -200,12 +201,13 @@ fun CardButton(onClick: () -> Unit, text: String, modifier: Modifier = Modifier)
} }
@Composable @Composable
fun IconCard(onClick: () -> Unit, iconId: Int, modifier: Modifier = Modifier) { fun IconCard(action: () -> Unit, resId: Int, modifier: Modifier = Modifier, main: Boolean = false) {
val clickableModifier = Modifier.clickable { onClick() } val clickableMod = Modifier.clickable { action() }
val iconRes = ImageVector.vectorResource(iconId) val defaultC = CardDefaults.elevatedCardColors()
ElevatedCard(modifier = Modifier.size(48.dp)) { val mainC = CardDefaults.elevatedCardColors(containerColor = MaterialTheme.colorScheme.primary)
Box(modifier = clickableModifier.fillMaxSize(), contentAlignment = Alignment.Center) { ElevatedCard(modifier = Modifier.size(48.dp), colors = if (main) mainC else defaultC, shape = CircleShape) {
Icon(imageVector = iconRes, contentDescription = null, modifier = modifier) Box(modifier = clickableMod.fillMaxSize(), contentAlignment = Alignment.Center) {
Icon(painter = painterResource(resId), contentDescription = null, modifier = modifier)
} }
} }
} }
@@ -241,7 +243,7 @@ fun getDefaultPass(): OrbitalPass {
fun SharedDialog( fun SharedDialog(
title: String, onCancel: () -> Unit, onAccept: () -> Unit, content: @Composable () -> Unit title: String, onCancel: () -> Unit, onAccept: () -> Unit, content: @Composable () -> Unit
) { ) {
val padding = LocalSpacing.current.extraLarge val padding = LocalSpacing.current.large
Dialog(onDismissRequest = { onCancel() }) { Dialog(onDismissRequest = { onCancel() }) {
ElevatedCard { ElevatedCard {
Column( Column(
@@ -268,7 +270,7 @@ fun SharedDialog(
@Composable @Composable
fun InfoDialog(title: String, text: String, onDismiss: () -> Unit) { fun InfoDialog(title: String, text: String, onDismiss: () -> Unit) {
val padding = LocalSpacing.current.extraLarge val padding = LocalSpacing.current.large
Dialog(onDismissRequest = onDismiss) { Dialog(onDismissRequest = onDismiss) {
ElevatedCard { ElevatedCard {
Column( Column(
@@ -290,7 +292,10 @@ fun InfoDialog(title: String, text: String, onDismiss: () -> Unit) {
) )
Row(modifier = Modifier.padding(start = padding, bottom = padding, end = padding)) { Row(modifier = Modifier.padding(start = padding, bottom = padding, end = padding)) {
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
CardButton(onClick = onDismiss, text = stringResource(id = R.string.btn_understand)) CardButton(
onClick = onDismiss,
text = stringResource(id = R.string.btn_understand)
)
} }
} }
} }
@@ -311,9 +316,41 @@ fun Modifier.infiniteMarquee(): Modifier {
@Composable @Composable
fun Modifier.layoutPadding(): Modifier { fun Modifier.layoutPadding(): Modifier {
val statusBarMod = this.statusBarsPadding() val statusBarMod = this.statusBarsPadding()
val spacing = LocalSpacing.current.small val spacing = LocalSpacing.current.extraSmall
return when { return statusBarMod.padding(start = spacing, top = 0.dp, end = spacing, bottom = spacing)
isVerticalLayout() -> statusBarMod.padding(horizontal = spacing) }
else -> statusBarMod.padding(start = 0.dp, top = 0.dp, end = spacing, bottom = spacing)
@Composable
fun ScreenColumn(floatingBar: @Composable () -> Unit = {}, content: @Composable (Boolean) -> Unit) {
Box(contentAlignment = Alignment.BottomCenter) {
Column(
modifier = Modifier.layoutPadding(),
verticalArrangement = Arrangement.spacedBy(LocalSpacing.current.extraSmall)
) { content(isVerticalLayout()) }
floatingBar()
}
}
@Composable
fun FloatingBar(
startAction: () -> Unit, startIconResId: Int,
centerAction: () -> Unit, centerIconResId: Int,
endAction: () -> Unit, endIconResId: Int
) {
val spacing = LocalSpacing.current
Surface(
color = MaterialTheme.colorScheme.background,
shape = CircleShape,
modifier = Modifier.padding(bottom = spacing.large)
) {
Row(
horizontalArrangement = Arrangement.spacedBy(spacing.medium),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(spacing.medium)
) {
IconCard(action = startAction, resId = startIconResId)
IconCard(action = centerAction, resId = centerIconResId, main = true)
IconCard(action = endAction, resId = endIconResId)
}
} }
} }
@@ -85,7 +85,7 @@ private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
} }
private val labelRect = Rect() private val labelRect = Rect()
fun NavGraphBuilder.mapDestination() { fun NavGraphBuilder.mapDestination(function: () -> Boolean) {
composable(Screen.Map.route) { composable(Screen.Map.route) {
val viewModel = viewModel(MapViewModel::class.java, factory = MapViewModel.Factory) val viewModel = viewModel(MapViewModel::class.java, factory = MapViewModel.Factory)
val uiState = viewModel.uiState.collectAsStateWithLifecycle() val uiState = viewModel.uiState.collectAsStateWithLifecycle()
@@ -110,17 +110,17 @@ private fun MapScreen(uiState: State<MapState>, mapView: MapView) {
Column(modifier = Modifier.layoutPadding(), verticalArrangement = Arrangement.spacedBy(6.dp)) { Column(modifier = Modifier.layoutPadding(), verticalArrangement = Arrangement.spacedBy(6.dp)) {
if (isVerticalLayout()) { if (isVerticalLayout()) {
TopBar { TopBar {
IconCard(onClick = selectPrev, iconId = R.drawable.ic_arrow, modifier = rotateMod) IconCard(action = selectPrev, resId = R.drawable.ic_arrow, modifier = rotateMod)
TimerRow(timeString = timeString, isTimeAos = isTimeAos) TimerRow(timeString = timeString, isTimeAos = isTimeAos)
IconCard(onClick = selectNext, iconId = R.drawable.ic_arrow) IconCard(action = selectNext, resId = R.drawable.ic_arrow)
} }
NextPassRow(pass = uiState.value.orbitalPass) NextPassRow(pass = uiState.value.orbitalPass)
} else { } else {
TopBar { TopBar {
IconCard(onClick = selectPrev, iconId = R.drawable.ic_arrow, modifier = rotateMod) IconCard(action = selectPrev, resId = R.drawable.ic_arrow, modifier = rotateMod)
TimerRow(timeString = timeString, isTimeAos = isTimeAos) TimerRow(timeString = timeString, isTimeAos = isTimeAos)
NextPassRow(pass = uiState.value.orbitalPass, modifier = Modifier.weight(1f)) NextPassRow(pass = uiState.value.orbitalPass, modifier = Modifier.weight(1f))
IconCard(onClick = selectNext, iconId = R.drawable.ic_arrow) IconCard(action = selectNext, resId = R.drawable.ic_arrow)
} }
} }
ElevatedCard(modifier = Modifier.weight(1f)) { ElevatedCard(modifier = Modifier.weight(1f)) {
@@ -102,11 +102,11 @@ private fun SliderRow(
) { ) {
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(LocalSpacing.current.medium), verticalArrangement = Arrangement.spacedBy(LocalSpacing.current.small),
modifier = Modifier.padding(horizontal = LocalSpacing.current.extraLarge) modifier = Modifier.padding(horizontal = LocalSpacing.current.large)
) { ) {
Row( Row(
horizontalArrangement = Arrangement.spacedBy(LocalSpacing.current.medium), horizontalArrangement = Arrangement.spacedBy(LocalSpacing.current.small),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Text( Text(
@@ -44,16 +44,18 @@ import com.rtbishop.look4sat.domain.predict.NearEarthObject
import com.rtbishop.look4sat.domain.predict.OrbitalData import com.rtbishop.look4sat.domain.predict.OrbitalData
import com.rtbishop.look4sat.domain.predict.OrbitalPass import com.rtbishop.look4sat.domain.predict.OrbitalPass
import com.rtbishop.look4sat.presentation.MainTheme import com.rtbishop.look4sat.presentation.MainTheme
import com.rtbishop.look4sat.presentation.NavActions
import com.rtbishop.look4sat.presentation.Screen import com.rtbishop.look4sat.presentation.Screen
import com.rtbishop.look4sat.presentation.common.EmptyListCard import com.rtbishop.look4sat.presentation.common.EmptyListCard
import com.rtbishop.look4sat.presentation.common.FloatingBar
import com.rtbishop.look4sat.presentation.common.IconCard import com.rtbishop.look4sat.presentation.common.IconCard
import com.rtbishop.look4sat.presentation.common.InfoDialog import com.rtbishop.look4sat.presentation.common.InfoDialog
import com.rtbishop.look4sat.presentation.common.NextPassRow import com.rtbishop.look4sat.presentation.common.NextPassRow
import com.rtbishop.look4sat.presentation.common.ScreenColumn
import com.rtbishop.look4sat.presentation.common.TimerRow import com.rtbishop.look4sat.presentation.common.TimerRow
import com.rtbishop.look4sat.presentation.common.TopBar import com.rtbishop.look4sat.presentation.common.TopBar
import com.rtbishop.look4sat.presentation.common.infiniteMarquee import com.rtbishop.look4sat.presentation.common.infiniteMarquee
import com.rtbishop.look4sat.presentation.common.isVerticalLayout import com.rtbishop.look4sat.presentation.common.isVerticalLayout
import com.rtbishop.look4sat.presentation.common.layoutPadding
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
@@ -61,20 +63,20 @@ import java.util.Locale
private val sdfDate = SimpleDateFormat("EEE dd MMM", Locale.ENGLISH) private val sdfDate = SimpleDateFormat("EEE dd MMM", Locale.ENGLISH)
private val sdfTime = SimpleDateFormat("HH:mm:ss", Locale.ENGLISH) private val sdfTime = SimpleDateFormat("HH:mm:ss", Locale.ENGLISH)
fun NavGraphBuilder.passesDestination(navigateToRadar: (Int, Long) -> Unit) { fun NavGraphBuilder.passesDestination(navActions: NavActions) {
composable(Screen.Passes.route) { composable(Screen.Passes.route) {
val viewModel = viewModel( val viewModel = viewModel(
modelClass = PassesViewModel::class.java, modelClass = PassesViewModel::class.java,
factory = PassesViewModel.Factory factory = PassesViewModel.Factory
) )
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
PassesScreen(uiState, navigateToRadar) PassesScreen(uiState, navActions)
} }
} }
@Composable @Composable
private fun PassesScreen(uiState: PassesState, navigateToRadar: (Int, Long) -> Unit) { private fun PassesScreen(uiState: PassesState, navActions: NavActions) {
val refreshPasses = { uiState.takeAction(PassesAction.RefreshPasses) } val refreshList = { uiState.takeAction(PassesAction.RefreshPasses) }
val showPassesDialog = { uiState.takeAction(PassesAction.TogglePassesDialog) } val showPassesDialog = { uiState.takeAction(PassesAction.TogglePassesDialog) }
val showRadiosDialog = { uiState.takeAction(PassesAction.ToggleRadiosDialog) } val showRadiosDialog = { uiState.takeAction(PassesAction.ToggleRadiosDialog) }
if (uiState.isPassesDialogShown) { if (uiState.isPassesDialogShown) {
@@ -95,26 +97,35 @@ private fun PassesScreen(uiState: PassesState, navigateToRadar: (Int, Long) -> U
uiState.takeAction(PassesAction.DismissWelcome) uiState.takeAction(PassesAction.DismissWelcome)
} }
} }
Column(modifier = Modifier.layoutPadding(), verticalArrangement = Arrangement.spacedBy(6.dp)) { ScreenColumn(floatingBar = { PassesFloatingBar(navActions) }) { isVerticalLayout ->
if (isVerticalLayout()) { if (isVerticalLayout) {
TopBar { TopBar {
IconCard(onClick = { showPassesDialog() }, iconId = R.drawable.ic_filter) IconCard(action = { showPassesDialog() }, resId = R.drawable.ic_filter)
TimerRow(timeString = uiState.nextTime, isTimeAos = uiState.isNextTimeAos) TimerRow(timeString = uiState.nextTime, isTimeAos = uiState.isNextTimeAos)
IconCard(onClick = { showRadiosDialog() }, iconId = R.drawable.ic_satellite) IconCard(action = { showRadiosDialog() }, resId = R.drawable.ic_satellite)
} }
NextPassRow(pass = uiState.nextPass) NextPassRow(pass = uiState.nextPass)
} else { } else {
TopBar { TopBar {
IconCard(onClick = { showPassesDialog() }, iconId = R.drawable.ic_filter) IconCard(action = { showPassesDialog() }, resId = R.drawable.ic_filter)
TimerRow(timeString = uiState.nextTime, isTimeAos = uiState.isNextTimeAos) TimerRow(timeString = uiState.nextTime, isTimeAos = uiState.isNextTimeAos)
NextPassRow(pass = uiState.nextPass, modifier = Modifier.weight(1f)) NextPassRow(pass = uiState.nextPass, modifier = Modifier.weight(1f))
IconCard(onClick = { showRadiosDialog() }, iconId = R.drawable.ic_satellite) IconCard(action = { showRadiosDialog() }, resId = R.drawable.ic_satellite)
} }
} }
PassesList(uiState.isRefreshing, uiState.itemsList, navigateToRadar, refreshPasses) PassesList(uiState.isRefreshing, uiState.itemsList, navActions.openRadar, refreshList)
} }
} }
@Composable
private fun PassesFloatingBar(navActions: NavActions) {
FloatingBar(
startAction = navActions.openSettings, startIconResId = R.drawable.ic_settings,
centerAction = navActions.openSatellites, centerIconResId = R.drawable.ic_sputnik,
endAction = navActions.openMap, endIconResId = R.drawable.ic_map
)
}
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun PassesList( private fun PassesList(
@@ -84,17 +84,17 @@ private fun RadarScreen(uiState: RadarState, navigateUp: () -> Unit) {
Column(modifier = Modifier.layoutPadding(), verticalArrangement = Arrangement.spacedBy(6.dp)) { Column(modifier = Modifier.layoutPadding(), verticalArrangement = Arrangement.spacedBy(6.dp)) {
if (isVerticalLayout()) { if (isVerticalLayout()) {
TopBar { TopBar {
IconCard(onClick = navigateUp, iconId = R.drawable.ic_back) IconCard(action = navigateUp, resId = R.drawable.ic_back)
TimerRow(timeString = uiState.currentTime, isTimeAos = uiState.isCurrentTimeAos) TimerRow(timeString = uiState.currentTime, isTimeAos = uiState.isCurrentTimeAos)
IconCard(onClick = addToCalendar, iconId = R.drawable.ic_calendar) IconCard(action = addToCalendar, resId = R.drawable.ic_calendar)
} }
NextPassRow(pass = upcomingPass) NextPassRow(pass = upcomingPass)
} else { } else {
TopBar { TopBar {
IconCard(onClick = navigateUp, iconId = R.drawable.ic_back) IconCard(action = navigateUp, resId = R.drawable.ic_back)
TimerRow(timeString = uiState.currentTime, isTimeAos = uiState.isCurrentTimeAos) TimerRow(timeString = uiState.currentTime, isTimeAos = uiState.isCurrentTimeAos)
NextPassRow(pass = upcomingPass, modifier = Modifier.weight(1f)) NextPassRow(pass = upcomingPass, modifier = Modifier.weight(1f))
IconCard(onClick = addToCalendar, iconId = R.drawable.ic_calendar) IconCard(action = addToCalendar, resId = R.drawable.ic_calendar)
} }
} }
if(isVerticalLayout()) { if(isVerticalLayout()) {
@@ -92,16 +92,16 @@ private fun SatellitesScreen(uiState: SatellitesState, navigateUp: () -> Unit) {
} }
TopBar { TopBar {
SearchBar(setQuery = { setQuery(it) }, modifier = Modifier.weight(1f)) SearchBar(setQuery = { setQuery(it) }, modifier = Modifier.weight(1f))
IconCard(onClick = unselectAll, iconId = R.drawable.ic_check_off) IconCard(action = unselectAll, resId = R.drawable.ic_check_off)
IconCard(onClick = selectAll, iconId = R.drawable.ic_check_on) IconCard(action = selectAll, resId = R.drawable.ic_check_on)
} }
} else { } else {
TopBar { TopBar {
SaveButton(saveSelection = saveSelection, modifier = Modifier.height(48.dp)) SaveButton(saveSelection = saveSelection, modifier = Modifier.height(48.dp))
TypeCard(types = uiState.currentTypes, toggleDialog, modifier = Modifier.weight(1f)) TypeCard(types = uiState.currentTypes, toggleDialog, modifier = Modifier.weight(1f))
SearchBar(setQuery = { setQuery(it) }, modifier = Modifier.weight(1f)) SearchBar(setQuery = { setQuery(it) }, modifier = Modifier.weight(1f))
IconCard(onClick = unselectAll, iconId = R.drawable.ic_check_off) IconCard(action = unselectAll, resId = R.drawable.ic_check_off)
IconCard(onClick = selectAll, iconId = R.drawable.ic_check_on) IconCard(action = selectAll, resId = R.drawable.ic_check_on)
} }
} }
ElevatedCard(modifier = Modifier.fillMaxSize()) { ElevatedCard(modifier = Modifier.fillMaxSize()) {
@@ -50,7 +50,7 @@ import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
fun NavGraphBuilder.settingsDestination() { fun NavGraphBuilder.settingsDestination(function: () -> Boolean) {
composable(Screen.Settings.route) { composable(Screen.Settings.route) {
val viewModel = viewModel( val viewModel = viewModel(
modelClass = SettingsViewModel::class.java, modelClass = SettingsViewModel::class.java,
@@ -348,7 +348,7 @@ private fun DataCard(
Spacer(modifier = Modifier.width(6.dp)) Spacer(modifier = Modifier.width(6.dp))
CardButton( CardButton(
onClick = { updateFromFile() }, onClick = { updateFromFile() },
text = stringResource(id = R.string.btn_file), text = stringResource(id = R.string.btn_import),
modifier = Modifier.weight(1f) modifier = Modifier.weight(1f)
) )
Spacer(modifier = Modifier.width(6.dp)) Spacer(modifier = Modifier.width(6.dp))
-26
View File
@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="Theme.Look4Sat.SplashScreen" parent="Theme.SplashScreen">
<item name="android:forceDarkAllowed" tools:targetApi="q">false</item>
<item name="postSplashScreenTheme">@style/Theme.Look4Sat.Main</item>
<item name="windowSplashScreenBackground">@color/background</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_splash</item>
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
<style name="Theme.Look4Sat.Main" parent="Theme.Material3.Dark.NoActionBar">
<item name="colorAccent">@color/accent</item>
<item name="colorControlNormal">@color/textMain</item>
<item name="colorPrimary">@color/accent</item>
<item name="colorSecondary">@color/accent</item>
<item name="colorOnPrimaryContainer">@color/background</item>
<item name="android:forceDarkAllowed" tools:targetApi="q">false</item>
<item name="android:listDivider">@drawable/item_divider</item>
<item name="android:navigationBarColor">@color/background</item>
<item name="android:textColorPrimary">@color/textMain</item>
<item name="android:statusBarColor">@color/background</item>
<item name="android:windowBackground">@color/background</item>
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
</resources>
+5 -5
View File
@@ -1,5 +1,5 @@
[versions] [versions]
android-gradle-plugin = "8.12.1" android-gradle-plugin = "8.12.2"
google-ksp = "2.2.10-2.0.2" google-ksp = "2.2.10-2.0.2"
kotlin = "2.2.10" kotlin = "2.2.10"
@@ -7,9 +7,9 @@ androidx-core-ktx = "1.17.0"
androidx-core-splashscreen = "1.0.1" androidx-core-splashscreen = "1.0.1"
androidx-room = "2.7.2" androidx-room = "2.7.2"
compose-bom = "2025.08.00" compose-bom = "2025.08.01"
compose-activity = "1.10.1" compose-activity = "1.10.1"
compose-lifecycle = "2.9.2" compose-lifecycle = "2.9.3"
compose-navigation = "2.9.3" compose-navigation = "2.9.3"
other-coroutines = "1.10.2" other-coroutines = "1.10.2"
@@ -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-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" }
compose-animation = { group = "androidx.compose.animation", name = "animation" } compose-animation = { group = "androidx.compose.animation", name = "animation" }
compose-material3 = { group = "androidx.compose.material3", name = "material3" } compose-material3 = { group = "androidx.compose.material3", name = "material3" }
compose-material3-navigation = { group = "androidx.compose.material3", name = "material3-adaptive-navigation-suite" } compose-material3-adaptive = { group = "androidx.compose.material3.adaptive", name = "adaptive" }
compose-runtime = { group = "androidx.compose.runtime", name = "runtime" } compose-runtime = { group = "androidx.compose.runtime", name = "runtime" }
compose-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } compose-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
@@ -68,7 +68,7 @@ kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
[bundles] [bundles]
composeAll = [ composeAll = [
"compose-animation", "compose-runtime", "compose-tooling", "compose-activity", "compose-animation", "compose-runtime", "compose-tooling", "compose-activity",
"compose-lifecycle", "compose-material3", "compose-material3-navigation", "compose-lifecycle", "compose-material3", "compose-material3-adaptive",
"compose-navigation", "compose-viewmodel" "compose-navigation", "compose-viewmodel"
] ]
composeDebug = ["compose-debug-manifest", "compose-debug-tooling"] composeDebug = ["compose-debug-manifest", "compose-debug-tooling"]