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
+397 -605

No files matched your search

+4 -8
View File
@@ -1,10 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name=".MainApplication"
@@ -12,15 +11,12 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/Theme.Look4Sat.Main"
tools:targetApi="33">
android:theme="@style/Theme.Look4Sat.Main">
<activity
android:name=".MainActivity"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/Theme.Look4Sat.SplashScreen"
tools:ignore="LockedOrientationActivity">
android:theme="@style/Theme.Look4Sat.SplashScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -17,30 +17,24 @@
*/
package com.rtbishop.look4sat
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.util.DisplayMetrics
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
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.theme.MainTheme
import com.rtbishop.look4sat.presentation.MainTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen()
super.onCreate(savedInstanceState)
setContent { MainTheme { MainScreen() } }
setContent {
val container = (LocalContext.current.applicationContext as MainApplication).container
val otherSettings = container.settingsRepo.otherSettings.collectAsState().value
MainTheme(isLightTheme = otherSettings.stateOfLightTheme) { MainScreen() }
}
override fun attachBaseContext(newBase: Context?) {
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
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.util.Date
import java.util.Locale
@@ -32,7 +28,6 @@ class MainApplication : Application() {
lateinit var container: MainContainer
override fun onCreate() {
enableStrictMode()
super.onCreate()
container = MainContainer(this)
// 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 {
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
@@ -49,7 +49,7 @@ fun MainScreen(navController: NavHostController = rememberNavController()) {
@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)) {
NavigationBar(modifier = Modifier.height(48.dp), tonalElevation = 0.dp) {
val navBackStackEntry = navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry.value?.destination?.route
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.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CardDefaults
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.OrbitalData
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.util.Date
import java.util.Locale
@@ -126,9 +128,9 @@ fun NextPassRow(pass: OrbitalPass) {
tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(16.dp)
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = " ${pass.maxElevation}°",
textAlign = TextAlign.End,
text = "${pass.maxElevation}°",
color = MaterialTheme.colorScheme.primary
)
}
@@ -137,21 +139,26 @@ fun NextPassRow(pass: OrbitalPass) {
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth()
) {
Row(
modifier = Modifier.weight(1f),
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)),
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(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.End,
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Icon(
@@ -159,9 +166,29 @@ fun NextPassRow(pass: OrbitalPass) {
contentDescription = null,
modifier = Modifier.size(16.dp)
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = " ${pass.altitude} km",
textAlign = TextAlign.Start,
text = "${pass.altitude} km",
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
)
}
@@ -174,8 +201,8 @@ fun NextPassRow(pass: OrbitalPass) {
fun CardButton(onClick: () -> Unit, text: String, modifier: Modifier = Modifier) {
ElevatedButton(
onClick = { onClick() }, colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.tertiary,
contentColor = MaterialTheme.colorScheme.onTertiary
containerColor = MaterialTheme.colorScheme.surfaceVariant,
contentColor = MaterialTheme.colorScheme.onSurfaceVariant
), shape = MaterialTheme.shapes.small, modifier = modifier
) { 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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.rtbishop.look4sat.presentation.theme.MainTheme
import com.rtbishop.look4sat.presentation.MainTheme
@Preview(showBackground = true)
@Composable
@@ -56,7 +56,7 @@ fun TypesDialog(items: List<String>, selected: String, dismiss: () -> Unit, sele
text = "$index).",
modifier = Modifier.padding(start = 12.dp, end = 6.dp),
fontWeight = FontWeight.Normal,
color = MaterialTheme.colorScheme.secondary
color = MaterialTheme.colorScheme.primary
)
Text(
text = item,
@@ -39,7 +39,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.rtbishop.look4sat.R
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.CardLoadingIndicator
@@ -199,7 +199,7 @@ private fun Entry(item: SatItem, onSelected: (Int, Boolean) -> Unit, modifier: M
) {
Text(
text = "$passSatId - ",
color = MaterialTheme.colorScheme.secondary
color = MaterialTheme.colorScheme.primary
)
Text(
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.sp
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.gotoUrl
@@ -52,7 +52,7 @@ private fun CardCredits(modifier: Modifier = Modifier) {
text = stringResource(id = R.string.outro_title),
fontSize = 18.sp,
fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.secondary,
color = MaterialTheme.colorScheme.primary,
modifier = modifier.padding(6.dp)
)
Text(
@@ -64,7 +64,7 @@ private fun CardCredits(modifier: Modifier = Modifier) {
text = stringResource(id = R.string.outro_license),
fontSize = 18.sp,
fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.secondary,
color = MaterialTheme.colorScheme.primary,
modifier = modifier.padding(6.dp)
)
Row(horizontalArrangement = Arrangement.SpaceEvenly) {
@@ -9,7 +9,6 @@ import android.graphics.Paint
import android.graphics.Rect
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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.OrbitalObject
import com.rtbishop.look4sat.domain.predict.OrbitalPos
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.CustomZoomButtonsController
import org.osmdroid.views.MapView
@@ -73,7 +71,7 @@ fun MapScreen() {
val positionClick = { orbitalObject: OrbitalObject -> viewModel.selectSatellite(orbitalObject) }
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
ElevatedCard(modifier = Modifier.fillMaxSize()) {
MapView(modifier = Modifier.fillMaxSize()) { mapView ->
MapView(modifier = Modifier.fillMaxSize(), isLightTheme = viewModel.stateOfLightTheme) { mapView ->
stationPos.value?.let { setStationPosition(it, mapView) }
positions.value?.let { setPositions(it, mapView, positionClick) }
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()
try {
posMap.entries.forEach {
@@ -195,24 +197,27 @@ private fun setFootprint(orbitalPos: OrbitalPos, mapView: MapView) {
//}
@Composable
private fun MapView(modifier: Modifier = Modifier, update: ((map: MapView) -> Unit)? = null) {
val mapView = rememberMapViewWithLifecycle()
private fun MapView(
modifier: Modifier = Modifier,
isLightTheme: Boolean,
update: ((map: MapView) -> Unit)? = null
) {
val mapView = rememberMapViewWithLifecycle(isLightTheme)
AndroidView({ mapView }, modifier) { update?.invoke(it) }
}
@Composable
private fun rememberMapViewWithLifecycle(): MapView {
private fun rememberMapViewWithLifecycle(isLightTheme: Boolean): MapView {
val context = LocalContext.current
val mapView = remember { MapView(context) }.apply {
setMultiTouchControls(true)
setTileSource(TileSourceFactory.WIKIMEDIA)
minZoomLevel = getMinZoom(resources.displayMetrics.heightPixels) + 0.25
maxZoomLevel = 5.99
controller.setZoom(minZoomLevel + 0.5)
zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
overlayManager.tilesOverlay.loadingBackgroundColor = Color.TRANSPARENT
overlayManager.tilesOverlay.loadingLineColor = Color.TRANSPARENT
overlayManager.tilesOverlay.setColorFilter(getColorFilter())
overlayManager.tilesOverlay.setColorFilter(getColorFilter(isLightTheme))
setScrollableAreaLimitLatitude(maxLat, minLat, 0)
// add overlays: 0 - GSP, 1 - SatTrack, 2 - SatFootprint, 3 - SatIcons
overlays.addAll(Array(4) { FolderOverlay() })
@@ -239,17 +244,13 @@ private fun rememberMapViewLifecycleObserver(mapView: MapView) = remember(mapVie
}
@Composable
private fun getColorFilter(): ColorMatrixColorFilter {
val viewModel = viewModel(MapViewModel::class.java, factory = MapViewModel.Factory)
val grayScaleMatrix = ColorMatrix().apply { setSaturation(0f) }
val negativeMatrix = ColorMatrix(
private fun getColorFilter(isLightTheme: Boolean): ColorMatrixColorFilter {
val grayScale = ColorMatrix().apply { setSaturation(0f) }
val negative = ColorMatrix(
floatArrayOf(-1f, 0f, 0f, 0f, 260f, 0f, -1f, 0f, 0f, 260f, 0f, 0f, -1f, 0f, 260f, 0f, 0f, 0f, 1f, 0f)
)
negativeMatrix.preConcat(grayScaleMatrix)
return when {
isSystemInDarkTheme() || viewModel.stateOfOldScheme -> ColorMatrixColorFilter(negativeMatrix)
else -> ColorMatrixColorFilter(grayScaleMatrix)
}
negative.preConcat(grayScale)
return if (isLightTheme) ColorMatrixColorFilter(grayScale) else ColorMatrixColorFilter(negative)
}
private fun getMinZoom(screenHeight: Int): Double {
@@ -53,7 +53,7 @@ class MapViewModel(private val satelliteRepo: ISatelliteRepo, settingsRepo: ISet
private var dataUpdateRate = 1000L
private var selectedOrbitalObject: OrbitalObject? = null
val stateOfOldScheme = settingsRepo.otherSettings.value.stateOfOldScheme
val stateOfLightTheme = settingsRepo.otherSettings.value.stateOfLightTheme
val stationPosition = flow {
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.sp
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
private val allModes = listOf(
@@ -206,7 +206,7 @@ fun RadiosDialog(modes: List<String>, dismiss: () -> Unit, save: (List<String>)
text = "$index).",
modifier = Modifier.padding(start = 8.dp, end = 6.dp),
fontWeight = FontWeight.Normal,
color = MaterialTheme.colorScheme.secondary
color = MaterialTheme.colorScheme.primary
)
Text(
text = item,
@@ -7,10 +7,12 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.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.OrbitalData
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.NextPassRow
import com.rtbishop.look4sat.presentation.components.PullRefreshIndicator
@@ -48,7 +50,7 @@ import java.text.SimpleDateFormat
import java.util.Date
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)
@Composable
@@ -155,9 +157,9 @@ private fun PassItem(pass: OrbitalPass, navToRadar: (Int, Long) -> Unit, modifie
tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(16.dp)
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = " ${pass.maxElevation}°",
textAlign = TextAlign.End,
text = "${pass.maxElevation}°",
color = MaterialTheme.colorScheme.primary
)
}
@@ -166,25 +168,25 @@ private fun PassItem(pass: OrbitalPass, navToRadar: (Int, Long) -> Unit, modifie
horizontalArrangement = Arrangement.SpaceBetween,
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(
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
) {
Icon(
@@ -192,9 +194,29 @@ private fun PassItem(pass: OrbitalPass, navToRadar: (Int, Long) -> Unit, modifie
contentDescription = null,
modifier = Modifier.size(16.dp)
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = " ${pass.altitude} km",
textAlign = TextAlign.Start,
text = "${pass.altitude} km",
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
)
}
@@ -211,11 +233,7 @@ private fun PassItem(pass: OrbitalPass, navToRadar: (Int, Long) -> Unit, modifie
)
LinearProgressIndicator(
progress = { if (pass.isDeepSpace) 100f else pass.progress },
modifier = modifier
.fillMaxWidth(0.75f)
.padding(top = 2.dp),
color = MaterialTheme.colorScheme.primary,
trackColor = MaterialTheme.colorScheme.secondaryContainer
modifier = modifier.fillMaxWidth(0.75f)
)
Text(
text = if (pass.isDeepSpace) defaultTime else sdfTime.format(Date(pass.losTime)),
@@ -1,5 +1,7 @@
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.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
@@ -8,7 +10,10 @@ import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
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.rotate
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.TextStyle
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer
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.PI_2
import com.rtbishop.look4sat.domain.utility.toRadians
import kotlin.math.abs
import kotlin.math.cos
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.sin
import kotlin.math.sqrt
@Composable
fun RadarViewCompose(item: OrbitalPos, items: List<OrbitalPos>, azimElev: Pair<Float, Float>) {
val viewModel = viewModel(RadarViewModel::class.java, factory = RadarViewModel.Factory)
val radarColor: Color = if (viewModel.stateOfOldScheme) Color(0xFFDCDCDC) else MaterialTheme.colorScheme.tertiary
val primaryColor: Color = if (viewModel.stateOfOldScheme) Color(0xFFFFE082) else MaterialTheme.colorScheme.primary
val secondaryColor: Color = if (viewModel.stateOfOldScheme) Color(0xFFDC0000) else MaterialTheme.colorScheme.onSurface
val context = LocalContext.current
val view = LocalView.current
val radarColor = MaterialTheme.colorScheme.secondary
val trackColor = MaterialTheme.colorScheme.primary
val aimColor = MaterialTheme.colorScheme.error
val strokeWidth = 4f
val animTransition = rememberInfiniteTransition(label = "animScale")
val animSpec = infiniteRepeatable<Float>(tween(1000))
val animScale = animTransition.animateFloat(16f, 64f, animSpec, label = "animScale")
val aimThreshold = 0.05f
val measurer = rememberTextMeasurer()
val sweepDegrees = remember { mutableFloatStateOf(0f) }
val trackCreated = remember { mutableStateOf(false) }
val trackPath = remember { mutableStateOf(Path()) }
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()) {
val radius = (size.minDimension / 2f) * 0.95f
if (!trackCreated.value) {
@@ -60,13 +139,13 @@ fun RadarViewCompose(item: OrbitalPos, items: List<OrbitalPos>, azimElev: Pair<F
trackCreated.value = true
}
rotate(-azimElev.first) {
drawSweep(center, sweepDegrees.floatValue, radius, primaryColor)
drawSweep(center, sweepDegrees.floatValue, radius, trackColor)
drawRadar(radius, radarColor, strokeWidth, 3)
drawInfo(radius, primaryColor, measurer, 3)
drawInfo(radius, trackColor, measurer, 3)
translate(center.x, center.y) {
drawTrack(trackPath.value, trackEffect.value, secondaryColor, primaryColor)
if (item.elevation > 0) drawPosition(item, radius, animScale.value, primaryColor)
drawAim(azimElev.first, azimElev.second, radius, strokeWidth, secondaryColor)
drawTrack(trackPath.value, trackEffect.value, aimColor, trackColor)
if (item.elevation > 0) drawPosition(item, radius, animScale.value, trackColor)
drawAim(azimElev.first, azimElev.second, radius, strokeWidth, aimColor)
}
sweepDegrees.floatValue = (sweepDegrees.floatValue + 360 / 12.0f / 60) % 360
}
@@ -56,7 +56,7 @@ class RadarViewModel(
private val stationPos = settingsRepo.stationPosition.value
private val magDeclination = getMagDeclination(stationPos)
val stateOfOldScheme = settingsRepo.otherSettings.value.stateOfOldScheme
val stateOfLightTheme = settingsRepo.otherSettings.value.stateOfLightTheme
val transmitters = mutableStateOf<List<SatRadio>>(emptyList())
val radarData = mutableStateOf<RadarData?>(null)
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.window.Dialog
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
@Preview(showBackground = true)
@@ -36,7 +36,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.domain.model.OtherSettings
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.gotoUrl
import com.rtbishop.look4sat.presentation.components.showToast
@@ -110,7 +110,7 @@ fun SettingsScreen() {
val toggleUpdate = { value: Boolean -> viewModel.toggleUpdate(value) }
val toggleSweep = { value: Boolean -> viewModel.toggleSweep(value) }
val toggleSensor = { value: Boolean -> viewModel.toggleSensor(value) }
val toggleOldScheme = { value: Boolean -> viewModel.toggleOldScheme(value)}
val toggleLightTheme = { value: Boolean -> viewModel.toggleLightTheme(value)}
// Screen setup
val versionName = context.packageManager.getPackageInfo(context.packageName, 0).versionName ?: "4.0.0"
@@ -118,7 +118,7 @@ fun SettingsScreen() {
item { CardAbout(versionName) }
item { LocationCard(positionSettings, setGpsPos, showPosDialog, showLocDialog, dismissPos) }
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(
painter = painterResource(id = R.drawable.ic_sputnik),
tint = MaterialTheme.colorScheme.secondary,
tint = MaterialTheme.colorScheme.primary,
contentDescription = null,
modifier = Modifier.size(72.dp)
)
@@ -148,7 +148,7 @@ private fun CardAbout(version: String, modifier: Modifier = Modifier) {
Text(
text = stringResource(id = R.string.app_name),
fontSize = 48.sp,
color = MaterialTheme.colorScheme.secondary
color = MaterialTheme.colorScheme.primary
)
Text(
text = stringResource(id = R.string.app_version, version), fontSize = 20.sp
@@ -374,7 +374,7 @@ private fun OtherCardPreview() = MainTheme {
stateOfSensors = true,
stateOfSweep = true,
stateOfUtc = false,
stateOfOldScheme = false)
stateOfLightTheme = false)
OtherCard(settings = values, {}, {}, {}, {},{})
}
@@ -385,7 +385,7 @@ private fun OtherCard(
toggleUpdate: (Boolean) -> Unit,
toggleSweep: (Boolean) -> Unit,
toggleSensor: (Boolean) -> Unit,
toggleOldScheme: (Boolean) -> Unit
toggleLightTheme: (Boolean) -> Unit
) {
ElevatedCard(modifier = Modifier.fillMaxWidth()) {
Column(modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp)) {
@@ -426,8 +426,8 @@ private fun OtherCard(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Text(text = stringResource(id = R.string.other_switch_old_scheme))
Switch(checked = settings.stateOfOldScheme, onCheckedChange = { toggleOldScheme(it) })
Text(text = stringResource(id = R.string.other_switch_light_theme))
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) {
LinearProgressIndicator(
modifier = modifier.padding(start = 6.dp),
color = MaterialTheme.colorScheme.primary,
trackColor = MaterialTheme.colorScheme.secondaryContainer
// color = MaterialTheme.colorScheme.primary,
// trackColor = MaterialTheme.colorScheme.secondaryContainer
)
} else {
LinearProgressIndicator(
progress = { 0f },
modifier = modifier.padding(start = 6.dp),
color = MaterialTheme.colorScheme.primary,
trackColor = MaterialTheme.colorScheme.secondaryContainer
// color = MaterialTheme.colorScheme.primary,
// trackColor = MaterialTheme.colorScheme.secondaryContainer
)
}
@@ -129,7 +129,7 @@ class SettingsViewModel(
fun toggleUpdate(value: Boolean) = settingsRepo.setStateOfAutoUpdate(value)
fun toggleSweep(value: Boolean) = settingsRepo.setStateOfSweep(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 setRotatorEnabled(value: Boolean) = settings.setRotatorEnabled(value)
// 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_sweep">• Показывать анимацию радара</string>
<string name="other_switch_sensors">• Использовать сенсоры устройства</string>
<string name="other_switch_light_theme">• Использовать светлую тему</string>
<string name="outro_title">Я хотел бы сказать спасибо:</string>
<string name="outro_thanks">• Вам за использование этого приложения! \nЖелаю всегда чистого неба над головой!
@@ -178,5 +179,4 @@
за интерес к приложению и публикацию интервью на сайте.
</string>
<string name="outro_license">Это ПО поставляется без гарантий.</string>
<string name="other_switch_old_scheme">• Используйте старую цветовую схему.</string>
</resources>
+1 -1
View File
@@ -162,6 +162,7 @@
<string name="other_switch_update">• ස්වයං දත්ත යාවත්කාලීනය</string>
<string name="other_switch_sweep">• radar sweep සජීවිකරණය සබල කරන්න</string>
<string name="other_switch_sensors">• Radar දර්ශනය කරකැවීමට සංවේදක භාවිතා කරන්න </string>
<string name="other_switch_light_theme">• සැහැල්ලු තේමාව භාවිතා කරන්න</string>
<string name="outro_title">මම ස්තුති කිරීමට කැමති:</string>
<string name="outro_thanks">• බාගෙන භාවිතා කළ ඔබට! \nඅහස සදා ඔබ වෙනුවෙන් පැහැදිලියි!
@@ -175,5 +176,4 @@
<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>
<string name="outro_license">මෘදුකාංගය වගකීමක් සමග නොලැබේ</string>
<string name="other_switch_old_scheme">• පැරණි වර්ණ පටිපාටිය භාවිතා කරන්න</string>
</resources>
+1 -1
View File
@@ -162,6 +162,7 @@
<string name="other_switch_update">• 启用卫星数据自动更新</string>
<string name="other_switch_sweep">• 启用雷达扫描动画</string>
<string name="other_switch_sensors">• 使用传感器旋转雷达视图</string>
<string name="other_switch_light_theme">• 使用旧版配色方案</string>
<string name="outro_title">我要感谢:</string>
<string name="outro_thanks">• 感谢下载和使用 Look4Sat!愿你的天空永远晴朗!
@@ -179,5 +180,4 @@
team for their interest to the app and the interview published.
</string>
<string name="outro_license">该应用程序不提供任何保修.</string>
<string name="other_switch_old_scheme">• 使用旧版配色方案</string>
</resources>
+2 -2
View File
@@ -77,7 +77,7 @@
<string name="pass_satName">%s</string>
<string name="pass_satId">Id:%05d</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_losAz">%.1f° - LOS</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_sweep">• Enable radar sweep animation</string>
<string name="other_switch_sensors">• Use sensors to rotate radar view</string>
<string name="other_switch_light_theme">• Use light theme</string>
<string name="outro_title">I would like to say thanks to:</string>
<string name="outro_thanks">• You for downloading and using Look4Sat! \nMay your sky always be clear!
@@ -180,5 +181,4 @@
team for their interest to the app and the interview published.
</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>
@@ -19,9 +19,9 @@ package com.rtbishop.look4sat.data.repository
import android.content.SharedPreferences
import android.location.LocationManager
import android.os.CancellationSignal
import androidx.core.content.edit
import androidx.core.location.LocationManagerCompat
import androidx.core.os.CancellationSignal
import com.rtbishop.look4sat.domain.model.DatabaseState
import com.rtbishop.look4sat.domain.model.OtherSettings
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 keyStateOfSweep = "stateOfSweep"
private val keyStateOfUtc = "stateOfUtc"
private val keyStateOfOldScheme = "stateOfOldScheme"
private val keyStateOfLightTheme = "stateOfLightTheme"
private val keyStationAltitude = "stationAltitude"
private val keyStationLatitude = "stationLatitude"
private val keyStationLongitude = "stationLongitude"
@@ -222,9 +222,9 @@ class SettingsRepo(private val manager: LocationManager, private val preferences
_otherSettings.value = otherSettings.value.copy(stateOfUtc = value)
}
override fun setStateOfOldScheme(value: Boolean){
preferences.edit { putBoolean(keyStateOfOldScheme, value) }
_otherSettings.value = otherSettings.value.copy(stateOfOldScheme = value)
override fun setStateOfLightTheme(value: Boolean){
preferences.edit { putBoolean(keyStateOfLightTheme, value) }
_otherSettings.value = otherSettings.value.copy(stateOfLightTheme = value)
}
private fun getOtherSettings(): OtherSettings {
@@ -232,8 +232,8 @@ class SettingsRepo(private val manager: LocationManager, private val preferences
val stateOfSensors = preferences.getBoolean(keyStateOfSensors, true)
val stateOfSweep = preferences.getBoolean(keyStateOfSweep, true)
val stateOfUtc = preferences.getBoolean(keyStateOfUtc, false)
val stateOfOldScheme = preferences.getBoolean(keyStateOfOldScheme,false)
return OtherSettings(stateOfAutoUpdate, stateOfSensors, stateOfSweep, stateOfUtc,stateOfOldScheme)
val stateOfLightTheme = preferences.getBoolean(keyStateOfLightTheme,false)
return OtherSettings(stateOfAutoUpdate, stateOfSensors, stateOfSweep, stateOfUtc, stateOfLightTheme)
}
//endregion
@@ -1,13 +1,21 @@
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(
val stateOfAutoUpdate: Boolean,
val stateOfSensors: Boolean,
val stateOfSweep: Boolean,
val stateOfUtc: Boolean,
val stateOfOldScheme: Boolean
val stateOfLightTheme: Boolean
)
@@ -55,7 +55,7 @@ interface ISettingsRepo {
fun setStateOfSensors(value: Boolean)
fun setStateOfSweep(value: Boolean)
fun setStateOfUtc(value: Boolean)
fun setStateOfOldScheme(value: Boolean)
fun setStateOfLightTheme(value: Boolean)
//endregion
//region # Undefined settings
+14 -14
View File
@@ -1,29 +1,29 @@
[versions]
android-gradle-plugin = "8.3.0"
google-ksp = "1.9.22-1.0.17"
kotlin = "1.9.22"
android-gradle-plugin = "8.5.0"
google-ksp = "1.9.24-1.0.20"
kotlin = "1.9.24"
androidx-core-ktx = "1.12.0"
androidx-core-ktx = "1.13.1"
androidx-core-splashscreen = "1.0.1"
androidx-room = "2.6.1"
compose = "1.6.3"
compose-activity = "1.8.2"
compose-compiler = "1.5.10"
compose-lifecycle = "2.7.0"
compose = "1.6.8"
compose-activity = "1.9.0"
compose-compiler = "1.5.14"
compose-lifecycle = "2.8.2"
compose-material3 = "1.2.1"
compose-navigation = "2.7.7"
other-coroutines = "1.7.3"
other-json = "20231013"
other-coroutines = "1.8.1"
other-json = "20240303"
other-okhttp = "4.12.0"
other-osmdroid = "6.1.17"
other-osmdroid = "6.1.18"
test-junit4 = "4.13.2"
test-mockk = "1.13.9"
test-mockk = "1.13.11"
androidTest-junit = "1.1.5"
androidTest-espresso = "3.5.1"
androidTest-junit = "1.2.0"
androidTest-espresso = "3.6.0"
[libraries]
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
distributionBase=GRADLE_USER_HOME
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
zipStorePath=wrapper/dists