diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8f06ef47..d2b8fb80 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,16 +7,15 @@
+ android:roundIcon="@mipmap/ic_launcher_round">
+ android:theme="@style/Theme.Look4Sat.SplashScreen"
+ android:windowSoftInputMode="adjustResize">
@@ -24,5 +23,4 @@
-
diff --git a/app/src/main/java/com/rtbishop/look4sat/MainActivity.kt b/app/src/main/java/com/rtbishop/look4sat/MainActivity.kt
index de5aa9e2..392d7a06 100644
--- a/app/src/main/java/com/rtbishop/look4sat/MainActivity.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/MainActivity.kt
@@ -20,21 +20,23 @@ package com.rtbishop.look4sat
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
+import androidx.activity.enableEdgeToEdge
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.platform.LocalContext
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
-import com.rtbishop.look4sat.presentation.MainScreen
import com.rtbishop.look4sat.presentation.MainTheme
+import com.rtbishop.look4sat.presentation.MainScreen
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen()
+ enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContent {
val container = (LocalContext.current.applicationContext as MainApplication).container
val otherSettings = container.settingsRepo.otherSettings.collectAsState().value
- MainTheme(isLightTheme = otherSettings.stateOfLightTheme) { MainScreen() }
+ MainTheme(isDarkTheme = !otherSettings.stateOfLightTheme) { MainScreen() }
}
}
}
diff --git a/app/src/main/java/com/rtbishop/look4sat/MainApplication.kt b/app/src/main/java/com/rtbishop/look4sat/MainApplication.kt
index e67b9c02..317d0b91 100644
--- a/app/src/main/java/com/rtbishop/look4sat/MainApplication.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/MainApplication.kt
@@ -37,19 +37,13 @@ class MainApplication : Application() {
}
private suspend fun checkAutoUpdate(timeNow: Long = System.currentTimeMillis()) {
- val settingsRepo = container.settingsRepo
- if (settingsRepo.otherSettings.value.stateOfAutoUpdate) {
- val timeDelta = timeNow - settingsRepo.databaseState.value.updateTimestamp
- if (timeDelta > AUTO_UPDATE_DELTA_MS) {
+ if (container.settingsRepo.otherSettings.value.stateOfAutoUpdate) {
+ val timeDelta = timeNow - container.settingsRepo.databaseState.value.updateTimestamp
+ if (timeDelta > 172_800_000L) { // 48 hours in ms
val sdf = SimpleDateFormat("d MMM yyyy - HH:mm:ss", Locale.getDefault())
println("Started periodic data update on ${sdf.format(Date())}")
container.databaseRepo.updateFromRemote()
}
}
}
-
- companion object {
- private const val AUTO_UPDATE_DELTA_MS = 172_800_000L // 48 hours in ms
- const val MAX_OKHTTP_CACHE_SIZE = 10_000_000L // 10 Megabytes
- }
}
diff --git a/app/src/main/java/com/rtbishop/look4sat/MainContainer.kt b/app/src/main/java/com/rtbishop/look4sat/MainContainer.kt
index 23620a6e..787ccedd 100644
--- a/app/src/main/java/com/rtbishop/look4sat/MainContainer.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/MainContainer.kt
@@ -28,7 +28,6 @@ import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
-import okhttp3.Cache
import okhttp3.OkHttpClient
import org.osmdroid.config.Configuration
@@ -65,16 +64,13 @@ class MainContainer(private val context: Context) {
private fun provideLocalSource(): ILocalSource {
val database = Room.databaseBuilder(context, Look4SatDb::class.java, "Look4SatDBv313").apply {
-// addMigrations(MIGRATION_1_2)
fallbackToDestructiveMigration()
}.build()
return LocalSource(database.look4SatDao())
}
private fun provideRemoteSource(): IRemoteSource {
- val cache = Cache(context.cacheDir, MainApplication.MAX_OKHTTP_CACHE_SIZE)
- val httpClient = OkHttpClient.Builder().cache(cache).build()
- return RemoteSource(context.contentResolver, httpClient, Dispatchers.IO)
+ return RemoteSource(Dispatchers.IO, context.contentResolver, OkHttpClient.Builder().build())
}
private fun provideSatelliteRepo(): ISatelliteRepo {
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 a09e9f44..d726c48f 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/MainScreen.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/MainScreen.kt
@@ -1,16 +1,15 @@
package com.rtbishop.look4sat.presentation
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.height
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.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
@@ -21,69 +20,89 @@ import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.rtbishop.look4sat.R
-import com.rtbishop.look4sat.presentation.entries.EntriesScreen
-import com.rtbishop.look4sat.presentation.entries.EntriesViewModel
import com.rtbishop.look4sat.presentation.info.InfoScreen
import com.rtbishop.look4sat.presentation.map.MapScreen
import com.rtbishop.look4sat.presentation.passes.PassesScreen
import com.rtbishop.look4sat.presentation.passes.PassesViewModel
import com.rtbishop.look4sat.presentation.radar.RadarScreen
+import com.rtbishop.look4sat.presentation.satellites.SatellitesScreen
+import com.rtbishop.look4sat.presentation.satellites.SatellitesViewModel
import com.rtbishop.look4sat.presentation.settings.SettingsScreen
sealed class Screen(var title: String, var icon: Int, var route: String) {
- data object Entries : Screen("Entries", R.drawable.ic_sputnik, "entries")
+ data object Main : Screen("Main", R.drawable.ic_sputnik, "main")
+ data object Radar : Screen("Radar", R.drawable.ic_sputnik, "radar")
+ 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_passes, "passes.radar")
- data object Map : Screen("World Map", R.drawable.ic_world_map, "world_map")
+ 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")
}
@Composable
-fun MainScreen(navController: NavHostController = rememberNavController()) {
- Scaffold(bottomBar = { MainNavBar(navController = navController) }) { innerPadding ->
- Box(modifier = Modifier.padding(innerPadding)) { MainNavGraph(navController) }
+fun MainScreen() {
+ val outerNavController: NavHostController = rememberNavController()
+ val radarRoute = "${Screen.Radar.route}?catNum={catNum}&aosTime={aosTime}"
+ val radarArgs = listOf(navArgument("catNum") { defaultValue = 0 },
+ navArgument("aosTime") { defaultValue = 0L })
+ val navToRadar = { catNum: Int, aosTime: Long ->
+ val navRoute = "${Screen.Radar.route}?catNum=${catNum}&aosTime=${aosTime}"
+ outerNavController.navigate(navRoute)
+ }
+ NavHost(navController = outerNavController, startDestination = Screen.Main.route) {
+ composable(Screen.Main.route) { NavBarScreen(navToRadar) }
+ composable(radarRoute, radarArgs) { RadarScreen() }
+ }
+}
+
+@Composable
+private fun NavBarScreen(navToRadar: (Int, Long) -> Unit) {
+ val innerNavController: NavHostController = rememberNavController()
+ val navToPasses = { innerNavController.navigate(Screen.Passes.route) }
+ Scaffold(bottomBar = { MainNavBar(navController = innerNavController) }) { innerPadding ->
+ Box(modifier = Modifier.padding(innerPadding)) {
+ NavHost(innerNavController, startDestination = Screen.Passes.route) {
+ composable(Screen.Satellites.route) {
+ val viewModel = viewModel(
+ SatellitesViewModel::class.java, factory = SatellitesViewModel.Factory
+ )
+ val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
+ SatellitesScreen(uiState, navToPasses)
+ }
+ composable(Screen.Passes.route) {
+ val viewModel = viewModel(
+ PassesViewModel::class.java, factory = PassesViewModel.Factory
+ )
+ val uiState = viewModel.uiState.value
+ PassesScreen(uiState, navToRadar)
+ }
+ composable(Screen.Map.route) { MapScreen() }
+ composable(Screen.Settings.route) { SettingsScreen() }
+ composable(Screen.Info.route) { InfoScreen() }
+ }
+ }
}
}
@Composable
private fun MainNavBar(navController: NavController) {
- val items = listOf(Screen.Entries, Screen.Passes, Screen.Map, Screen.Settings, Screen.Info)
- NavigationBar(modifier = Modifier.height(48.dp), tonalElevation = 0.dp) {
- val navBackStackEntry = navController.currentBackStackEntryAsState()
- val currentRoute = navBackStackEntry.value?.destination?.route
- items.forEach { screen ->
- NavigationBarItem(selected = currentRoute?.contains(screen.route) ?: false, onClick = {
- navController.navigate(screen.route) {
- navController.graph.startDestinationRoute?.let { popUpTo(it) { saveState = false } }
- launchSingleTop = true
- restoreState = false
- }
- }, icon = { Icon(painterResource(id = screen.icon), contentDescription = screen.title) })
+ val items = listOf(Screen.Satellites, Screen.Passes, Screen.Map, Screen.Settings, Screen.Info)
+ val currentBackStackEntry = navController.currentBackStackEntryAsState()
+ val currentRoute = currentBackStackEntry.value?.destination?.route
+ NavigationBar {
+ items.forEach { item ->
+ NavigationBarItem(selected = currentRoute?.contains(item.route) ?: false,
+ onClick = {
+ navController.navigate(item.route) {
+ navController.graph.startDestinationRoute?.let {
+ popUpTo(it) { saveState = false }
+ }
+ launchSingleTop = true
+ restoreState = false
+ }
+ },
+ icon = { Icon(painterResource(id = item.icon), contentDescription = item.title) },
+ label = { Text(item.title) })
}
}
}
-
-@Composable
-private fun MainNavGraph(navController: NavHostController) {
- val radarRoute = "${Screen.Radar.route}?catNum={catNum}&aosTime={aosTime}"
- val radarArgs = listOf(navArgument("catNum") { defaultValue = 0 }, navArgument("aosTime") { defaultValue = 0L })
- NavHost(navController, startDestination = Screen.Passes.route) {
- composable(Screen.Entries.route) {
- val viewModel = viewModel(EntriesViewModel::class.java, factory = EntriesViewModel.Factory)
- val navToPasses = { navController.navigate(Screen.Passes.route) }
- EntriesScreen(viewModel.uiState.collectAsStateWithLifecycle().value, navToPasses)
- }
- composable(Screen.Passes.route) {
- val viewModel = viewModel(PassesViewModel::class.java, factory = PassesViewModel.Factory)
- val navToRadar = { catNum: Int, aosTime: Long ->
- navController.navigate("${Screen.Radar.route}?catNum=${catNum}&aosTime=${aosTime}")
- }
- PassesScreen(viewModel.uiState.value, navToRadar)
- }
- composable(radarRoute, radarArgs) { RadarScreen() }
- composable(Screen.Map.route) { MapScreen() }
- composable(Screen.Settings.route) { SettingsScreen() }
- composable(Screen.Info.route) { InfoScreen() }
- }
-}
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/MainTheme.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/MainTheme.kt
index b874fc34..45f82645 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/MainTheme.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/MainTheme.kt
@@ -1,6 +1,7 @@
package com.rtbishop.look4sat.presentation
import androidx.activity.ComponentActivity
+import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Shapes
@@ -10,7 +11,6 @@ import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
@@ -20,18 +20,16 @@ import androidx.compose.ui.unit.sp
import androidx.core.view.WindowCompat
@Composable
-fun MainTheme(isLightTheme: Boolean = false, content: @Composable () -> Unit) {
+fun MainTheme(isDarkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
val view = LocalView.current
if (view.isInEditMode) {
MaterialTheme(darkScheme, shapes, typography, content)
} else {
- val colorScheme = if (isLightTheme) lightScheme else darkScheme
+ val colorScheme = if (isDarkTheme) darkScheme else lightScheme
SideEffect {
val window = (view.context as ComponentActivity).window
- window.statusBarColor = colorScheme.background.toArgb()
- window.navigationBarColor = colorScheme.surface.toArgb()
val insetsController = WindowCompat.getInsetsController(window, view)
- insetsController.isAppearanceLightStatusBars = isLightTheme
+ insetsController.isAppearanceLightStatusBars = false
}
MaterialTheme(colorScheme, shapes, typography, content)
}
@@ -57,22 +55,42 @@ private val lightScheme = lightColorScheme(
)
private val darkScheme = darkColorScheme(
- primary = Color(0xFFFFE082),
- onPrimary = Color(0xFF000000),
+ primary = Color(0xFFFFE082), // main accent, switch background, active progress
+ onPrimary = Color(0xFF000000), // on main accent, switch knob
+// primaryContainer = Color(0xFF121212),
+// onPrimaryContainer = Color(0xFF121212),
+// inversePrimary = Color(0xFF121212),
secondary = Color(0xFFE0E0E0),
onSecondary = Color(0xFF000000),
- secondaryContainer = Color(0xFFFFE082), // navBar indicator
- onSecondaryContainer = Color(0xFF000000), // navBar active icon
+ secondaryContainer = Color(0xFF484848), // navBar indicator,
+ onSecondaryContainer = Color(0xFFE0E0E0), // navBar active icon
+// tertiary = Color(0xFF121212),
+// onTertiary = Color(0xFF121212),
+// tertiaryContainer = Color(0xFF121212),
+// onTertiaryContainer = Color(0xFF121212),
background = Color(0xFF121212),
onBackground = Color(0xFFE0E0E0),
- surface = Color(0xFF242424),
- onSurface = Color(0xFFE0E0E0),
- surfaceTint = Color(0x00000000),
+ surface = Color(0xFF242424), // card background
+ onSurface = Color(0xFFE0E0E0), // on card background
surfaceVariant = Color(0xFF484848), // buttons background
onSurfaceVariant = Color(0xFFE0E0E0), // navBar inactive icon
+ surfaceTint = Color(0x00000000),
+// inverseSurface = Color(0xFF121212),
+// inverseOnSurface = Color(0xFF121212),
error = Color(0xFFDC0000),
+// onError = Color(0xFFFFFFFF),
+// errorContainer = Color(0xFF121212),
+// onErrorContainer = Color(0xFF121212),
outline = Color(0xA3E0E0E0),
- scrim = Color(0xFF000000)
+// outlineVariant = Color(0xFF121212),
+ scrim = Color(0xFF000000),
+// surfaceBright = Color(0xFF121212),
+ surfaceContainer = Color(0xFF242424), // navBar background
+// surfaceContainerHigh = Color(0xFF121212),
+ surfaceContainerHighest = Color(0xFF242424), // filled card background
+ surfaceContainerLow = Color(0xFF242424), // elevated card background
+// surfaceContainerLowest = Color(0xFF121212),
+// surfaceDim = Color(0xFF121212),
)
private val shapes = Shapes(
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesDialog.kt
deleted file mode 100644
index 530f3c33..00000000
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesDialog.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.rtbishop.look4sat.presentation.entries
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.lazy.grid.GridCells
-import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
-import androidx.compose.foundation.lazy.grid.itemsIndexed
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.HorizontalDivider
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.ModalBottomSheet
-import androidx.compose.material3.RadioButton
-import androidx.compose.material3.Text
-import androidx.compose.material3.rememberModalBottomSheetState
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.text.style.TextOverflow
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import com.rtbishop.look4sat.presentation.MainTheme
-
-@Preview(showBackground = true)
-@Composable
-private fun TypeDialogPreview() {
- val types = listOf("All", "Amateur", "Geostationary", "Military", "Weather")
- MainTheme { TypesDialog(types, "All", {}) {} }
-}
-
-@OptIn(ExperimentalMaterial3Api::class)
-@Composable
-fun TypesDialog(items: List, selected: String, dismiss: () -> Unit, select: (String) -> Unit) {
- ModalBottomSheet(
- onDismissRequest = { dismiss() },
- sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
- modifier = Modifier.fillMaxHeight(0.80f)
- ) {
- LazyVerticalGrid(
- columns = GridCells.Fixed(1),
- modifier = Modifier.background(MaterialTheme.colorScheme.background),
- horizontalArrangement = Arrangement.spacedBy(1.dp),
- verticalArrangement = Arrangement.spacedBy(1.dp)
- ) {
- item { HorizontalDivider(thickness = 0.dp, color = MaterialTheme.colorScheme.surface) }
- itemsIndexed(items) { index, item ->
- Row(verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier
- .background(MaterialTheme.colorScheme.surface)
- .clickable { select(item) }) {
- Text(
- text = "$index).",
- modifier = Modifier.padding(start = 12.dp, end = 6.dp),
- fontWeight = FontWeight.Normal,
- color = MaterialTheme.colorScheme.primary
- )
- Text(
- text = item,
- modifier = Modifier.weight(1f),
- fontWeight = FontWeight.Medium,
- maxLines = 1,
- overflow = TextOverflow.Ellipsis
- )
- RadioButton(
- selected = item == selected,
- onClick = null,
- modifier = Modifier.padding(start = 8.dp, top = 8.dp, end = 12.dp, bottom = 8.dp)
- )
- }
- }
- item { HorizontalDivider(thickness = 24.dp, color = MaterialTheme.colorScheme.surface) }
- }
- }
-}
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesState.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesState.kt
deleted file mode 100644
index 07db7147..00000000
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesState.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.rtbishop.look4sat.presentation.entries
-
-import com.rtbishop.look4sat.domain.model.SatItem
-
-data class EntriesState(
- val isDialogShown: Boolean,
- val isLoading: Boolean,
- val itemsList: List,
- val currentType: String,
- val typesList: List,
- val takeAction: (EntriesAction) -> Unit
-)
-
-sealed class EntriesAction {
- data object SaveSelection : EntriesAction()
- data class SearchFor(val query: String) : EntriesAction()
- data object SelectAll : EntriesAction()
- data class SelectSingle(val id: Int, val isTicked: Boolean) : EntriesAction()
- data class SelectType(val type: String) : EntriesAction()
- data object ToggleTypesDialog : EntriesAction()
- data object UnselectAll : EntriesAction()
-}
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 f358f6d3..9eb0da64 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
@@ -1,6 +1,5 @@
package com.rtbishop.look4sat.presentation.passes
-import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
@@ -27,7 +26,6 @@ import androidx.compose.ui.Modifier
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.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -80,7 +78,6 @@ fun PassesScreen(uiState: PassesState, navToRadar: (Int, Long) -> Unit) {
}
}
-@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun PassesList(
refreshState: PullRefreshState,
@@ -93,7 +90,7 @@ private fun PassesList(
Box(modifier = Modifier.pullRefresh(refreshState), contentAlignment = Alignment.TopCenter) {
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(items = passes, key = { item -> item.catNum + item.aosTime }) { pass ->
- PassItem(pass = pass, navToRadar = navToRadar, modifier = Modifier.animateItemPlacement())
+ PassItem(pass = pass, navToRadar = navToRadar, modifier = Modifier.animateItem())
}
}
PullRefreshIndicator(refreshing = isRefreshing, state = refreshState, backgroundColor = backgroundColor)
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 9d05c359..c54941da 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
@@ -12,6 +12,7 @@ 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
@@ -34,27 +35,32 @@ fun RadarScreen() {
val currentPass = viewModel.getPass().collectAsState(null).value
val id = currentPass?.catNum ?: 99999
val name = currentPass?.name ?: "Satellite"
- Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
+ Scaffold { innerPadding ->
+ Column(
+ modifier = Modifier.padding(innerPadding),
+ verticalArrangement = Arrangement.spacedBy(6.dp)
+ ) {
// TimerBarNew(id, name, "88:88:88", R.drawable.ic_notifications) {}
- ElevatedCard(
- modifier = Modifier
- .fillMaxSize()
- .weight(1f)
- ) {
- viewModel.radarData.value?.let { data ->
- RadarViewCompose(
- item = data.orbitalPos,
- items = data.satTrack,
- azimElev = viewModel.orientation.value
- )
+ ElevatedCard(
+ modifier = Modifier
+ .fillMaxSize()
+ .weight(1f)
+ ) {
+ viewModel.radarData.value?.let { data ->
+ RadarViewCompose(
+ item = data.orbitalPos,
+ items = data.satTrack,
+ azimElev = viewModel.orientation.value
+ )
+ }
+ }
+ ElevatedCard(
+ modifier = Modifier
+ .fillMaxSize()
+ .weight(1f)
+ ) {
+ TransmittersList(transmitters = viewModel.transmitters.value)
}
- }
- ElevatedCard(
- modifier = Modifier
- .fillMaxSize()
- .weight(1f)
- ) {
- TransmittersList(transmitters = viewModel.transmitters.value)
}
}
}
@@ -78,7 +84,10 @@ private fun TransmitterItem(radio: SatRadio) {
.background(MaterialTheme.colorScheme.surface)
.padding(6.dp)
) {
- Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.fillMaxWidth()
+ ) {
Icon(
painter = painterResource(id = R.drawable.ic_arrow),
contentDescription = null, modifier = Modifier.rotate(180f)
@@ -93,7 +102,10 @@ private fun TransmitterItem(radio: SatRadio) {
contentDescription = null
)
}
- Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.fillMaxWidth()
+ ) {
Text(
text = stringResource(id = R.string.radio_downlink, radio.downlinkLow ?: 0L),
textAlign = TextAlign.Center,
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarView.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarView.kt
index 9eb578fe..8be34fd6 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarView.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarView.kt
@@ -70,66 +70,66 @@ fun RadarViewCompose(item: OrbitalPos, items: List, azimElev: Pair 0) {
- if(item.elevation > 0) {
- soundPool.value?.resume(beepSoundId.intValue)
- } else {
- soundPool.value?.pause(beepSoundId.intValue)
- }
- }
-
- DisposableEffect(Unit) {
- val audioAttributes = AudioAttributes.Builder()
- .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
- .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
- .build()
-
- soundPool.value = SoundPool.Builder()
- .setMaxStreams(1)
- .setAudioAttributes(audioAttributes)
- .build()
-
- beepSoundId.intValue = soundPool.value?.load(context, R.raw.beep, 1) ?: 0
-
- soundPool.value?.setOnLoadCompleteListener { soundPool, _, status ->
- if (status == 0) {
- soundPool.play(beepSoundId.intValue, 0.5f, 0.5f, 0, -1, 1f)
- }
- }
-
- onDispose {
- soundPool.value?.release()
- }
- }
+// LaunchedEffect(item.azimuth, item.elevation, azimElev.first, azimElev.second) {
+// val aimAzimuthRadians = azimElev.first.toDouble().toRadians()
+// val aimElevationRadians = abs(min(azimElev.second, 0f)).toDouble().toRadians()
+// // radius of 0.5 makes the aimTargetDifference range 0.0 to 1.0
+// val radius = 0.5
+// val aimX = sph2CartX(aimAzimuthRadians, aimElevationRadians, radius)
+// val aimY = sph2CartY(aimAzimuthRadians, aimElevationRadians, radius)
+// val satX = sph2CartX(item.azimuth, item.elevation, radius)
+// val satY = sph2CartY(item.azimuth, item.elevation, radius)
+// aimTargetDifference.floatValue = sqrt((satX - aimX).pow(2) + (satY - aimY).pow(2))
+//
+//
+// val minPlaybackRate = 0.5f
+// val maxPlaybackRate = 2.0f
+// val playbackRate =
+// maxPlaybackRate - (aimTargetDifference.floatValue / (maxPlaybackRate - minPlaybackRate))
+//
+// soundPool.value?.setRate(beepSoundId.intValue, playbackRate)
+// }
+//
+// LaunchedEffect(aimTargetDifference.floatValue < aimThreshold) {
+// if (aimTargetDifference.floatValue < aimThreshold) {
+// view.performHapticFeedback(HapticFeedbackConstantsCompat.VIRTUAL_KEY)
+// soundPool.value?.pause(beepSoundId.intValue)
+// } else {
+// soundPool.value?.resume(beepSoundId.intValue)
+// }
+// }
+//
+// LaunchedEffect(item.elevation > 0) {
+// if(item.elevation > 0) {
+// soundPool.value?.resume(beepSoundId.intValue)
+// } else {
+// soundPool.value?.pause(beepSoundId.intValue)
+// }
+// }
+//
+// DisposableEffect(Unit) {
+// val audioAttributes = AudioAttributes.Builder()
+// .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
+// .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+// .build()
+//
+// soundPool.value = SoundPool.Builder()
+// .setMaxStreams(1)
+// .setAudioAttributes(audioAttributes)
+// .build()
+//
+// beepSoundId.intValue = soundPool.value?.load(context, R.raw.beep, 1) ?: 0
+//
+// soundPool.value?.setOnLoadCompleteListener { soundPool, _, status ->
+// if (status == 0) {
+// soundPool.play(beepSoundId.intValue, 0.5f, 0.5f, 0, -1, 1f)
+// }
+// }
+//
+// onDispose {
+// soundPool.value?.release()
+// }
+// }
Canvas(modifier = Modifier.fillMaxSize()) {
val radius = (size.minDimension / 2f) * 0.95f
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesDialog.kt
new file mode 100644
index 00000000..7a11c877
--- /dev/null
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesDialog.kt
@@ -0,0 +1,92 @@
+package com.rtbishop.look4sat.presentation.satellites
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
+import androidx.compose.foundation.lazy.grid.itemsIndexed
+import androidx.compose.material3.ElevatedCard
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.RadioButton
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.compose.ui.window.Dialog
+import com.rtbishop.look4sat.presentation.MainTheme
+
+@Preview(showBackground = true)
+@Composable
+private fun TypeDialogPreview() {
+ val types = listOf("All", "Amateur", "Geostationary", "Military", "Weather")
+ MainTheme { TypesDialog(types, "All", {}) {} }
+}
+
+@Composable
+fun TypesDialog(
+ items: List, selected: String, dismiss: () -> Unit, select: (String) -> Unit
+) {
+ val height = LocalConfiguration.current.screenHeightDp
+ Dialog(onDismissRequest = { dismiss() }) {
+ ElevatedCard {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier.heightIn(max = height.times(0.80).dp)
+ ) {
+ Text(
+ text = "Select category",
+ fontSize = 18.sp,
+ textAlign = TextAlign.Center,
+ color = MaterialTheme.colorScheme.primary,
+ modifier = Modifier.padding(top = 8.dp, bottom = 4.dp)
+ )
+ LazyVerticalGrid(
+ columns = GridCells.Adaptive(240.dp),
+ modifier = Modifier.background(MaterialTheme.colorScheme.background),
+ horizontalArrangement = Arrangement.spacedBy(1.dp),
+ verticalArrangement = Arrangement.spacedBy(1.dp)
+ ) {
+ itemsIndexed(items) { index, item ->
+ Row(verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .background(MaterialTheme.colorScheme.surface)
+ .clickable { select(item) }) {
+ Text(
+ text = "$index).",
+ modifier = Modifier.padding(start = 12.dp, end = 6.dp),
+ fontWeight = FontWeight.Normal,
+ color = MaterialTheme.colorScheme.primary
+ )
+ Text(
+ text = item,
+ modifier = Modifier.weight(1f),
+ fontWeight = FontWeight.Medium,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis
+ )
+ RadioButton(
+ selected = item == selected,
+ onClick = null,
+ modifier = Modifier.padding(
+ start = 8.dp, top = 8.dp, end = 12.dp, bottom = 8.dp
+ )
+ )
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesScreen.kt
similarity index 80%
rename from app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesScreen.kt
rename to app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesScreen.kt
index 8436620b..dc03ebd3 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesScreen.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesScreen.kt
@@ -1,6 +1,5 @@
-package com.rtbishop.look4sat.presentation.entries
+package com.rtbishop.look4sat.presentation.satellites
-import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
@@ -44,29 +43,29 @@ import com.rtbishop.look4sat.presentation.components.CardIcon
import com.rtbishop.look4sat.presentation.components.CardLoadingIndicator
@Composable
-fun EntriesScreen(uiState: EntriesState, navToPasses: () -> Unit) {
- val toggleDialog = { uiState.takeAction(EntriesAction.ToggleTypesDialog) }
+fun SatellitesScreen(uiState: SatellitesState, navToPasses: () -> Unit) {
+ val toggleDialog = { uiState.takeAction(SatellitesAction.ToggleTypesDialog) }
if (uiState.isDialogShown) {
TypesDialog(items = uiState.typesList, selected = uiState.currentType, toggleDialog) {
- uiState.takeAction(EntriesAction.SelectType(it))
+ uiState.takeAction(SatellitesAction.SelectType(it))
}
}
- val unselectAll = { uiState.takeAction(EntriesAction.UnselectAll) }
- val selectAll = { uiState.takeAction(EntriesAction.SelectAll) }
+ 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(EntriesAction.SearchFor(newQuery)) },
- saveSelection = {
- uiState.takeAction(EntriesAction.SaveSelection)
- navToPasses()
- })
+ TopBar(setQuery = { newQuery: String ->
+ uiState.takeAction(SatellitesAction.SearchFor(newQuery))
+ }, saveSelection = {
+ uiState.takeAction(SatellitesAction.SaveSelection)
+ navToPasses()
+ })
MiddleBar(uiState.currentType, { toggleDialog() }, { unselectAll() }, { selectAll() })
ElevatedCard(modifier = Modifier.fillMaxSize()) {
if (uiState.isLoading) {
CardLoadingIndicator()
} else {
- EntriesCard(uiState.itemsList) { id, isTicked ->
- uiState.takeAction(EntriesAction.SelectSingle(id, isTicked))
+ SatellitesCard(uiState.itemsList) { id, isTicked ->
+ uiState.takeAction(SatellitesAction.SelectSingle(id, isTicked))
}
}
}
@@ -105,7 +104,9 @@ private fun SearchBar(setQuery: (String) -> Unit, modifier: Modifier = Modifier)
singleLine = true,
modifier = modifier.padding(start = 12.dp),
textStyle = TextStyle(
- fontSize = 16.sp, fontWeight = FontWeight.Medium, color = MaterialTheme.colorScheme.onSurface
+ fontSize = 16.sp,
+ fontWeight = FontWeight.Medium,
+ color = MaterialTheme.colorScheme.onSurface
),
decorationBox = { innerTextField ->
if (currentQuery.value.isEmpty()) {
@@ -147,14 +148,14 @@ private fun MiddleBarPreview() = MainTheme { MiddleBar("Amateur", {}, {}, {}) }
@Composable
private fun MiddleBar(type: String, navigate: () -> Unit, uncheck: () -> Unit, check: () -> Unit) {
Row(horizontalArrangement = Arrangement.spacedBy(6.dp), modifier = Modifier.height(48.dp)) {
- EntryTypeCard(type = type, { navigate() }, modifier = Modifier.weight(1f))
+ TypeCard(type = type, { navigate() }, modifier = Modifier.weight(1f))
CardIcon(onClick = { uncheck() }, iconId = R.drawable.ic_check_off)
CardIcon(onClick = { check() }, iconId = R.drawable.ic_check_on)
}
}
@Composable
-private fun EntryTypeCard(type: String, onClick: () -> Unit, modifier: Modifier = Modifier) {
+private fun TypeCard(type: String, onClick: () -> Unit, modifier: Modifier = Modifier) {
ElevatedCard(modifier = modifier) {
Row(horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically,
@@ -180,13 +181,13 @@ private fun EntryTypeCard(type: String, onClick: () -> Unit, modifier: Modifier
@Preview(showBackground = true)
@Composable
-private fun EntryPreview() {
+private fun SatellitePreview() {
val satItem = SatItem(44444, "Ultra Super Mega long satellite name", true)
- MainTheme { Entry(item = satItem, onSelected = { _, _ -> run {} }, modifier = Modifier) }
+ MainTheme { Satellite(item = satItem, onSelected = { _, _ -> run {} }, modifier = Modifier) }
}
@Composable
-private fun Entry(item: SatItem, onSelected: (Int, Boolean) -> Unit, modifier: Modifier) {
+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,
modifier = modifier.clickable { onSelected(item.catnum, item.isSelected) }) {
@@ -198,8 +199,7 @@ private fun Entry(item: SatItem, onSelected: (Int, Boolean) -> Unit, modifier: M
.padding(start = 14.dp, top = 8.dp, end = 12.dp, bottom = 8.dp)
) {
Text(
- text = "$passSatId - ",
- color = MaterialTheme.colorScheme.primary
+ text = "$passSatId - ", color = MaterialTheme.colorScheme.primary
)
Text(
text = item.name,
@@ -208,7 +208,11 @@ private fun Entry(item: SatItem, onSelected: (Int, Boolean) -> Unit, modifier: M
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
- Checkbox(checked = item.isSelected, onCheckedChange = null, modifier = Modifier.padding(start = 6.dp))
+ Checkbox(
+ checked = item.isSelected,
+ onCheckedChange = null,
+ modifier = Modifier.padding(start = 6.dp)
+ )
}
}
}
@@ -216,21 +220,20 @@ private fun Entry(item: SatItem, onSelected: (Int, Boolean) -> Unit, modifier: M
@Preview(showBackground = true)
@Composable
-private fun EntriesPreview() {
+private fun SatellitesPreview() {
val entries = listOf(
SatItem(8888, "Meteor", false),
SatItem(44444, "ISS", true),
SatItem(88888, "Starlink", false)
)
- MainTheme { EntriesCard(entries) { _, _ -> run {} } }
+ MainTheme { SatellitesCard(entries) { _, _ -> run {} } }
}
-@OptIn(ExperimentalFoundationApi::class)
@Composable
-fun EntriesCard(items: List, onSelected: (Int, Boolean) -> Unit) {
+fun SatellitesCard(items: List, onSelected: (Int, Boolean) -> Unit) {
LazyColumn {
items(items = items, key = { item -> item.catnum }) { entry ->
- Entry(entry, onSelected, Modifier.animateItemPlacement())
+ Satellite(entry, onSelected, Modifier.animateItem())
}
}
}
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesState.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesState.kt
new file mode 100644
index 00000000..0661b5d8
--- /dev/null
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesState.kt
@@ -0,0 +1,22 @@
+package com.rtbishop.look4sat.presentation.satellites
+
+import com.rtbishop.look4sat.domain.model.SatItem
+
+data class SatellitesState(
+ val isDialogShown: Boolean,
+ val isLoading: Boolean,
+ val itemsList: List,
+ val currentType: String,
+ val typesList: List,
+ val takeAction: (SatellitesAction) -> Unit
+)
+
+sealed class SatellitesAction {
+ data object SaveSelection : SatellitesAction()
+ data class SearchFor(val query: String) : SatellitesAction()
+ data object SelectAll : SatellitesAction()
+ data class SelectSingle(val id: Int, val isTicked: Boolean) : SatellitesAction()
+ data class SelectType(val type: String) : SatellitesAction()
+ data object ToggleTypesDialog : SatellitesAction()
+ data object UnselectAll : SatellitesAction()
+}
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesViewModel.kt
similarity index 79%
rename from app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesViewModel.kt
rename to app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesViewModel.kt
index 618c4083..317b5747 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesViewModel.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/satellites/SatellitesViewModel.kt
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package com.rtbishop.look4sat.presentation.entries
+package com.rtbishop.look4sat.presentation.satellites
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
@@ -29,11 +29,11 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
-class EntriesViewModel(private val selectionRepo: ISelectionRepo) : ViewModel() {
+class SatellitesViewModel(private val selectionRepo: ISelectionRepo) : ViewModel() {
private val defaultType = "All"
private val _uiState = MutableStateFlow(
- EntriesState(
+ SatellitesState(
isDialogShown = false,
isLoading = true,
itemsList = emptyList(),
@@ -42,7 +42,7 @@ class EntriesViewModel(private val selectionRepo: ISelectionRepo) : ViewModel()
takeAction = ::handleAction
)
)
- val uiState: StateFlow = _uiState
+ val uiState: StateFlow = _uiState
init {
viewModelScope.launch {
@@ -54,15 +54,15 @@ class EntriesViewModel(private val selectionRepo: ISelectionRepo) : ViewModel()
}
}
- private fun handleAction(action: EntriesAction) {
+ private fun handleAction(action: SatellitesAction) {
when (action) {
- EntriesAction.SaveSelection -> saveSelection()
- is EntriesAction.SearchFor -> searchFor(action.query)
- EntriesAction.SelectAll -> selectAll(true)
- is EntriesAction.SelectSingle -> selectSingle(action.id, action.isTicked)
- is EntriesAction.SelectType -> selectType(action.type)
- EntriesAction.ToggleTypesDialog -> toggleTypesDialog()
- EntriesAction.UnselectAll -> selectAll(false)
+ SatellitesAction.SaveSelection -> saveSelection()
+ is SatellitesAction.SearchFor -> searchFor(action.query)
+ SatellitesAction.SelectAll -> selectAll(true)
+ is SatellitesAction.SelectSingle -> selectSingle(action.id, action.isTicked)
+ is SatellitesAction.SelectType -> selectType(action.type)
+ SatellitesAction.ToggleTypesDialog -> toggleTypesDialog()
+ SatellitesAction.UnselectAll -> selectAll(false)
}
}
@@ -93,7 +93,7 @@ class EntriesViewModel(private val selectionRepo: ISelectionRepo) : ViewModel()
val applicationKey = ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY
initializer {
val container = (this[applicationKey] as MainApplication).container
- EntriesViewModel(container.selectionRepo)
+ SatellitesViewModel(container.selectionRepo)
}
}
}
diff --git a/app/src/main/res/drawable/ic_world_map.xml b/app/src/main/res/drawable/ic_map.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_world_map.xml
rename to app/src/main/res/drawable/ic_map.xml
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 98fe171e..c73371e0 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,20 +1,12 @@
-
+
#FFE082
#121212
-
-
diff --git a/data/src/main/java/com/rtbishop/look4sat/data/source/RemoteSource.kt b/data/src/main/java/com/rtbishop/look4sat/data/source/RemoteSource.kt
index f2d097c2..1993ed0d 100644
--- a/data/src/main/java/com/rtbishop/look4sat/data/source/RemoteSource.kt
+++ b/data/src/main/java/com/rtbishop/look4sat/data/source/RemoteSource.kt
@@ -27,9 +27,9 @@ import okhttp3.OkHttpClient
import okhttp3.Request
class RemoteSource(
+ private val dispatcher: CoroutineDispatcher,
private val contentResolver: ContentResolver,
- private val httpClient: OkHttpClient,
- private val dispatcher: CoroutineDispatcher
+ private val httpClient: OkHttpClient
) : IRemoteSource {
override suspend fun getFileStream(uri: String): InputStream? = withContext(dispatcher) {
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 1bc8b421..6ee70ef0 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,16 +1,16 @@
[versions]
-android-gradle-plugin = "8.7.1"
+android-gradle-plugin = "8.7.2"
google-ksp = "2.0.20-1.0.25"
kotlin = "2.0.21"
-androidx-core-ktx = "1.13.1"
+androidx-core-ktx = "1.15.0"
androidx-core-splashscreen = "1.0.1"
androidx-room = "2.6.1"
-composeBom = "2024.10.00"
+composeBom = "2024.10.01"
compose-activity = "1.9.3"
-compose-lifecycle = "2.8.6"
-compose-material3 = "1.3.0"
+compose-lifecycle = "2.8.7"
+compose-material3 = "1.3.1"
compose-navigation = "2.8.3"
other-coroutines = "1.9.0"