Updated dependencies and gradle plugin, minor fixes

This commit is contained in:
Arty Bishop committed 2025-12-27 15:01:46 +00:00
1 parent f1c978d167
commit 5aa837e5ef
31 files changed
+402 -610

No files matched your search

+4 -8
View File
@@ -1,10 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.VIBRATE" />
<application <application
android:name=".MainApplication" android:name=".MainApplication"
@@ -12,15 +11,12 @@
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/Theme.Look4Sat.Main" android:theme="@style/Theme.Look4Sat.Main">
tools:targetApi="33">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:screenOrientation="portrait" android:theme="@style/Theme.Look4Sat.SplashScreen">
android:theme="@style/Theme.Look4Sat.SplashScreen"
tools:ignore="LockedOrientationActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
@@ -17,30 +17,24 @@
*/ */
package com.rtbishop.look4sat package com.rtbishop.look4sat
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.util.DisplayMetrics
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.platform.LocalContext
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import com.rtbishop.look4sat.presentation.MainScreen import com.rtbishop.look4sat.presentation.MainScreen
import com.rtbishop.look4sat.presentation.theme.MainTheme import com.rtbishop.look4sat.presentation.MainTheme
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen() installSplashScreen()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContent { MainTheme { MainScreen() } } setContent {
} val container = (LocalContext.current.applicationContext as MainApplication).container
val otherSettings = container.settingsRepo.otherSettings.collectAsState().value
override fun attachBaseContext(newBase: Context?) { MainTheme(isLightTheme = otherSettings.stateOfLightTheme) { MainScreen() }
val newConfig = Configuration(newBase?.resources?.configuration).apply {
densityDpi = DisplayMetrics.DENSITY_DEVICE_STABLE
fontScale = 1.0f
} }
applyOverrideConfiguration(newConfig)
super.attachBaseContext(newBase)
} }
} }
@@ -18,10 +18,6 @@
package com.rtbishop.look4sat package com.rtbishop.look4sat
import android.app.Application import android.app.Application
import android.content.pm.ApplicationInfo
import android.os.StrictMode
import android.os.StrictMode.ThreadPolicy
import android.os.StrictMode.VmPolicy
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
@@ -32,7 +28,6 @@ class MainApplication : Application() {
lateinit var container: MainContainer lateinit var container: MainContainer
override fun onCreate() { override fun onCreate() {
enableStrictMode()
super.onCreate() super.onCreate()
container = MainContainer(this) container = MainContainer(this)
// trigger automatic update every 48 hours // trigger automatic update every 48 hours
@@ -53,14 +48,6 @@ class MainApplication : Application() {
} }
} }
private fun enableStrictMode() {
val isDebuggable = 0 != applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE
if (isDebuggable) {
StrictMode.setThreadPolicy(ThreadPolicy.Builder().detectAll().penaltyLog().build())
StrictMode.setVmPolicy(VmPolicy.Builder().detectAll().penaltyLog().build())
}
}
companion object { companion object {
private const val AUTO_UPDATE_DELTA_MS = 172_800_000L // 48 hours in ms 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 const val MAX_OKHTTP_CACHE_SIZE = 10_000_000L // 10 Megabytes
@@ -49,7 +49,7 @@ fun MainScreen(navController: NavHostController = rememberNavController()) {
@Composable @Composable
private fun MainNavBar(navController: NavController) { private fun MainNavBar(navController: NavController) {
val items = listOf(Screen.Entries, Screen.Passes, Screen.Map, Screen.Settings, Screen.Info) val items = listOf(Screen.Entries, Screen.Passes, Screen.Map, Screen.Settings, Screen.Info)
NavigationBar(modifier = Modifier.height(48.dp)) { NavigationBar(modifier = Modifier.height(48.dp), tonalElevation = 0.dp) {
val navBackStackEntry = navController.currentBackStackEntryAsState() val navBackStackEntry = navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry.value?.destination?.route val currentRoute = navBackStackEntry.value?.destination?.route
items.forEach { screen -> items.forEach { screen ->
@@ -0,0 +1,106 @@
package com.rtbishop.look4sat.presentation
import androidx.activity.ComponentActivity
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Shapes
import androidx.compose.material3.Typography
import androidx.compose.material3.darkColorScheme
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
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.view.WindowCompat
@Composable
fun MainTheme(isLightTheme: Boolean = false, content: @Composable () -> Unit) {
val view = LocalView.current
if (view.isInEditMode) {
MaterialTheme(darkScheme, shapes, typography, content)
} else {
val colorScheme = if (isLightTheme) lightScheme else darkScheme
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
}
MaterialTheme(colorScheme, shapes, typography, content)
}
}
private val lightScheme = lightColorScheme(
primary = Color(0xFF715C0C),
onPrimary = Color(0xFFFFFFFF),
secondary = Color(0xFF685E40),
onSecondary = Color(0xFFFFFFFF),
secondaryContainer = Color(0xFFF1E1BB),
onSecondaryContainer = Color(0xFF221B04),
background = Color(0xFFFFF8F0),
onBackground = Color(0xFF1E1B13),
surface = Color(0xFFFFF8F0),
onSurface = Color(0xFF1E1B13),
surfaceTint = Color(0x00000000),
surfaceVariant = Color(0xFFEBE2CF),
onSurfaceVariant = Color(0xFF4C4639),
error = Color(0xFFDC0000),
outline = Color(0xFF7D7667),
scrim = Color(0xFF000000)
)
private val darkScheme = darkColorScheme(
primary = Color(0xFFFFE082),
onPrimary = Color(0xFF000000),
secondary = Color(0xFFE0E0E0),
onSecondary = Color(0xFF000000),
secondaryContainer = Color(0xFFFFE082), // navBar indicator
onSecondaryContainer = Color(0xFF000000), // navBar active icon
background = Color(0xFF121212),
onBackground = Color(0xFFE0E0E0),
surface = Color(0xFF242424),
onSurface = Color(0xFFE0E0E0),
surfaceTint = Color(0x00000000),
surfaceVariant = Color(0xFF484848), // buttons background
onSurfaceVariant = Color(0xFFE0E0E0), // navBar inactive icon
error = Color(0xFFDC0000),
outline = Color(0xA3E0E0E0),
scrim = Color(0xFF000000)
)
private val shapes = Shapes(
extraSmall = RoundedCornerShape(4.dp), // menus, snackbars, text fields
small = RoundedCornerShape(6.dp), // buttons, chips
medium = RoundedCornerShape(8.dp), // cards, small FABs
large = RoundedCornerShape(12.dp), // extended FABs, FABs, nav drawers
extraLarge = RoundedCornerShape(16.dp) // large FABs
)
private val typography = Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
), titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
), labelSmall = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Medium,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
)
@@ -11,11 +11,13 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
@@ -41,7 +43,7 @@ import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.domain.predict.NearEarthObject 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.theme.MainTheme import com.rtbishop.look4sat.presentation.MainTheme
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
@@ -126,9 +128,9 @@ fun NextPassRow(pass: OrbitalPass) {
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp)
) )
Spacer(modifier = Modifier.width(4.dp))
Text( Text(
text = " ${pass.maxElevation}°", text = "${pass.maxElevation}°",
textAlign = TextAlign.End,
color = MaterialTheme.colorScheme.primary color = MaterialTheme.colorScheme.primary
) )
} }
@@ -137,21 +139,26 @@ fun NextPassRow(pass: OrbitalPass) {
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text(
text = sdfTime.format(Date(pass.aosTime)),
textAlign = TextAlign.Start,
fontSize = 15.sp,
modifier = Modifier.weight(1f)
)
Text(
text = stringResource(id = R.string.pass_aosLos, pass.aosAzimuth.toInt(), pass.losAzimuth.toInt()),
textAlign = TextAlign.Center,
fontSize = 15.sp,
modifier = Modifier.weight(1.5f)
)
Row( Row(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.End, 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,
modifier = Modifier.weight(1f)
)
}
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Icon( Icon(
@@ -159,9 +166,29 @@ fun NextPassRow(pass: OrbitalPass) {
contentDescription = null, contentDescription = null,
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp)
) )
Spacer(modifier = Modifier.width(4.dp))
Text( Text(
text = " ${pass.altitude} km", text = "${pass.altitude} km",
textAlign = TextAlign.Start, fontSize = 15.sp
)
}
Row(
modifier = Modifier.weight(1f),
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,
pass.aosAzimuth.toInt(),
pass.losAzimuth.toInt()
),
fontSize = 15.sp fontSize = 15.sp
) )
} }
@@ -174,8 +201,8 @@ fun NextPassRow(pass: OrbitalPass) {
fun CardButton(onClick: () -> Unit, text: String, modifier: Modifier = Modifier) { fun CardButton(onClick: () -> Unit, text: String, modifier: Modifier = Modifier) {
ElevatedButton( ElevatedButton(
onClick = { onClick() }, colors = ButtonDefaults.buttonColors( onClick = { onClick() }, colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.tertiary, containerColor = MaterialTheme.colorScheme.surfaceVariant,
contentColor = MaterialTheme.colorScheme.onTertiary contentColor = MaterialTheme.colorScheme.onSurfaceVariant
), shape = MaterialTheme.shapes.small, modifier = modifier ), shape = MaterialTheme.shapes.small, modifier = modifier
) { Text(text = text, fontSize = 17.sp) } ) { Text(text = text, fontSize = 17.sp) }
} }
@@ -23,7 +23,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.rtbishop.look4sat.presentation.theme.MainTheme import com.rtbishop.look4sat.presentation.MainTheme
@Preview(showBackground = true) @Preview(showBackground = true)
@Composable @Composable
@@ -56,7 +56,7 @@ fun TypesDialog(items: List<String>, selected: String, dismiss: () -> Unit, sele
text = "$index).", text = "$index).",
modifier = Modifier.padding(start = 12.dp, end = 6.dp), modifier = Modifier.padding(start = 12.dp, end = 6.dp),
fontWeight = FontWeight.Normal, fontWeight = FontWeight.Normal,
color = MaterialTheme.colorScheme.secondary color = MaterialTheme.colorScheme.primary
) )
Text( Text(
text = item, text = item,
@@ -39,7 +39,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.rtbishop.look4sat.R import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.domain.model.SatItem import com.rtbishop.look4sat.domain.model.SatItem
import com.rtbishop.look4sat.presentation.theme.MainTheme import com.rtbishop.look4sat.presentation.MainTheme
import com.rtbishop.look4sat.presentation.components.CardIcon import com.rtbishop.look4sat.presentation.components.CardIcon
import com.rtbishop.look4sat.presentation.components.CardLoadingIndicator import com.rtbishop.look4sat.presentation.components.CardLoadingIndicator
@@ -199,7 +199,7 @@ private fun Entry(item: SatItem, onSelected: (Int, Boolean) -> Unit, modifier: M
) { ) {
Text( Text(
text = "$passSatId - ", text = "$passSatId - ",
color = MaterialTheme.colorScheme.secondary color = MaterialTheme.colorScheme.primary
) )
Text( Text(
text = item.name, text = item.name,
@@ -22,7 +22,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.rtbishop.look4sat.R import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.presentation.theme.MainTheme import com.rtbishop.look4sat.presentation.MainTheme
import com.rtbishop.look4sat.presentation.components.CardButton import com.rtbishop.look4sat.presentation.components.CardButton
import com.rtbishop.look4sat.presentation.components.gotoUrl import com.rtbishop.look4sat.presentation.components.gotoUrl
@@ -52,7 +52,7 @@ private fun CardCredits(modifier: Modifier = Modifier) {
text = stringResource(id = R.string.outro_title), text = stringResource(id = R.string.outro_title),
fontSize = 18.sp, fontSize = 18.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.secondary, color = MaterialTheme.colorScheme.primary,
modifier = modifier.padding(6.dp) modifier = modifier.padding(6.dp)
) )
Text( Text(
@@ -64,7 +64,7 @@ private fun CardCredits(modifier: Modifier = Modifier) {
text = stringResource(id = R.string.outro_license), text = stringResource(id = R.string.outro_license),
fontSize = 18.sp, fontSize = 18.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.secondary, color = MaterialTheme.colorScheme.primary,
modifier = modifier.padding(6.dp) modifier = modifier.padding(6.dp)
) )
Row(horizontalArrangement = Arrangement.SpaceEvenly) { Row(horizontalArrangement = Arrangement.SpaceEvenly) {
@@ -9,7 +9,6 @@ import android.graphics.Paint
import android.graphics.Rect import android.graphics.Rect
import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@@ -32,7 +31,6 @@ import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.domain.predict.GeoPos import com.rtbishop.look4sat.domain.predict.GeoPos
import com.rtbishop.look4sat.domain.predict.OrbitalObject import com.rtbishop.look4sat.domain.predict.OrbitalObject
import com.rtbishop.look4sat.domain.predict.OrbitalPos import com.rtbishop.look4sat.domain.predict.OrbitalPos
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.util.GeoPoint import org.osmdroid.util.GeoPoint
import org.osmdroid.views.CustomZoomButtonsController import org.osmdroid.views.CustomZoomButtonsController
import org.osmdroid.views.MapView import org.osmdroid.views.MapView
@@ -73,7 +71,7 @@ fun MapScreen() {
val positionClick = { orbitalObject: OrbitalObject -> viewModel.selectSatellite(orbitalObject) } val positionClick = { orbitalObject: OrbitalObject -> viewModel.selectSatellite(orbitalObject) }
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) { Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
ElevatedCard(modifier = Modifier.fillMaxSize()) { ElevatedCard(modifier = Modifier.fillMaxSize()) {
MapView(modifier = Modifier.fillMaxSize()) { mapView -> MapView(modifier = Modifier.fillMaxSize(), isLightTheme = viewModel.stateOfLightTheme) { mapView ->
stationPos.value?.let { setStationPosition(it, mapView) } stationPos.value?.let { setStationPosition(it, mapView) }
positions.value?.let { setPositions(it, mapView, positionClick) } positions.value?.let { setPositions(it, mapView, positionClick) }
satTrack.value?.let { setSatelliteTrack(it, mapView) } satTrack.value?.let { setSatelliteTrack(it, mapView) }
@@ -98,7 +96,11 @@ private fun setStationPosition(stationPos: GeoPos, mapView: MapView) {
} }
} }
private fun setPositions(posMap: Map<OrbitalObject, GeoPos>, mapView: MapView, action: (OrbitalObject) -> Unit) { private fun setPositions(
posMap: Map<OrbitalObject, GeoPos>,
mapView: MapView,
action: (OrbitalObject) -> Unit
) {
val markers = FolderOverlay() val markers = FolderOverlay()
try { try {
posMap.entries.forEach { posMap.entries.forEach {
@@ -195,24 +197,27 @@ private fun setFootprint(orbitalPos: OrbitalPos, mapView: MapView) {
//} //}
@Composable @Composable
private fun MapView(modifier: Modifier = Modifier, update: ((map: MapView) -> Unit)? = null) { private fun MapView(
val mapView = rememberMapViewWithLifecycle() modifier: Modifier = Modifier,
isLightTheme: Boolean,
update: ((map: MapView) -> Unit)? = null
) {
val mapView = rememberMapViewWithLifecycle(isLightTheme)
AndroidView({ mapView }, modifier) { update?.invoke(it) } AndroidView({ mapView }, modifier) { update?.invoke(it) }
} }
@Composable @Composable
private fun rememberMapViewWithLifecycle(): MapView { private fun rememberMapViewWithLifecycle(isLightTheme: Boolean): MapView {
val context = LocalContext.current val context = LocalContext.current
val mapView = remember { MapView(context) }.apply { val mapView = remember { MapView(context) }.apply {
setMultiTouchControls(true) setMultiTouchControls(true)
setTileSource(TileSourceFactory.WIKIMEDIA)
minZoomLevel = getMinZoom(resources.displayMetrics.heightPixels) + 0.25 minZoomLevel = getMinZoom(resources.displayMetrics.heightPixels) + 0.25
maxZoomLevel = 5.99 maxZoomLevel = 5.99
controller.setZoom(minZoomLevel + 0.5) controller.setZoom(minZoomLevel + 0.5)
zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER) zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
overlayManager.tilesOverlay.loadingBackgroundColor = Color.TRANSPARENT overlayManager.tilesOverlay.loadingBackgroundColor = Color.TRANSPARENT
overlayManager.tilesOverlay.loadingLineColor = Color.TRANSPARENT overlayManager.tilesOverlay.loadingLineColor = Color.TRANSPARENT
overlayManager.tilesOverlay.setColorFilter(getColorFilter()) overlayManager.tilesOverlay.setColorFilter(getColorFilter(isLightTheme))
setScrollableAreaLimitLatitude(maxLat, minLat, 0) setScrollableAreaLimitLatitude(maxLat, minLat, 0)
// add overlays: 0 - GSP, 1 - SatTrack, 2 - SatFootprint, 3 - SatIcons // add overlays: 0 - GSP, 1 - SatTrack, 2 - SatFootprint, 3 - SatIcons
overlays.addAll(Array(4) { FolderOverlay() }) overlays.addAll(Array(4) { FolderOverlay() })
@@ -239,17 +244,13 @@ private fun rememberMapViewLifecycleObserver(mapView: MapView) = remember(mapVie
} }
@Composable @Composable
private fun getColorFilter(): ColorMatrixColorFilter { private fun getColorFilter(isLightTheme: Boolean): ColorMatrixColorFilter {
val viewModel = viewModel(MapViewModel::class.java, factory = MapViewModel.Factory) val grayScale = ColorMatrix().apply { setSaturation(0f) }
val grayScaleMatrix = ColorMatrix().apply { setSaturation(0f) } val negative = ColorMatrix(
val negativeMatrix = ColorMatrix(
floatArrayOf(-1f, 0f, 0f, 0f, 260f, 0f, -1f, 0f, 0f, 260f, 0f, 0f, -1f, 0f, 260f, 0f, 0f, 0f, 1f, 0f) floatArrayOf(-1f, 0f, 0f, 0f, 260f, 0f, -1f, 0f, 0f, 260f, 0f, 0f, -1f, 0f, 260f, 0f, 0f, 0f, 1f, 0f)
) )
negativeMatrix.preConcat(grayScaleMatrix) negative.preConcat(grayScale)
return when { return if (isLightTheme) ColorMatrixColorFilter(grayScale) else ColorMatrixColorFilter(negative)
isSystemInDarkTheme() || viewModel.stateOfOldScheme -> ColorMatrixColorFilter(negativeMatrix)
else -> ColorMatrixColorFilter(grayScaleMatrix)
}
} }
private fun getMinZoom(screenHeight: Int): Double { private fun getMinZoom(screenHeight: Int): Double {
@@ -53,7 +53,7 @@ class MapViewModel(private val satelliteRepo: ISatelliteRepo, settingsRepo: ISet
private var dataUpdateRate = 1000L private var dataUpdateRate = 1000L
private var selectedOrbitalObject: OrbitalObject? = null private var selectedOrbitalObject: OrbitalObject? = null
val stateOfOldScheme = settingsRepo.otherSettings.value.stateOfOldScheme val stateOfLightTheme = settingsRepo.otherSettings.value.stateOfLightTheme
val stationPosition = flow { val stationPosition = flow {
val osmLat = clipLat(stationPos.latitude) val osmLat = clipLat(stationPos.latitude)
@@ -56,7 +56,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.rtbishop.look4sat.R import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.presentation.theme.MainTheme import com.rtbishop.look4sat.presentation.MainTheme
import com.rtbishop.look4sat.presentation.components.CardButton import com.rtbishop.look4sat.presentation.components.CardButton
private val allModes = listOf( private val allModes = listOf(
@@ -206,7 +206,7 @@ fun RadiosDialog(modes: List<String>, dismiss: () -> Unit, save: (List<String>)
text = "$index).", text = "$index).",
modifier = Modifier.padding(start = 8.dp, end = 6.dp), modifier = Modifier.padding(start = 8.dp, end = 6.dp),
fontWeight = FontWeight.Normal, fontWeight = FontWeight.Normal,
color = MaterialTheme.colorScheme.secondary color = MaterialTheme.colorScheme.primary
) )
Text( Text(
text = item, text = item,
@@ -7,10 +7,12 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material3.ElevatedCard import androidx.compose.material3.ElevatedCard
@@ -35,7 +37,7 @@ import com.rtbishop.look4sat.domain.predict.DeepSpaceObject
import com.rtbishop.look4sat.domain.predict.NearEarthObject 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.theme.MainTheme import com.rtbishop.look4sat.presentation.MainTheme
import com.rtbishop.look4sat.presentation.components.CardIcon import com.rtbishop.look4sat.presentation.components.CardIcon
import com.rtbishop.look4sat.presentation.components.NextPassRow import com.rtbishop.look4sat.presentation.components.NextPassRow
import com.rtbishop.look4sat.presentation.components.PullRefreshIndicator import com.rtbishop.look4sat.presentation.components.PullRefreshIndicator
@@ -48,7 +50,7 @@ import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale 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)
@Composable @Composable
@@ -155,9 +157,9 @@ private fun PassItem(pass: OrbitalPass, navToRadar: (Int, Long) -> Unit, modifie
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp)
) )
Spacer(modifier = Modifier.width(4.dp))
Text( Text(
text = " ${pass.maxElevation}°", text = "${pass.maxElevation}°",
textAlign = TextAlign.End,
color = MaterialTheme.colorScheme.primary color = MaterialTheme.colorScheme.primary
) )
} }
@@ -166,25 +168,25 @@ private fun PassItem(pass: OrbitalPass, navToRadar: (Int, Long) -> Unit, modifie
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text(
text = sdfDate.format(Date(pass.aosTime)),
textAlign = TextAlign.Start,
fontSize = 15.sp,
modifier = Modifier.weight(1f)
)
Text(
text = stringResource(
id = R.string.pass_aosLos,
pass.aosAzimuth.toInt(),
pass.losAzimuth.toInt()
),
textAlign = TextAlign.Center,
fontSize = 15.sp,
modifier = Modifier.weight(1.5f)
)
Row( Row(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.End, 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
)
}
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Icon( Icon(
@@ -192,9 +194,29 @@ private fun PassItem(pass: OrbitalPass, navToRadar: (Int, Long) -> Unit, modifie
contentDescription = null, contentDescription = null,
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp)
) )
Spacer(modifier = Modifier.width(4.dp))
Text( Text(
text = " ${pass.altitude} km", text = "${pass.altitude} km",
textAlign = TextAlign.Start, fontSize = 15.sp
)
}
Row(
modifier = Modifier.weight(1f),
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,
pass.aosAzimuth.toInt(),
pass.losAzimuth.toInt()
),
fontSize = 15.sp fontSize = 15.sp
) )
} }
@@ -211,11 +233,7 @@ private fun PassItem(pass: OrbitalPass, navToRadar: (Int, Long) -> Unit, modifie
) )
LinearProgressIndicator( LinearProgressIndicator(
progress = { if (pass.isDeepSpace) 100f else pass.progress }, progress = { if (pass.isDeepSpace) 100f else pass.progress },
modifier = modifier modifier = modifier.fillMaxWidth(0.75f)
.fillMaxWidth(0.75f)
.padding(top = 2.dp),
color = MaterialTheme.colorScheme.primary,
trackColor = MaterialTheme.colorScheme.secondaryContainer
) )
Text( Text(
text = if (pass.isDeepSpace) defaultTime else sdfTime.format(Date(pass.losTime)), text = if (pass.isDeepSpace) defaultTime else sdfTime.format(Date(pass.losTime)),
@@ -1,5 +1,7 @@
package com.rtbishop.look4sat.presentation.radar package com.rtbishop.look4sat.presentation.radar
import android.media.AudioAttributes
import android.media.SoundPool
import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.animation.core.rememberInfiniteTransition
@@ -8,7 +10,10 @@ import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -25,33 +30,107 @@ import androidx.compose.ui.graphics.drawscope.Fill
import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.drawscope.rotate import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.graphics.drawscope.translate import androidx.compose.ui.graphics.drawscope.translate
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.TextMeasurer import androidx.compose.ui.text.TextMeasurer
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.drawText import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.core.view.HapticFeedbackConstantsCompat
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.domain.predict.OrbitalPos import com.rtbishop.look4sat.domain.predict.OrbitalPos
import com.rtbishop.look4sat.domain.predict.PI_2 import com.rtbishop.look4sat.domain.predict.PI_2
import com.rtbishop.look4sat.domain.utility.toRadians import com.rtbishop.look4sat.domain.utility.toRadians
import kotlin.math.abs
import kotlin.math.cos import kotlin.math.cos
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.sin import kotlin.math.sin
import kotlin.math.sqrt
@Composable @Composable
fun RadarViewCompose(item: OrbitalPos, items: List<OrbitalPos>, azimElev: Pair<Float, Float>) { fun RadarViewCompose(item: OrbitalPos, items: List<OrbitalPos>, azimElev: Pair<Float, Float>) {
val viewModel = viewModel(RadarViewModel::class.java, factory = RadarViewModel.Factory) val context = LocalContext.current
val radarColor: Color = if (viewModel.stateOfOldScheme) Color(0xFFDCDCDC) else MaterialTheme.colorScheme.tertiary val view = LocalView.current
val primaryColor: Color = if (viewModel.stateOfOldScheme) Color(0xFFFFE082) else MaterialTheme.colorScheme.primary val radarColor = MaterialTheme.colorScheme.secondary
val secondaryColor: Color = if (viewModel.stateOfOldScheme) Color(0xFFDC0000) else MaterialTheme.colorScheme.onSurface val trackColor = MaterialTheme.colorScheme.primary
val aimColor = MaterialTheme.colorScheme.error
val strokeWidth = 4f val strokeWidth = 4f
val animTransition = rememberInfiniteTransition(label = "animScale") val animTransition = rememberInfiniteTransition(label = "animScale")
val animSpec = infiniteRepeatable<Float>(tween(1000)) val animSpec = infiniteRepeatable<Float>(tween(1000))
val animScale = animTransition.animateFloat(16f, 64f, animSpec, label = "animScale") val animScale = animTransition.animateFloat(16f, 64f, animSpec, label = "animScale")
val aimThreshold = 0.05f
val measurer = rememberTextMeasurer() val measurer = rememberTextMeasurer()
val sweepDegrees = remember { mutableFloatStateOf(0f) } val sweepDegrees = remember { mutableFloatStateOf(0f) }
val trackCreated = remember { mutableStateOf(false) } val trackCreated = remember { mutableStateOf(false) }
val trackPath = remember { mutableStateOf(Path()) } val trackPath = remember { mutableStateOf(Path()) }
val trackEffect = remember { mutableStateOf(PathEffect.cornerPathEffect(0f)) } val trackEffect = remember { mutableStateOf(PathEffect.cornerPathEffect(0f)) }
val soundPool = remember { mutableStateOf<SoundPool?>(null) }
val beepSoundId = remember { mutableIntStateOf(0) }
val aimTargetDifference = remember { mutableFloatStateOf(0f) }
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()) { Canvas(modifier = Modifier.fillMaxSize()) {
val radius = (size.minDimension / 2f) * 0.95f val radius = (size.minDimension / 2f) * 0.95f
if (!trackCreated.value) { if (!trackCreated.value) {
@@ -60,13 +139,13 @@ fun RadarViewCompose(item: OrbitalPos, items: List<OrbitalPos>, azimElev: Pair<F
trackCreated.value = true trackCreated.value = true
} }
rotate(-azimElev.first) { rotate(-azimElev.first) {
drawSweep(center, sweepDegrees.floatValue, radius, primaryColor) drawSweep(center, sweepDegrees.floatValue, radius, trackColor)
drawRadar(radius, radarColor, strokeWidth, 3) drawRadar(radius, radarColor, strokeWidth, 3)
drawInfo(radius, primaryColor, measurer, 3) drawInfo(radius, trackColor, measurer, 3)
translate(center.x, center.y) { translate(center.x, center.y) {
drawTrack(trackPath.value, trackEffect.value, secondaryColor, primaryColor) drawTrack(trackPath.value, trackEffect.value, aimColor, trackColor)
if (item.elevation > 0) drawPosition(item, radius, animScale.value, primaryColor) if (item.elevation > 0) drawPosition(item, radius, animScale.value, trackColor)
drawAim(azimElev.first, azimElev.second, radius, strokeWidth, secondaryColor) drawAim(azimElev.first, azimElev.second, radius, strokeWidth, aimColor)
} }
sweepDegrees.floatValue = (sweepDegrees.floatValue + 360 / 12.0f / 60) % 360 sweepDegrees.floatValue = (sweepDegrees.floatValue + 360 / 12.0f / 60) % 360
} }
@@ -56,7 +56,7 @@ class RadarViewModel(
private val stationPos = settingsRepo.stationPosition.value private val stationPos = settingsRepo.stationPosition.value
private val magDeclination = getMagDeclination(stationPos) private val magDeclination = getMagDeclination(stationPos)
val stateOfOldScheme = settingsRepo.otherSettings.value.stateOfOldScheme val stateOfLightTheme = settingsRepo.otherSettings.value.stateOfLightTheme
val transmitters = mutableStateOf<List<SatRadio>>(emptyList()) val transmitters = mutableStateOf<List<SatRadio>>(emptyList())
val radarData = mutableStateOf<RadarData?>(null) val radarData = mutableStateOf<RadarData?>(null)
val orientation = mutableStateOf(sensorsRepo.orientation.value) val orientation = mutableStateOf(sensorsRepo.orientation.value)
@@ -19,7 +19,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import com.rtbishop.look4sat.R import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.presentation.theme.MainTheme import com.rtbishop.look4sat.presentation.MainTheme
import com.rtbishop.look4sat.presentation.components.CardButton import com.rtbishop.look4sat.presentation.components.CardButton
@Preview(showBackground = true) @Preview(showBackground = true)
@@ -36,7 +36,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.rtbishop.look4sat.R import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.domain.model.OtherSettings import com.rtbishop.look4sat.domain.model.OtherSettings
import com.rtbishop.look4sat.domain.predict.GeoPos import com.rtbishop.look4sat.domain.predict.GeoPos
import com.rtbishop.look4sat.presentation.theme.MainTheme import com.rtbishop.look4sat.presentation.MainTheme
import com.rtbishop.look4sat.presentation.components.CardButton import com.rtbishop.look4sat.presentation.components.CardButton
import com.rtbishop.look4sat.presentation.components.gotoUrl import com.rtbishop.look4sat.presentation.components.gotoUrl
import com.rtbishop.look4sat.presentation.components.showToast import com.rtbishop.look4sat.presentation.components.showToast
@@ -110,7 +110,7 @@ fun SettingsScreen() {
val toggleUpdate = { value: Boolean -> viewModel.toggleUpdate(value) } val toggleUpdate = { value: Boolean -> viewModel.toggleUpdate(value) }
val toggleSweep = { value: Boolean -> viewModel.toggleSweep(value) } val toggleSweep = { value: Boolean -> viewModel.toggleSweep(value) }
val toggleSensor = { value: Boolean -> viewModel.toggleSensor(value) } val toggleSensor = { value: Boolean -> viewModel.toggleSensor(value) }
val toggleOldScheme = { value: Boolean -> viewModel.toggleOldScheme(value)} val toggleLightTheme = { value: Boolean -> viewModel.toggleLightTheme(value)}
// Screen setup // Screen setup
val versionName = context.packageManager.getPackageInfo(context.packageName, 0).versionName ?: "4.0.0" val versionName = context.packageManager.getPackageInfo(context.packageName, 0).versionName ?: "4.0.0"
@@ -118,7 +118,7 @@ fun SettingsScreen() {
item { CardAbout(versionName) } item { CardAbout(versionName) }
item { LocationCard(positionSettings, setGpsPos, showPosDialog, showLocDialog, dismissPos) } item { LocationCard(positionSettings, setGpsPos, showPosDialog, showLocDialog, dismissPos) }
item { DataCard(dataSettings, updateFromWeb, updateFromFile, clearAllData) } item { DataCard(dataSettings, updateFromWeb, updateFromFile, clearAllData) }
item { OtherCard(otherSettings, toggleUtc, toggleUpdate, toggleSweep, toggleSensor,toggleOldScheme) } item { OtherCard(otherSettings, toggleUtc, toggleUpdate, toggleSweep, toggleSensor,toggleLightTheme) }
} }
} }
@@ -140,7 +140,7 @@ private fun CardAbout(version: String, modifier: Modifier = Modifier) {
) { ) {
Icon( Icon(
painter = painterResource(id = R.drawable.ic_sputnik), painter = painterResource(id = R.drawable.ic_sputnik),
tint = MaterialTheme.colorScheme.secondary, tint = MaterialTheme.colorScheme.primary,
contentDescription = null, contentDescription = null,
modifier = Modifier.size(72.dp) modifier = Modifier.size(72.dp)
) )
@@ -148,7 +148,7 @@ private fun CardAbout(version: String, modifier: Modifier = Modifier) {
Text( Text(
text = stringResource(id = R.string.app_name), text = stringResource(id = R.string.app_name),
fontSize = 48.sp, fontSize = 48.sp,
color = MaterialTheme.colorScheme.secondary color = MaterialTheme.colorScheme.primary
) )
Text( Text(
text = stringResource(id = R.string.app_version, version), fontSize = 20.sp text = stringResource(id = R.string.app_version, version), fontSize = 20.sp
@@ -374,7 +374,7 @@ private fun OtherCardPreview() = MainTheme {
stateOfSensors = true, stateOfSensors = true,
stateOfSweep = true, stateOfSweep = true,
stateOfUtc = false, stateOfUtc = false,
stateOfOldScheme = false) stateOfLightTheme = false)
OtherCard(settings = values, {}, {}, {}, {},{}) OtherCard(settings = values, {}, {}, {}, {},{})
} }
@@ -385,7 +385,7 @@ private fun OtherCard(
toggleUpdate: (Boolean) -> Unit, toggleUpdate: (Boolean) -> Unit,
toggleSweep: (Boolean) -> Unit, toggleSweep: (Boolean) -> Unit,
toggleSensor: (Boolean) -> Unit, toggleSensor: (Boolean) -> Unit,
toggleOldScheme: (Boolean) -> Unit toggleLightTheme: (Boolean) -> Unit
) { ) {
ElevatedCard(modifier = Modifier.fillMaxWidth()) { ElevatedCard(modifier = Modifier.fillMaxWidth()) {
Column(modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp)) { Column(modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp)) {
@@ -426,8 +426,8 @@ private fun OtherCard(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text(text = stringResource(id = R.string.other_switch_old_scheme)) Text(text = stringResource(id = R.string.other_switch_light_theme))
Switch(checked = settings.stateOfOldScheme, onCheckedChange = { toggleOldScheme(it) }) Switch(checked = settings.stateOfLightTheme, onCheckedChange = { toggleLightTheme(it) })
} }
} }
} }
@@ -448,14 +448,14 @@ private fun setUpdateTime(updateTime: Long): String {
private fun UpdateIndicator(isUpdating: Boolean, modifier: Modifier = Modifier) = if (isUpdating) { private fun UpdateIndicator(isUpdating: Boolean, modifier: Modifier = Modifier) = if (isUpdating) {
LinearProgressIndicator( LinearProgressIndicator(
modifier = modifier.padding(start = 6.dp), modifier = modifier.padding(start = 6.dp),
color = MaterialTheme.colorScheme.primary, // color = MaterialTheme.colorScheme.primary,
trackColor = MaterialTheme.colorScheme.secondaryContainer // trackColor = MaterialTheme.colorScheme.secondaryContainer
) )
} else { } else {
LinearProgressIndicator( LinearProgressIndicator(
progress = { 0f }, progress = { 0f },
modifier = modifier.padding(start = 6.dp), modifier = modifier.padding(start = 6.dp),
color = MaterialTheme.colorScheme.primary, // color = MaterialTheme.colorScheme.primary,
trackColor = MaterialTheme.colorScheme.secondaryContainer // trackColor = MaterialTheme.colorScheme.secondaryContainer
) )
} }
@@ -129,7 +129,7 @@ class SettingsViewModel(
fun toggleUpdate(value: Boolean) = settingsRepo.setStateOfAutoUpdate(value) fun toggleUpdate(value: Boolean) = settingsRepo.setStateOfAutoUpdate(value)
fun toggleSweep(value: Boolean) = settingsRepo.setStateOfSweep(value) fun toggleSweep(value: Boolean) = settingsRepo.setStateOfSweep(value)
fun toggleSensor(value: Boolean) = settingsRepo.setStateOfSensors(value) fun toggleSensor(value: Boolean) = settingsRepo.setStateOfSensors(value)
fun toggleOldScheme(value: Boolean) = settingsRepo.setStateOfOldScheme(value) fun toggleLightTheme(value: Boolean) = settingsRepo.setStateOfLightTheme(value)
// fun getRotatorEnabled(): Boolean = settings.getRotatorEnabled() // fun getRotatorEnabled(): Boolean = settings.getRotatorEnabled()
// fun setRotatorEnabled(value: Boolean) = settings.setRotatorEnabled(value) // fun setRotatorEnabled(value: Boolean) = settings.setRotatorEnabled(value)
// fun getRotatorServer(): String = settings.getRotatorServer() // fun getRotatorServer(): String = settings.getRotatorServer()
@@ -1,225 +0,0 @@
package com.rtbishop.look4sat.presentation.theme
import androidx.compose.ui.graphics.Color
val primaryLight = Color(0xFF715C0C)
val onPrimaryLight = Color(0xFFFFFFFF)
val primaryContainerLight = Color(0xFFFEE086)
val onPrimaryContainerLight = Color(0xFF231B00)
val secondaryLight = Color(0xFF685E40)
val onSecondaryLight = Color(0xFFFFFFFF)
val secondaryContainerLight = Color(0xFFF1E1BB)
val onSecondaryContainerLight = Color(0xFF221B04)
val tertiaryLight = Color(0xFF46664B)
val onTertiaryLight = Color(0xFFFFFFFF)
val tertiaryContainerLight = Color(0xFFC7ECCA)
val onTertiaryContainerLight = Color(0xFF02210C)
val errorLight = Color(0xFFBA1A1A)
val onErrorLight = Color(0xFFFFFFFF)
val errorContainerLight = Color(0xFFFFDAD6)
val onErrorContainerLight = Color(0xFF410002)
val backgroundLight = Color(0xFFFFF8F0)
val onBackgroundLight = Color(0xFF1E1B13)
val surfaceLight = Color(0xFFFFF8F0)
val onSurfaceLight = Color(0xFF1E1B13)
val surfaceVariantLight = Color(0xFFEBE2CF)
val onSurfaceVariantLight = Color(0xFF4C4639)
val outlineLight = Color(0xFF7D7667)
val outlineVariantLight = Color(0xFFCEC6B4)
val scrimLight = Color(0xFF000000)
val inverseSurfaceLight = Color(0xFF343027)
val inverseOnSurfaceLight = Color(0xFFF8F0E2)
val inversePrimaryLight = Color(0xFFE1C46D)
val surfaceDimLight = Color(0xFFE1D9CC)
val surfaceBrightLight = Color(0xFFFFF8F0)
val surfaceContainerLowestLight = Color(0xFFFFFFFF)
val surfaceContainerLowLight = Color(0xFFFBF3E5)
val surfaceContainerLight = Color(0xFFF5EDDF)
val surfaceContainerHighLight = Color(0xFFEFE7DA)
val surfaceContainerHighestLight = Color(0xFFE9E2D4)
val primaryLightMediumContrast = Color(0xFF524100)
val onPrimaryLightMediumContrast = Color(0xFFFFFFFF)
val primaryContainerLightMediumContrast = Color(0xFF897224)
val onPrimaryContainerLightMediumContrast = Color(0xFFFFFFFF)
val secondaryLightMediumContrast = Color(0xFF4B4226)
val onSecondaryLightMediumContrast = Color(0xFFFFFFFF)
val secondaryContainerLightMediumContrast = Color(0xFF7F7454)
val onSecondaryContainerLightMediumContrast = Color(0xFFFFFFFF)
val tertiaryLightMediumContrast = Color(0xFF2B4A31)
val onTertiaryLightMediumContrast = Color(0xFFFFFFFF)
val tertiaryContainerLightMediumContrast = Color(0xFF5C7C60)
val onTertiaryContainerLightMediumContrast = Color(0xFFFFFFFF)
val errorLightMediumContrast = Color(0xFF8C0009)
val onErrorLightMediumContrast = Color(0xFFFFFFFF)
val errorContainerLightMediumContrast = Color(0xFFDA342E)
val onErrorContainerLightMediumContrast = Color(0xFFFFFFFF)
val backgroundLightMediumContrast = Color(0xFFFFF8F0)
val onBackgroundLightMediumContrast = Color(0xFF1E1B13)
val surfaceLightMediumContrast = Color(0xFFFFF8F0)
val onSurfaceLightMediumContrast = Color(0xFF1E1B13)
val surfaceVariantLightMediumContrast = Color(0xFFEBE2CF)
val onSurfaceVariantLightMediumContrast = Color(0xFF484235)
val outlineLightMediumContrast = Color(0xFF655F50)
val outlineVariantLightMediumContrast = Color(0xFF817A6B)
val scrimLightMediumContrast = Color(0xFF000000)
val inverseSurfaceLightMediumContrast = Color(0xFF343027)
val inverseOnSurfaceLightMediumContrast = Color(0xFFF8F0E2)
val inversePrimaryLightMediumContrast = Color(0xFFE1C46D)
val surfaceDimLightMediumContrast = Color(0xFFE1D9CC)
val surfaceBrightLightMediumContrast = Color(0xFFFFF8F0)
val surfaceContainerLowestLightMediumContrast = Color(0xFFFFFFFF)
val surfaceContainerLowLightMediumContrast = Color(0xFFFBF3E5)
val surfaceContainerLightMediumContrast = Color(0xFFF5EDDF)
val surfaceContainerHighLightMediumContrast = Color(0xFFEFE7DA)
val surfaceContainerHighestLightMediumContrast = Color(0xFFE9E2D4)
val primaryLightHighContrast = Color(0xFF2B2100)
val onPrimaryLightHighContrast = Color(0xFFFFFFFF)
val primaryContainerLightHighContrast = Color(0xFF524100)
val onPrimaryContainerLightHighContrast = Color(0xFFFFFFFF)
val secondaryLightHighContrast = Color(0xFF292209)
val onSecondaryLightHighContrast = Color(0xFFFFFFFF)
val secondaryContainerLightHighContrast = Color(0xFF4B4226)
val onSecondaryContainerLightHighContrast = Color(0xFFFFFFFF)
val tertiaryLightHighContrast = Color(0xFF082813)
val onTertiaryLightHighContrast = Color(0xFFFFFFFF)
val tertiaryContainerLightHighContrast = Color(0xFF2B4A31)
val onTertiaryContainerLightHighContrast = Color(0xFFFFFFFF)
val errorLightHighContrast = Color(0xFF4E0002)
val onErrorLightHighContrast = Color(0xFFFFFFFF)
val errorContainerLightHighContrast = Color(0xFF8C0009)
val onErrorContainerLightHighContrast = Color(0xFFFFFFFF)
val backgroundLightHighContrast = Color(0xFFFFF8F0)
val onBackgroundLightHighContrast = Color(0xFF1E1B13)
val surfaceLightHighContrast = Color(0xFFFFF8F0)
val onSurfaceLightHighContrast = Color(0xFF000000)
val surfaceVariantLightHighContrast = Color(0xFFEBE2CF)
val onSurfaceVariantLightHighContrast = Color(0xFF282418)
val outlineLightHighContrast = Color(0xFF484235)
val outlineVariantLightHighContrast = Color(0xFF484235)
val scrimLightHighContrast = Color(0xFF000000)
val inverseSurfaceLightHighContrast = Color(0xFF343027)
val inverseOnSurfaceLightHighContrast = Color(0xFFFFFFFF)
val inversePrimaryLightHighContrast = Color(0xFFFFEBB4)
val surfaceDimLightHighContrast = Color(0xFFE1D9CC)
val surfaceBrightLightHighContrast = Color(0xFFFFF8F0)
val surfaceContainerLowestLightHighContrast = Color(0xFFFFFFFF)
val surfaceContainerLowLightHighContrast = Color(0xFFFBF3E5)
val surfaceContainerLightHighContrast = Color(0xFFF5EDDF)
val surfaceContainerHighLightHighContrast = Color(0xFFEFE7DA)
val surfaceContainerHighestLightHighContrast = Color(0xFFE9E2D4)
val primaryDark = Color(0xFFE1C46D)
val onPrimaryDark = Color(0xFF3C2F00)
val primaryContainerDark = Color(0xFF564500)
val onPrimaryContainerDark = Color(0xFFFEE086)
val secondaryDark = Color(0xFFD4C5A1)
val onSecondaryDark = Color(0xFF383016)
val secondaryContainerDark = Color(0xFF50462A)
val onSecondaryContainerDark = Color(0xFFF1E1BB)
val tertiaryDark = Color(0xFFACCFAF)
val onTertiaryDark = Color(0xFF183720)
val tertiaryContainerDark = Color(0xFF2E4E35)
val onTertiaryContainerDark = Color(0xFFC7ECCA)
val errorDark = Color(0xFFFFB4AB)
val onErrorDark = Color(0xFF690005)
val errorContainerDark = Color(0xFF93000A)
val onErrorContainerDark = Color(0xFFFFDAD6)
val backgroundDark = Color(0xFF16130B)
val onBackgroundDark = Color(0xFFE9E2D4)
val surfaceDark = Color(0xFF16130B)
val onSurfaceDark = Color(0xFFE9E2D4)
val surfaceVariantDark = Color(0xFF4C4639)
val onSurfaceVariantDark = Color(0xFFCEC6B4)
val outlineDark = Color(0xFF979080)
val outlineVariantDark = Color(0xFF4C4639)
val scrimDark = Color(0xFF000000)
val inverseSurfaceDark = Color(0xFFE9E2D4)
val inverseOnSurfaceDark = Color(0xFF343027)
val inversePrimaryDark = Color(0xFF715C0C)
val surfaceDimDark = Color(0xFF16130B)
val surfaceBrightDark = Color(0xFF3D392F)
val surfaceContainerLowestDark = Color(0xFF110E07)
val surfaceContainerLowDark = Color(0xFF1E1B13)
val surfaceContainerDark = Color(0xFF231F17)
val surfaceContainerHighDark = Color(0xFF2D2A21)
val surfaceContainerHighestDark = Color(0xFF38342B)
val primaryDarkMediumContrast = Color(0xFFE5C971)
val onPrimaryDarkMediumContrast = Color(0xFF1D1500)
val primaryContainerDarkMediumContrast = Color(0xFFA88F3D)
val onPrimaryContainerDarkMediumContrast = Color(0xFF000000)
val secondaryDarkMediumContrast = Color(0xFFD8CAA5)
val onSecondaryDarkMediumContrast = Color(0xFF1C1601)
val secondaryContainerDarkMediumContrast = Color(0xFF9C906E)
val onSecondaryContainerDarkMediumContrast = Color(0xFF000000)
val tertiaryDarkMediumContrast = Color(0xFFB0D4B3)
val onTertiaryDarkMediumContrast = Color(0xFF001B08)
val tertiaryContainerDarkMediumContrast = Color(0xFF77997B)
val onTertiaryContainerDarkMediumContrast = Color(0xFF000000)
val errorDarkMediumContrast = Color(0xFFFFBAB1)
val onErrorDarkMediumContrast = Color(0xFF370001)
val errorContainerDarkMediumContrast = Color(0xFFFF5449)
val onErrorContainerDarkMediumContrast = Color(0xFF000000)
val backgroundDarkMediumContrast = Color(0xFF16130B)
val onBackgroundDarkMediumContrast = Color(0xFFE9E2D4)
val surfaceDarkMediumContrast = Color(0xFF16130B)
val onSurfaceDarkMediumContrast = Color(0xFFFFFAF6)
val surfaceVariantDarkMediumContrast = Color(0xFF4C4639)
val onSurfaceVariantDarkMediumContrast = Color(0xFFD3CAB8)
val outlineDarkMediumContrast = Color(0xFFAAA291)
val outlineVariantDarkMediumContrast = Color(0xFF898273)
val scrimDarkMediumContrast = Color(0xFF000000)
val inverseSurfaceDarkMediumContrast = Color(0xFFE9E2D4)
val inverseOnSurfaceDarkMediumContrast = Color(0xFF2D2A21)
val inversePrimaryDarkMediumContrast = Color(0xFF584600)
val surfaceDimDarkMediumContrast = Color(0xFF16130B)
val surfaceBrightDarkMediumContrast = Color(0xFF3D392F)
val surfaceContainerLowestDarkMediumContrast = Color(0xFF110E07)
val surfaceContainerLowDarkMediumContrast = Color(0xFF1E1B13)
val surfaceContainerDarkMediumContrast = Color(0xFF231F17)
val surfaceContainerHighDarkMediumContrast = Color(0xFF2D2A21)
val surfaceContainerHighestDarkMediumContrast = Color(0xFF38342B)
val primaryDarkHighContrast = Color(0xFFFFFAF6)
val onPrimaryDarkHighContrast = Color(0xFF000000)
val primaryContainerDarkHighContrast = Color(0xFFE5C971)
val onPrimaryContainerDarkHighContrast = Color(0xFF000000)
val secondaryDarkHighContrast = Color(0xFFFFFAF6)
val onSecondaryDarkHighContrast = Color(0xFF000000)
val secondaryContainerDarkHighContrast = Color(0xFFD8CAA5)
val onSecondaryContainerDarkHighContrast = Color(0xFF000000)
val tertiaryDarkHighContrast = Color(0xFFF0FFEE)
val onTertiaryDarkHighContrast = Color(0xFF000000)
val tertiaryContainerDarkHighContrast = Color(0xFFB0D4B3)
val onTertiaryContainerDarkHighContrast = Color(0xFF000000)
val errorDarkHighContrast = Color(0xFFFFF9F9)
val onErrorDarkHighContrast = Color(0xFF000000)
val errorContainerDarkHighContrast = Color(0xFFFFBAB1)
val onErrorContainerDarkHighContrast = Color(0xFF000000)
val backgroundDarkHighContrast = Color(0xFF16130B)
val onBackgroundDarkHighContrast = Color(0xFFE9E2D4)
val surfaceDarkHighContrast = Color(0xFF16130B)
val onSurfaceDarkHighContrast = Color(0xFFFFFFFF)
val surfaceVariantDarkHighContrast = Color(0xFF4C4639)
val onSurfaceVariantDarkHighContrast = Color(0xFFFFFAF6)
val outlineDarkHighContrast = Color(0xFFD3CAB8)
val outlineVariantDarkHighContrast = Color(0xFFD3CAB8)
val scrimDarkHighContrast = Color(0xFF000000)
val inverseSurfaceDarkHighContrast = Color(0xFFE9E2D4)
val inverseOnSurfaceDarkHighContrast = Color(0xFF000000)
val inversePrimaryDarkHighContrast = Color(0xFF342900)
val surfaceDimDarkHighContrast = Color(0xFF16130B)
val surfaceBrightDarkHighContrast = Color(0xFF3D392F)
val surfaceContainerLowestDarkHighContrast = Color(0xFF110E07)
val surfaceContainerLowDarkHighContrast = Color(0xFF1E1B13)
val surfaceContainerDarkHighContrast = Color(0xFF231F17)
val surfaceContainerHighDarkHighContrast = Color(0xFF2D2A21)
val surfaceContainerHighestDarkHighContrast = Color(0xFF38342B)
@@ -1,217 +0,0 @@
package com.rtbishop.look4sat.presentation.theme
import android.app.Activity
import android.os.Build
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.LocalOverscrollConfiguration
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Shapes
import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.Typography
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.view.WindowCompat
import com.rtbishop.look4sat.MainApplication
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MainTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val view = LocalView.current
if (view.isInEditMode) MaterialTheme(
colorScheme = lightScheme,
typography = typography,
shapes = shapes
) {
CompositionLocalProvider(LocalOverscrollConfiguration.provides(null), content = content)
}
else {
val otherSettings by (LocalContext.current.applicationContext as MainApplication).container.settingsRepo.otherSettings.collectAsState()
val isOldScheme = otherSettings.stateOfOldScheme
val colorScheme = when {
isOldScheme -> oldScheme
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> darkScheme
else -> lightScheme
}
SideEffect {
val window = (view.context as Activity).window
window.statusBarColor = colorScheme.background.toArgb()
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars =
if (isOldScheme) false else !darkTheme
}
MaterialTheme(colorScheme = colorScheme, typography = typography, shapes = shapes) {
CompositionLocalProvider(LocalOverscrollConfiguration.provides(null), content = content)
}
}
}
private val typography = Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
), titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
), labelSmall = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Medium,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
)
private val shapes = Shapes(
extraSmall = RoundedCornerShape(4.dp), small = RoundedCornerShape(6.dp), // buttons corners
medium = RoundedCornerShape(8.dp), // cards corners
large = RoundedCornerShape(12.dp), extraLarge = RoundedCornerShape(16.dp)
)
private val accentYellow = Color(0xFFFFE082)
private val textWhite = Color(0xCCFFFFFF)
private val textGrey = Color(0x66FFFFFF)
private val textBlack = Color(0xFF000000)
private val surfaceInverse = Color(0x40FFFFFF)
private val surfaceBtn = Color(0xFF303030)
private val surfaceCard = Color(0xFF1C1C1C)
private val surfaceBg = Color(0xFF121212)
private val transparent = Color(0x00000000)
private val oldScheme = lightColorScheme(
primary = accentYellow,
onPrimary = textBlack,
// primaryContainer = primaryContainer,
// onPrimaryContainer = onPrimaryContainer,
// inversePrimary = inversePrimary,
secondary = accentYellow,
onSecondary = textBlack,
secondaryContainer = surfaceInverse, // navBar indicator
onSecondaryContainer = textBlack, // navBar active icon
tertiary = surfaceBtn,
onTertiary = textWhite,
// tertiaryContainer = tertiaryContainer,
// onTertiaryContainer = onTertiaryContainer,
background = surfaceBg,
onBackground = textWhite,
surface = surfaceCard,
onSurface = textWhite,
surfaceVariant = surfaceCard,
onSurfaceVariant = textGrey, // navBar inactive icon
surfaceTint = transparent,
inverseSurface = surfaceInverse,
// inverseOnSurface = inverseOnSurface,
// error = error,
// onError = onError,
// errorContainer = errorContainer,
// onErrorContainer = onErrorContainer,
// outline = outline,
// outlineVariant = outlineVariant,
// scrim = scrim,
)
private val lightScheme = lightColorScheme(
primary = primaryLight,
onPrimary = onPrimaryLight,
primaryContainer = primaryContainerLight,
onPrimaryContainer = onPrimaryContainerLight,
secondary = secondaryLight,
onSecondary = onSecondaryLight,
secondaryContainer = secondaryContainerLight,
onSecondaryContainer = onSecondaryContainerLight,
tertiary = tertiaryLight,
onTertiary = onTertiaryLight,
tertiaryContainer = tertiaryContainerLight,
onTertiaryContainer = onTertiaryContainerLight,
error = errorLight,
onError = onErrorLight,
errorContainer = errorContainerLight,
onErrorContainer = onErrorContainerLight,
background = backgroundLight,
onBackground = onBackgroundLight,
surface = surfaceLight,
onSurface = onSurfaceLight,
surfaceVariant = surfaceVariantLight,
onSurfaceVariant = onSurfaceVariantLight,
outline = outlineLight,
outlineVariant = outlineVariantLight,
scrim = scrimLight,
inverseSurface = inverseSurfaceLight,
inverseOnSurface = inverseOnSurfaceLight,
inversePrimary = inversePrimaryLight,
surfaceDim = surfaceDimLight,
surfaceBright = surfaceBrightLight,
surfaceContainerLowest = surfaceContainerLowestLight,
surfaceContainerLow = surfaceContainerLowLight,
surfaceContainer = surfaceContainerLight,
surfaceContainerHigh = surfaceContainerHighLight,
surfaceContainerHighest = surfaceContainerHighestLight,
)
private val darkScheme = darkColorScheme(
primary = primaryDark,
onPrimary = onPrimaryDark,
primaryContainer = primaryContainerDark,
onPrimaryContainer = onPrimaryContainerDark,
secondary = secondaryDark,
onSecondary = onSecondaryDark,
secondaryContainer = secondaryContainerDark,
onSecondaryContainer = onSecondaryContainerDark,
tertiary = tertiaryDark,
onTertiary = onTertiaryDark,
tertiaryContainer = tertiaryContainerDark,
onTertiaryContainer = onTertiaryContainerDark,
error = errorDark,
onError = onErrorDark,
errorContainer = errorContainerDark,
onErrorContainer = onErrorContainerDark,
background = backgroundDark,
onBackground = onBackgroundDark,
surface = surfaceDark,
onSurface = onSurfaceDark,
surfaceVariant = surfaceVariantDark,
onSurfaceVariant = onSurfaceVariantDark,
outline = outlineDark,
outlineVariant = outlineVariantDark,
scrim = scrimDark,
inverseSurface = inverseSurfaceDark,
inverseOnSurface = inverseOnSurfaceDark,
inversePrimary = inversePrimaryDark,
surfaceDim = surfaceDimDark,
surfaceBright = surfaceBrightDark,
surfaceContainerLowest = surfaceContainerLowestDark,
surfaceContainerLow = surfaceContainerLowDark,
surfaceContainer = surfaceContainerDark,
surfaceContainerHigh = surfaceContainerHighDark,
surfaceContainerHighest = surfaceContainerHighestDark,
)
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M20,3h-1L19,1h-2v2L7,3L7,1L5,1v2L4,3c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,5c0,-1.1 -0.9,-2 -2,-2zM20,21L4,21L4,8h16v13z" />
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M21.41,10.59l-7.99,-8c-0.78,-0.78 -2.05,-0.78 -2.83,0l-8.01,8c-0.78,0.78 -0.78,2.05 0,2.83l8.01,8c0.78,0.78 2.05,0.78 2.83,0l7.99,-8C22.2,12.63 22.2,11.37 21.41,10.59zM13.5,14.5V12H10v3H8v-4c0,-0.55 0.45,-1 1,-1h4.5V7.5L17,11L13.5,14.5z" />
</vector>
+1 -1
View File
@@ -162,6 +162,7 @@
<string name="other_switch_update">• Обновлять данные автоматически</string> <string name="other_switch_update">• Обновлять данные автоматически</string>
<string name="other_switch_sweep">• Показывать анимацию радара</string> <string name="other_switch_sweep">• Показывать анимацию радара</string>
<string name="other_switch_sensors">• Использовать сенсоры устройства</string> <string name="other_switch_sensors">• Использовать сенсоры устройства</string>
<string name="other_switch_light_theme">• Использовать светлую тему</string>
<string name="outro_title">Я хотел бы сказать спасибо:</string> <string name="outro_title">Я хотел бы сказать спасибо:</string>
<string name="outro_thanks">• Вам за использование этого приложения! \nЖелаю всегда чистого неба над головой! <string name="outro_thanks">• Вам за использование этого приложения! \nЖелаю всегда чистого неба над головой!
@@ -178,5 +179,4 @@
за интерес к приложению и публикацию интервью на сайте. за интерес к приложению и публикацию интервью на сайте.
</string> </string>
<string name="outro_license">Это ПО поставляется без гарантий.</string> <string name="outro_license">Это ПО поставляется без гарантий.</string>
<string name="other_switch_old_scheme">• Используйте старую цветовую схему.</string>
</resources> </resources>
+1 -1
View File
@@ -162,6 +162,7 @@
<string name="other_switch_update">• ස්වයං දත්ත යාවත්කාලීනය</string> <string name="other_switch_update">• ස්වයං දත්ත යාවත්කාලීනය</string>
<string name="other_switch_sweep">• radar sweep සජීවිකරණය සබල කරන්න</string> <string name="other_switch_sweep">• radar sweep සජීවිකරණය සබල කරන්න</string>
<string name="other_switch_sensors">• Radar දර්ශනය කරකැවීමට සංවේදක භාවිතා කරන්න </string> <string name="other_switch_sensors">• Radar දර්ශනය කරකැවීමට සංවේදක භාවිතා කරන්න </string>
<string name="other_switch_light_theme">• සැහැල්ලු තේමාව භාවිතා කරන්න</string>
<string name="outro_title">මම ස්තුති කිරීමට කැමති:</string> <string name="outro_title">මම ස්තුති කිරීමට කැමති:</string>
<string name="outro_thanks">• බාගෙන භාවිතා කළ ඔබට! \nඅහස සදා ඔබ වෙනුවෙන් පැහැදිලියි! <string name="outro_thanks">• බාගෙන භාවිතා කළ ඔබට! \nඅහස සදා ඔබ වෙනුවෙන් පැහැදිලියි!
@@ -175,5 +176,4 @@
<a href="https://db.satnogs.org/">SatNOGS</a>Web අඩවියට API හා DB විශාල දත්ත ප්‍රමාණයක් ලබාදීම සඳහා. <a href="https://db.satnogs.org/">SatNOGS</a>Web අඩවියට API හා DB විශාල දත්ත ප්‍රමාණයක් ලබාදීම සඳහා.
\n• <a href="https://appoftheday.downloadastro.com/app/look4sat-satellite-tracker/">DownloadAstro</a> කණ්ඩායමට යෙදුම පිළිබඳ ඔවුන්ගේ උනන්දුව සහ කැපවීම ලැබිම සම්බන්ධයෙන්.</string> \n• <a href="https://appoftheday.downloadastro.com/app/look4sat-satellite-tracker/">DownloadAstro</a> කණ්ඩායමට යෙදුම පිළිබඳ ඔවුන්ගේ උනන්දුව සහ කැපවීම ලැබිම සම්බන්ධයෙන්.</string>
<string name="outro_license">මෘදුකාංගය වගකීමක් සමග නොලැබේ</string> <string name="outro_license">මෘදුකාංගය වගකීමක් සමග නොලැබේ</string>
<string name="other_switch_old_scheme">• පැරණි වර්ණ පටිපාටිය භාවිතා කරන්න</string>
</resources> </resources>
+1 -1
View File
@@ -162,6 +162,7 @@
<string name="other_switch_update">• 启用卫星数据自动更新</string> <string name="other_switch_update">• 启用卫星数据自动更新</string>
<string name="other_switch_sweep">• 启用雷达扫描动画</string> <string name="other_switch_sweep">• 启用雷达扫描动画</string>
<string name="other_switch_sensors">• 使用传感器旋转雷达视图</string> <string name="other_switch_sensors">• 使用传感器旋转雷达视图</string>
<string name="other_switch_light_theme">• 使用旧版配色方案</string>
<string name="outro_title">我要感谢:</string> <string name="outro_title">我要感谢:</string>
<string name="outro_thanks">• 感谢下载和使用 Look4Sat!愿你的天空永远晴朗! <string name="outro_thanks">• 感谢下载和使用 Look4Sat!愿你的天空永远晴朗!
@@ -179,5 +180,4 @@
team for their interest to the app and the interview published. team for their interest to the app and the interview published.
</string> </string>
<string name="outro_license">该应用程序不提供任何保修.</string> <string name="outro_license">该应用程序不提供任何保修.</string>
<string name="other_switch_old_scheme">• 使用旧版配色方案</string>
</resources> </resources>
+2 -2
View File
@@ -77,7 +77,7 @@
<string name="pass_satName">%s</string> <string name="pass_satName">%s</string>
<string name="pass_satId">Id:%05d</string> <string name="pass_satId">Id:%05d</string>
<string name="pass_aosAz">AOS - %.1f°</string> <string name="pass_aosAz">AOS - %.1f°</string>
<string name="pass_aosLos" translatable="false">Az: %03d° -> Az: %03d°</string> <string name="pass_aosLos" translatable="false">%03d° -> %03d°</string>
<string name="pass_elevation">Elevation: %.1f°</string> <string name="pass_elevation">Elevation: %.1f°</string>
<string name="pass_losAz">%.1f° - LOS</string> <string name="pass_losAz">%.1f° - LOS</string>
<string name="pass_altitude">Altitude: %d km</string> <string name="pass_altitude">Altitude: %d km</string>
@@ -165,6 +165,7 @@
<string name="other_switch_update">• Enable automatic data update</string> <string name="other_switch_update">• Enable automatic data update</string>
<string name="other_switch_sweep">• Enable radar sweep animation</string> <string name="other_switch_sweep">• Enable radar sweep animation</string>
<string name="other_switch_sensors">• Use sensors to rotate radar view</string> <string name="other_switch_sensors">• Use sensors to rotate radar view</string>
<string name="other_switch_light_theme">• Use light theme</string>
<string name="outro_title">I would like to say thanks to:</string> <string name="outro_title">I would like to say thanks to:</string>
<string name="outro_thanks">• You for downloading and using Look4Sat! \nMay your sky always be clear! <string name="outro_thanks">• You for downloading and using Look4Sat! \nMay your sky always be clear!
@@ -180,5 +181,4 @@
team for their interest to the app and the interview published. team for their interest to the app and the interview published.
</string> </string>
<string name="outro_license">The app comes with no warranty.</string> <string name="outro_license">The app comes with no warranty.</string>
<string name="other_switch_old_scheme">• Use the old color scheme</string>
</resources> </resources>
@@ -19,9 +19,9 @@ package com.rtbishop.look4sat.data.repository
import android.content.SharedPreferences import android.content.SharedPreferences
import android.location.LocationManager import android.location.LocationManager
import android.os.CancellationSignal
import androidx.core.content.edit import androidx.core.content.edit
import androidx.core.location.LocationManagerCompat import androidx.core.location.LocationManagerCompat
import androidx.core.os.CancellationSignal
import com.rtbishop.look4sat.domain.model.DatabaseState import com.rtbishop.look4sat.domain.model.DatabaseState
import com.rtbishop.look4sat.domain.model.OtherSettings import com.rtbishop.look4sat.domain.model.OtherSettings
import com.rtbishop.look4sat.domain.model.PassesSettings import com.rtbishop.look4sat.domain.model.PassesSettings
@@ -53,7 +53,7 @@ class SettingsRepo(private val manager: LocationManager, private val preferences
private val keyStateOfSensors = "stateOfSensors" private val keyStateOfSensors = "stateOfSensors"
private val keyStateOfSweep = "stateOfSweep" private val keyStateOfSweep = "stateOfSweep"
private val keyStateOfUtc = "stateOfUtc" private val keyStateOfUtc = "stateOfUtc"
private val keyStateOfOldScheme = "stateOfOldScheme" private val keyStateOfLightTheme = "stateOfLightTheme"
private val keyStationAltitude = "stationAltitude" private val keyStationAltitude = "stationAltitude"
private val keyStationLatitude = "stationLatitude" private val keyStationLatitude = "stationLatitude"
private val keyStationLongitude = "stationLongitude" private val keyStationLongitude = "stationLongitude"
@@ -222,9 +222,9 @@ class SettingsRepo(private val manager: LocationManager, private val preferences
_otherSettings.value = otherSettings.value.copy(stateOfUtc = value) _otherSettings.value = otherSettings.value.copy(stateOfUtc = value)
} }
override fun setStateOfOldScheme(value: Boolean){ override fun setStateOfLightTheme(value: Boolean){
preferences.edit { putBoolean(keyStateOfOldScheme, value) } preferences.edit { putBoolean(keyStateOfLightTheme, value) }
_otherSettings.value = otherSettings.value.copy(stateOfOldScheme = value) _otherSettings.value = otherSettings.value.copy(stateOfLightTheme = value)
} }
private fun getOtherSettings(): OtherSettings { private fun getOtherSettings(): OtherSettings {
@@ -232,8 +232,8 @@ class SettingsRepo(private val manager: LocationManager, private val preferences
val stateOfSensors = preferences.getBoolean(keyStateOfSensors, true) val stateOfSensors = preferences.getBoolean(keyStateOfSensors, true)
val stateOfSweep = preferences.getBoolean(keyStateOfSweep, true) val stateOfSweep = preferences.getBoolean(keyStateOfSweep, true)
val stateOfUtc = preferences.getBoolean(keyStateOfUtc, false) val stateOfUtc = preferences.getBoolean(keyStateOfUtc, false)
val stateOfOldScheme = preferences.getBoolean(keyStateOfOldScheme,false) val stateOfLightTheme = preferences.getBoolean(keyStateOfLightTheme,false)
return OtherSettings(stateOfAutoUpdate, stateOfSensors, stateOfSweep, stateOfUtc,stateOfOldScheme) return OtherSettings(stateOfAutoUpdate, stateOfSensors, stateOfSweep, stateOfUtc, stateOfLightTheme)
} }
//endregion //endregion
@@ -1,13 +1,21 @@
package com.rtbishop.look4sat.domain.model package com.rtbishop.look4sat.domain.model
data class DatabaseState(val numberOfRadios: Int, val numberOfSatellites: Int, val updateTimestamp: Long) data class DatabaseState(
val numberOfRadios: Int,
val numberOfSatellites: Int,
val updateTimestamp: Long
)
data class PassesSettings(val hoursAhead: Int, val minElevation: Double, val selectedModes: List<String>) data class PassesSettings(
val hoursAhead: Int,
val minElevation: Double,
val selectedModes: List<String>
)
data class OtherSettings( data class OtherSettings(
val stateOfAutoUpdate: Boolean, val stateOfAutoUpdate: Boolean,
val stateOfSensors: Boolean, val stateOfSensors: Boolean,
val stateOfSweep: Boolean, val stateOfSweep: Boolean,
val stateOfUtc: Boolean, val stateOfUtc: Boolean,
val stateOfOldScheme: Boolean val stateOfLightTheme: Boolean
) )
@@ -55,7 +55,7 @@ interface ISettingsRepo {
fun setStateOfSensors(value: Boolean) fun setStateOfSensors(value: Boolean)
fun setStateOfSweep(value: Boolean) fun setStateOfSweep(value: Boolean)
fun setStateOfUtc(value: Boolean) fun setStateOfUtc(value: Boolean)
fun setStateOfOldScheme(value: Boolean) fun setStateOfLightTheme(value: Boolean)
//endregion //endregion
//region # Undefined settings //region # Undefined settings
+14 -14
View File
@@ -1,29 +1,29 @@
[versions] [versions]
android-gradle-plugin = "8.3.0" android-gradle-plugin = "8.5.0"
google-ksp = "1.9.22-1.0.17" google-ksp = "1.9.24-1.0.20"
kotlin = "1.9.22" kotlin = "1.9.24"
androidx-core-ktx = "1.12.0" androidx-core-ktx = "1.13.1"
androidx-core-splashscreen = "1.0.1" androidx-core-splashscreen = "1.0.1"
androidx-room = "2.6.1" androidx-room = "2.6.1"
compose = "1.6.3" compose = "1.6.8"
compose-activity = "1.8.2" compose-activity = "1.9.0"
compose-compiler = "1.5.10" compose-compiler = "1.5.14"
compose-lifecycle = "2.7.0" compose-lifecycle = "2.8.2"
compose-material3 = "1.2.1" compose-material3 = "1.2.1"
compose-navigation = "2.7.7" compose-navigation = "2.7.7"
other-coroutines = "1.7.3" other-coroutines = "1.8.1"
other-json = "20231013" other-json = "20240303"
other-okhttp = "4.12.0" other-okhttp = "4.12.0"
other-osmdroid = "6.1.17" other-osmdroid = "6.1.18"
test-junit4 = "4.13.2" test-junit4 = "4.13.2"
test-mockk = "1.13.9" test-mockk = "1.13.11"
androidTest-junit = "1.1.5" androidTest-junit = "1.2.0"
androidTest-espresso = "3.5.1" androidTest-espresso = "3.6.0"
[libraries] [libraries]
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core-ktx" } androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core-ktx" }
+1 -1
View File
@@ -1,6 +1,6 @@
#Fri Sep 01 22:09:30 BST 2023 #Fri Sep 01 22:09:30 BST 2023
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists