diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 95921e4a..a3488121 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -13,7 +13,7 @@
+ android:screenOrientation="portrait"
+ android:theme="@style/Theme.Look4Sat.SplashScreen"
+ tools:ignore="LockedOrientationActivity">
-
diff --git a/app/src/main/java/com/rtbishop/look4sat/MainActivity.kt b/app/src/main/java/com/rtbishop/look4sat/MainActivity.kt
index 11c16578..c543c343 100644
--- a/app/src/main/java/com/rtbishop/look4sat/MainActivity.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/MainActivity.kt
@@ -18,7 +18,6 @@
package com.rtbishop.look4sat
import android.content.Context
-import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.os.Bundle
import androidx.activity.ComponentActivity
@@ -32,15 +31,13 @@ import dagger.hilt.android.AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
- requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
installSplashScreen()
super.onCreate(savedInstanceState)
setContent { MainTheme { MainScreen() } }
}
override fun attachBaseContext(newBase: Context?) {
- val newConfig = Configuration(newBase?.resources?.configuration)
- newConfig.fontScale = 1.0f
+ val newConfig = Configuration(newBase?.resources?.configuration).apply { fontScale = 1.0f }
applyOverrideConfiguration(newConfig)
super.attachBaseContext(newBase)
}
diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/LocationSource.kt b/app/src/main/java/com/rtbishop/look4sat/framework/LocationSource.kt
index bbb0f854..4d80f303 100644
--- a/app/src/main/java/com/rtbishop/look4sat/framework/LocationSource.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/framework/LocationSource.kt
@@ -17,6 +17,7 @@
*/
package com.rtbishop.look4sat.framework
+import android.location.Criteria
import android.location.Location
import android.location.LocationManager
import androidx.core.location.LocationListenerCompat
@@ -35,13 +36,15 @@ class LocationSource(
private val settings: ISettingsSource,
) : ILocationSource, LocationListenerCompat {
+ private val defaultProvider = LocationManager.PASSIVE_PROVIDER
private val _stationPosition = MutableStateFlow(settings.loadStationPosition())
override val stationPosition: StateFlow = _stationPosition
override fun setGpsPosition(): Boolean {
if (!LocationManagerCompat.isLocationEnabled(manager)) return false
- forceLocationUpdate(LocationManager.GPS_PROVIDER)
- forceLocationUpdate(LocationManager.NETWORK_PROVIDER)
+ val criteria = Criteria().apply { isCostAllowed = true }
+ val bestProvider = manager.getBestProvider(criteria, true) ?: defaultProvider
+ forceLocationUpdate(bestProvider)
return true
}
@@ -65,7 +68,7 @@ class LocationSource(
private fun forceLocationUpdate(provider: String) {
try {
- val location = manager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER)
+ val location = manager.getLastKnownLocation(defaultProvider)
if (location == null || System.currentTimeMillis() - location.time > 600000) {
Timber.d("Requesting $provider location update")
manager.requestLocationUpdates(provider, 0L, 0f, this)
diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/SettingsSource.kt b/app/src/main/java/com/rtbishop/look4sat/framework/SettingsSource.kt
index 725be84c..3d7dc8be 100644
--- a/app/src/main/java/com/rtbishop/look4sat/framework/SettingsSource.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/framework/SettingsSource.kt
@@ -50,7 +50,7 @@ class SettingsSource(private val prefs: SharedPreferences) : ISettingsSource {
override fun loadStationPosition(): StationPos {
val latitude = prefs.getString(keyLatitude, null) ?: "0.0"
val longitude = prefs.getString(keyLongitude, null) ?: "0.0"
- val qthLocator = prefs.getString(keyLocator, null) ?: ""
+ val qthLocator = prefs.getString(keyLocator, null) ?: "null"
val timestamp = prefs.getLong(keyLocTimestamp, 0L)
return StationPos(latitude.toDouble(), longitude.toDouble(), qthLocator, timestamp)
}
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/MainComponents.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/Components.kt
similarity index 96%
rename from app/src/main/java/com/rtbishop/look4sat/presentation/MainComponents.kt
rename to app/src/main/java/com/rtbishop/look4sat/presentation/Components.kt
index 3881b1d5..6e45b6e5 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/MainComponents.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/Components.kt
@@ -9,7 +9,6 @@ import androidx.compose.foundation.interaction.Interaction
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
@@ -28,7 +27,7 @@ fun CardButton(onClick: () -> Unit, text: String, modifier: Modifier = Modifier)
onClick = { onClick() }, colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.tertiary,
contentColor = MaterialTheme.colorScheme.onTertiary
- ), shape = MaterialTheme.shapes.small, modifier = modifier.padding(start = 4.dp, end = 4.dp)
+ ), shape = MaterialTheme.shapes.small, modifier = modifier
) { Text(text = text, fontSize = 17.sp) }
}
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/MainScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/MainScreen.kt
index 20e69fdb..721f36fe 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/MainScreen.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/MainScreen.kt
@@ -60,14 +60,18 @@ private fun MainNavBar(navController: NavController) {
@Composable
private fun MainNavGraph(navController: NavHostController) {
+ val navToPasses = { navController.navigate(Screen.Passes.route) }
+ val navToRadar = { catNum: Int, aosTime: Long ->
+ navController.navigate("${Screen.Radar.route}?catNum=${catNum}&aosTime=${aosTime}")
+ }
val radarRoute = "${Screen.Radar.route}?catNum={catNum}&aosTime={aosTime}"
val radarArgs = listOf(navArgument("catNum") { defaultValue = 0 },
navArgument("aosTime") { defaultValue = 0L })
NavHost(navController, startDestination = Screen.Passes.route) {
- composable(Screen.Entries.route) { EntriesScreen(navController) }
- composable(Screen.Passes.route) { PassesScreen(navController) }
- composable(radarRoute, radarArgs) { RadarScreen(navController) }
+ composable(Screen.Entries.route) { EntriesScreen(navToPasses) }
+ composable(Screen.Passes.route) { PassesScreen(navToRadar) }
+ composable(radarRoute, radarArgs) { RadarScreen() }
composable(Screen.Map.route) { MapScreen() }
- composable(Screen.Settings.route) { SettingsScreen(navController) }
+ composable(Screen.Settings.route) { SettingsScreen() }
}
}
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesScreen.kt
index 9ebd186c..5f4e934b 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesScreen.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/entries/EntriesScreen.kt
@@ -26,21 +26,17 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
-import androidx.navigation.NavController
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.model.DataState
import com.rtbishop.look4sat.model.SatItem
import com.rtbishop.look4sat.presentation.CardLoadingIndicator
import com.rtbishop.look4sat.presentation.MainTheme
-import com.rtbishop.look4sat.presentation.Screen
import com.rtbishop.look4sat.presentation.dialogs.TypesDialog
import com.rtbishop.look4sat.presentation.onClick
@Composable
-fun EntriesScreen(navController: NavController) {
- val viewModel: EntriesViewModel = hiltViewModel()
+fun EntriesScreen(navToPasses: () -> Unit, viewModel: EntriesViewModel = hiltViewModel()) {
val state = viewModel.satData.collectAsState(initial = DataState.Loading)
- val navToPasses = { navController.navigate(Screen.Passes.route) }
val showDialog = rememberSaveable { mutableStateOf(false) }
val toggleDialog = { showDialog.value = showDialog.value.not() }
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/map/MapScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/map/MapScreen.kt
index 2c82c362..8ed372d9 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/map/MapScreen.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/map/MapScreen.kt
@@ -102,8 +102,8 @@ private fun setPositions(
posMap: Map, mapView: MapView, action: (Satellite) -> Unit
) {
val markers = FolderOverlay()
- posMap.entries.forEach {
- try {
+ try {
+ posMap.entries.forEach {
Marker(mapView).apply {
setInfoWindow(null)
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER)
@@ -119,12 +119,12 @@ private fun setPositions(
}
markers.add(this)
}
- } catch (exception: Exception) {
- Timber.d(exception)
}
+ mapView.overlays[3] = markers
+ mapView.invalidate()
+ } catch (exception: Exception) {
+ Timber.d(exception)
}
- mapView.overlays[3] = markers
- mapView.invalidate()
}
private fun getCustomTextIcon(textLabel: String, mapView: MapView): Drawable {
@@ -143,33 +143,33 @@ private fun getCustomTextIcon(textLabel: String, mapView: MapView): Drawable {
private fun setSatelliteTrack(satTrack: List>, mapView: MapView) {
// val center = GeoPoint(satTrack[0][0].lat, satTrack[0][0].lon)
val trackOverlay = FolderOverlay()
- satTrack.forEach { track ->
- val trackPoints = track.map { GeoPoint(it.lat, it.lon) }
- Polyline().apply {
- try {
+ try {
+ satTrack.forEach { track ->
+ val trackPoints = track.map { GeoPoint(it.lat, it.lon) }
+ Polyline().apply {
setPoints(trackPoints)
outlinePaint.set(trackPaint)
trackOverlay.add(this)
- } catch (exception: IllegalArgumentException) {
- println(exception.stackTraceToString())
}
}
+ mapView.overlays[1] = trackOverlay
+ } catch (exception: Exception) {
+ Timber.d(exception)
}
- mapView.overlays[1] = trackOverlay
// mapView.controller.animateTo(center)
}
private fun setFootprint(satPos: SatPos, mapView: MapView) {
val footprintPoints = satPos.getRangeCircle().map { GeoPoint(it.lat, it.lon) }
- val footprintOverlay = Polyline().apply {
- outlinePaint.set(footprintPaint)
- try {
+ try {
+ val footprintOverlay = Polyline().apply {
+ outlinePaint.set(footprintPaint)
setPoints(footprintPoints)
- } catch (exception: IllegalArgumentException) {
- println(exception.stackTraceToString())
}
+ mapView.overlays[2] = footprintOverlay
+ } catch (exception: Exception) {
+ Timber.d(exception)
}
- mapView.overlays[2] = footprintOverlay
}
//private fun handleMapData(mapData: MapData) {
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesScreen.kt
index 011ae921..2de6b221 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesScreen.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesScreen.kt
@@ -21,7 +21,6 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.*
import androidx.hilt.navigation.compose.hiltViewModel
-import androidx.navigation.NavController
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.domain.NearEarthSat
import com.rtbishop.look4sat.model.DataState
@@ -39,11 +38,7 @@ import java.util.*
private val sdf = SimpleDateFormat("HH:mm:ss", Locale.ENGLISH)
@Composable
-fun PassesScreen(navController: NavController) {
- val viewModel: PassesViewModel = hiltViewModel()
- val navToRadar = { catNum: Int, aosTime: Long ->
- navController.navigate("${Screen.Radar.route}?catNum=${catNum}&aosTime=${aosTime}")
- }
+fun PassesScreen(navToRadar: (Int, Long) -> Unit, viewModel: PassesViewModel = hiltViewModel()) {
val state = viewModel.passes.collectAsState(initial = null)
val timerText = viewModel.timerText.collectAsState(initial = null)
val isRefreshing = state.value is DataState.Loading
@@ -185,7 +180,6 @@ private fun Pass(pass: SatPass, navToRadar: (Int, Long) -> Unit, modifier: Modif
modifier = modifier
.fillMaxWidth(0.75f)
.padding(top = 3.dp),
- color = MaterialTheme.colorScheme.primary,
trackColor = MaterialTheme.colorScheme.inverseSurface
)
Text(
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarScreen.kt
index aa8e3e6b..6c6ce37a 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarScreen.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarScreen.kt
@@ -16,13 +16,11 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
-import androidx.navigation.NavController
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.model.SatRadio
@Composable
-fun RadarScreen(navController: NavController) {
- val viewModel: RadarViewModel = hiltViewModel()
+fun RadarScreen(viewModel: RadarViewModel = hiltViewModel()) {
val currentPass = viewModel.getPass().collectAsState(null)
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsScreen.kt
index 6c00cc1c..f33de6a9 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsScreen.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsScreen.kt
@@ -21,15 +21,17 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
-import androidx.navigation.NavController
import com.rtbishop.look4sat.BuildConfig
import com.rtbishop.look4sat.R
+import com.rtbishop.look4sat.model.StationPos
import com.rtbishop.look4sat.presentation.CardButton
import com.rtbishop.look4sat.presentation.MainTheme
import com.rtbishop.look4sat.presentation.dialogs.LocatorDialog
import com.rtbishop.look4sat.presentation.dialogs.PositionDialog
import com.rtbishop.look4sat.presentation.gotoUrl
import com.rtbishop.look4sat.presentation.showToast
+import java.text.SimpleDateFormat
+import java.util.*
private const val POLICY_URL = "https://sites.google.com/view/look4sat-privacy-policy/home"
private const val LICENSE_URL = "https://www.gnu.org/licenses/gpl-3.0.html"
@@ -38,9 +40,8 @@ private const val DONATE_URL = "https://ko-fi.com/rt_bishop"
private const val FDROID_URL = "https://f-droid.org/en/packages/com.rtbishop.look4sat/"
@Composable
-fun SettingsScreen(navController: NavController) {
+fun SettingsScreen(viewModel: SettingsViewModel = hiltViewModel()) {
val context = LocalContext.current
- val viewModel: SettingsViewModel = hiltViewModel()
// Permissions setup
val bluetoothContract = ActivityResultContracts.RequestPermission()
@@ -76,8 +77,8 @@ fun SettingsScreen(navController: NavController) {
val togglePosDialog = { showPosDialog.value = showPosDialog.value.not() }
if (showPosDialog.value) {
PositionDialog(
- locSettings.getLatitude,
- locSettings.getLongitude,
+ locSettings.stationPos.latitude,
+ locSettings.stationPos.longitude,
togglePosDialog,
locSettings.setManualLoc
)
@@ -85,7 +86,7 @@ fun SettingsScreen(navController: NavController) {
val showLocDialog = rememberSaveable { mutableStateOf(false) }
val toggleLocDialog = { showLocDialog.value = showLocDialog.value.not() }
if (showLocDialog.value) {
- LocatorDialog(locSettings.getLocator, toggleLocDialog, locSettings.setQthLoc)
+ LocatorDialog(locSettings.stationPos.qthLocator, toggleLocDialog, locSettings.setQthLoc)
}
// Screen setup
@@ -100,11 +101,18 @@ fun SettingsScreen(navController: NavController) {
}
}
+@Preview(showBackground = true)
+@Composable
+private fun CardAboutPreview() = MainTheme { CardAbout(version = "4.0.0") }
+
@Composable
private fun CardAbout(version: String, modifier: Modifier = Modifier) {
val context = LocalContext.current
ElevatedCard(modifier = modifier.fillMaxWidth()) {
- Column(horizontalAlignment = Alignment.CenterHorizontally) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
+ ) {
Row(horizontalArrangement = Arrangement.Center) {
Icon(
painter = painterResource(id = R.drawable.ic_entries),
@@ -128,21 +136,21 @@ private fun CardAbout(version: String, modifier: Modifier = Modifier) {
Text(
text = stringResource(id = R.string.app_subtitle),
fontSize = 20.sp,
- modifier = modifier.padding(top = 4.dp)
+ modifier = modifier.padding(top = 4.dp, bottom = 2.dp)
)
- Row(
- horizontalArrangement = Arrangement.SpaceEvenly, modifier = Modifier.padding(4.dp)
- ) {
+ Row(horizontalArrangement = Arrangement.SpaceEvenly) {
CardButton(
onClick = { gotoUrl(context, GITHUB_URL) },
text = stringResource(id = R.string.btn_github),
modifier = Modifier.weight(1f)
)
+ Spacer(modifier = Modifier.width(6.dp))
CardButton(
onClick = { gotoUrl(context, DONATE_URL) },
text = stringResource(id = R.string.btn_donate),
modifier = Modifier.weight(1f)
)
+ Spacer(modifier = Modifier.width(6.dp))
CardButton(
onClick = { gotoUrl(context, FDROID_URL) },
text = stringResource(id = R.string.btn_fdroid),
@@ -155,8 +163,11 @@ private fun CardAbout(version: String, modifier: Modifier = Modifier) {
@Preview(showBackground = true)
@Composable
-private fun LocationCardPreview() {
- MainTheme { }
+private fun LocationCardPreview() = MainTheme {
+ val stationPos = StationPos(0.0, 0.0, "IO91vl", 0L)
+ LocationCard(
+ settings = LocationSettings(true, stationPos, {}, { _, _ -> }, { }),
+ setGpsLoc = {}, togglePosDialog = {}) {}
}
@Composable
@@ -167,36 +178,56 @@ private fun LocationCard(
toggleLocDialog: () -> Unit
) {
ElevatedCard(modifier = Modifier.fillMaxWidth()) {
- Column(modifier = Modifier.padding(4.dp)) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
+ ) {
Row(verticalAlignment = Alignment.CenterVertically) {
- Text(text = "Station position")
- UpdateIndicator(isUpdating = settings.getUpdating, Modifier.weight(1f))
+ Text(
+ text = stringResource(id = R.string.location_title),
+ color = MaterialTheme.colorScheme.primary
+ )
+ UpdateIndicator(isUpdating = settings.isUpdating, Modifier.weight(1f))
}
- Row(
- horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()
- ) {
- Text(text = "Updated: ${settings.getLastUpdated}")
- Text(text = "QTH: ${settings.getLocator}")
- }
- Row(
- horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()
- ) {
- Text(text = "Latitude: ${settings.getLatitude}")
- Text(text = "Longitude: ${settings.getLongitude}")
+ Spacer(modifier = Modifier.height(2.dp))
+ Text(text = setUpdateTime(updateTime = settings.stationPos.timestamp))
+ Spacer(modifier = Modifier.height(2.dp))
+ Row(horizontalArrangement = Arrangement.SpaceBetween) {
+ Text(
+ text = "Lat: ${settings.stationPos.latitude}°",
+ modifier = Modifier.weight(1f),
+ textAlign = TextAlign.Start
+ )
+ Text(
+ text = "Lon: ${settings.stationPos.longitude}°",
+ modifier = Modifier.weight(1f),
+ textAlign = TextAlign.Center
+ )
+ Text(
+ text = "Qth: ${settings.stationPos.qthLocator}",
+ modifier = Modifier.weight(1f),
+ textAlign = TextAlign.End
+ )
}
+ Spacer(modifier = Modifier.height(1.dp))
Row(horizontalArrangement = Arrangement.SpaceEvenly) {
CardButton(
- onClick = setGpsLoc, // locationRequest.launch(arrayOf(locationFine, locationCoarse))
- text = stringResource(id = R.string.btn_gps), modifier = Modifier.weight(1f)
+ onClick = setGpsLoc,
+ text = stringResource(id = R.string.btn_gps),
+ modifier = Modifier.weight(1f)
)
+ Spacer(modifier = Modifier.width(6.dp))
CardButton(
- onClick = togglePosDialog, // open Position dialog
- text = stringResource(id = R.string.btn_manual), modifier = Modifier.weight(1f)
- ) // viewModel.setStationPosition(position.first, position.second)
+ onClick = togglePosDialog,
+ text = stringResource(id = R.string.btn_manual),
+ modifier = Modifier.weight(1f)
+ )
+ Spacer(modifier = Modifier.width(6.dp))
CardButton(
- onClick = toggleLocDialog, // open Locator dialog
- text = stringResource(id = R.string.btn_qth), modifier = Modifier.weight(1f)
- ) // viewModel.setPositionFromQth(locator)
+ onClick = toggleLocDialog,
+ text = stringResource(id = R.string.btn_qth),
+ modifier = Modifier.weight(1f)
+ )
}
}
}
@@ -204,42 +235,52 @@ private fun LocationCard(
@Preview(showBackground = true)
@Composable
-private fun DataCardPreview() {
- MainTheme { }
+private fun DataCardPreview() = MainTheme {
+ DataCard(settings = DataSettings(
+ true, 0L, 5000, 2500, {}, { }, {})
+ ) {}
}
@Composable
private fun DataCard(settings: DataSettings, updateFromFile: () -> Unit) {
ElevatedCard(modifier = Modifier.fillMaxWidth()) {
- Column(modifier = Modifier.padding(4.dp)) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
+ ) {
Row(verticalAlignment = Alignment.CenterVertically) {
- Text(text = "Satellite data")
- UpdateIndicator(isUpdating = settings.getUpdating, Modifier.weight(1f))
+ Text(
+ text = stringResource(id = R.string.data_title),
+ color = MaterialTheme.colorScheme.primary
+ )
+ UpdateIndicator(isUpdating = settings.isUpdating, Modifier.weight(1f))
}
- Row(
- horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()
- ) {
- Text(text = "Updated: ${settings.getLastUpdated}")
- Text(text = "")
- }
- Row(
- horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()
- ) {
- Text(text = "Satellites: ${settings.getSatellites}")
- Text(text = "Transceivers: ${settings.getRadios}")
+ Spacer(modifier = Modifier.height(2.dp))
+ Text(text = setUpdateTime(updateTime = settings.lastUpdated))
+ Spacer(modifier = Modifier.height(2.dp))
+ Row(horizontalArrangement = Arrangement.SpaceBetween) {
+ Text(text = "Satellites: ${settings.satsTotal}")
+ Spacer(modifier = Modifier.weight(1f))
+ Text(text = "Transceivers: ${settings.radiosTotal}")
}
+ Spacer(modifier = Modifier.height(1.dp))
Row(horizontalArrangement = Arrangement.SpaceEvenly) {
CardButton(
- onClick = settings.updateFromWeb, // viewModel.updateFromWeb()
- text = stringResource(id = R.string.btn_web), modifier = Modifier.weight(1f)
+ onClick = settings.updateFromWeb,
+ text = stringResource(id = R.string.btn_web),
+ modifier = Modifier.weight(1f)
)
+ Spacer(modifier = Modifier.width(6.dp))
CardButton(
- onClick = updateFromFile, // contentRequest.launch("*/*")
- text = stringResource(id = R.string.btn_file), modifier = Modifier.weight(1f)
+ onClick = updateFromFile,
+ text = stringResource(id = R.string.btn_file),
+ modifier = Modifier.weight(1f)
)
+ Spacer(modifier = Modifier.width(6.dp))
CardButton(
- onClick = settings.clearAllData, // viewModel.clearAllData()
- text = stringResource(id = R.string.btn_clear), modifier = Modifier.weight(1f)
+ onClick = settings.clearAllData,
+ text = stringResource(id = R.string.btn_clear),
+ modifier = Modifier.weight(1f)
)
}
}
@@ -293,15 +334,17 @@ private fun DataCard(settings: DataSettings, updateFromFile: () -> Unit) {
//
@Preview(showBackground = true)
@Composable
-private fun OtherCardPreview() {
- MainTheme { }
+private fun OtherCardPreview() = MainTheme {
+ OtherCard(settings = OtherSettings(
+ getUtc = false, getUpdate = true, getSweep = true, getSensor = true,
+ setUtc = {}, setUpdate = {}, setSweep = {}, setSensor = {})
+ )
}
@Composable
private fun OtherCard(settings: OtherSettings) {
ElevatedCard(modifier = Modifier.fillMaxWidth()) {
- Column(modifier = Modifier.padding(4.dp)) {
- Text(text = stringResource(id = R.string.other_title))
+ Column(modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp)) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
@@ -309,7 +352,7 @@ private fun OtherCard(settings: OtherSettings) {
) {
Text(text = stringResource(id = R.string.other_switch_utc))
Switch(checked = settings.getUtc, onCheckedChange = { settings.setUtc(it) })
- } // viewModel.setUseUTC(isChecked)
+ }
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
@@ -317,7 +360,7 @@ private fun OtherCard(settings: OtherSettings) {
) {
Text(text = stringResource(id = R.string.other_switch_update))
Switch(checked = settings.getUpdate, onCheckedChange = { settings.setUpdate(it) })
- } // AutoUpdateEnabled(isChecked)
+ }
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
@@ -325,7 +368,7 @@ private fun OtherCard(settings: OtherSettings) {
) {
Text(text = stringResource(id = R.string.other_switch_sweep))
Switch(checked = settings.getSweep, onCheckedChange = { settings.setSweep(it) })
- } // viewModel.setShowSweep(isChecked)
+ }
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
@@ -333,58 +376,49 @@ private fun OtherCard(settings: OtherSettings) {
) {
Text(text = stringResource(id = R.string.other_switch_sensors))
Switch(checked = settings.getSensor, onCheckedChange = { settings.setSensor(it) })
- } // viewModel.setUseCompass(isChecked)
+ }
}
}
}
-//
-// showToast(getString(R.string.data_clear_success))
-// showToast(getString(R.string.data_success))
-//
-//private fun setUpdateTime(updateTime: Long) {
-// val updatePattern = getString(R.string.data_update)
-// val updateDate = if (updateTime == 0L) {
-// getString(R.string.pass_placeholder)
-// } else {
-// SimpleDateFormat("d MMM yyyy - HH:mm:ss", Locale.getDefault()).format(Date(updateTime))
-// }
-// binding.settingsData.dataUpdate.text = String.format(updatePattern, updateDate)
-//}
-//
+@Preview(showBackground = true)
+@Composable
+private fun CardCreditsPreview() = MainTheme { CardCredits() }
+
@Composable
private fun CardCredits(modifier: Modifier = Modifier) {
val context = LocalContext.current
ElevatedCard(modifier = modifier.fillMaxWidth()) {
- Column(horizontalAlignment = Alignment.CenterHorizontally) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
+ ) {
Text(
text = stringResource(id = R.string.outro_title),
fontSize = 18.sp,
fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.secondary,
- modifier = modifier.padding(8.dp)
+ modifier = modifier.padding(6.dp)
)
Text(
text = stringResource(id = R.string.outro_thanks),
fontSize = 16.sp,
- textAlign = TextAlign.Center,
- modifier = modifier.padding(horizontal = 6.dp, vertical = 4.dp)
+ textAlign = TextAlign.Center
)
Text(
text = stringResource(id = R.string.outro_license),
fontSize = 18.sp,
fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.secondary,
- modifier = modifier.padding(8.dp)
+ modifier = modifier.padding(6.dp)
)
- Row(
- horizontalArrangement = Arrangement.SpaceEvenly, modifier = Modifier.padding(4.dp)
- ) {
+ Row(horizontalArrangement = Arrangement.SpaceEvenly) {
CardButton(
onClick = { gotoUrl(context, LICENSE_URL) },
text = stringResource(id = R.string.btn_license),
modifier = Modifier.weight(1f)
)
+ Spacer(modifier = Modifier.width(6.dp))
CardButton(
onClick = { gotoUrl(context, POLICY_URL) },
text = stringResource(id = R.string.btn_privacy),
@@ -396,8 +430,26 @@ private fun CardCredits(modifier: Modifier = Modifier) {
}
@Composable
-private fun UpdateIndicator(isUpdating: Boolean, modifier: Modifier = Modifier) = if (isUpdating) {
- LinearProgressIndicator(modifier = modifier.padding(start = 6.dp, end = 6.dp))
-} else {
- LinearProgressIndicator(modifier = modifier.padding(start = 6.dp, end = 6.dp), progress = 0f)
+private fun setUpdateTime(updateTime: Long): String {
+ val updateDate = if (updateTime != 0L) {
+ val timePattern = stringResource(id = R.string.last_updated_pattern)
+ SimpleDateFormat(timePattern, Locale.getDefault()).format(Date(updateTime))
+ } else {
+ stringResource(id = R.string.pass_placeholder)
+ }
+ return stringResource(id = R.string.data_update, updateDate)
+}
+
+@Composable
+private fun UpdateIndicator(isUpdating: Boolean, modifier: Modifier = Modifier) = if (isUpdating) {
+ LinearProgressIndicator(
+ modifier = modifier.padding(start = 6.dp),
+ trackColor = MaterialTheme.colorScheme.inverseSurface
+ )
+} else {
+ LinearProgressIndicator(
+ progress = 0f,
+ modifier = modifier.padding(start = 6.dp),
+ trackColor = MaterialTheme.colorScheme.inverseSurface
+ )
}
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsScreenState.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsScreenState.kt
index c80ca3e1..5434d4e7 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsScreenState.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsScreenState.kt
@@ -1,21 +1,20 @@
package com.rtbishop.look4sat.presentation.settings
+import com.rtbishop.look4sat.model.StationPos
+
data class LocationSettings(
- val getUpdating: Boolean,
- val getLastUpdated: Long,
- val getLatitude: Double,
- val getLongitude: Double,
- val getLocator: String,
+ val isUpdating: Boolean,
+ val stationPos: StationPos,
val setGpsLoc: () -> Unit,
val setManualLoc: (Double, Double) -> Unit,
val setQthLoc: (String) -> Unit
)
data class DataSettings(
- val getUpdating: Boolean,
- val getLastUpdated: Long,
- val getSatellites: Int,
- val getRadios: Int,
+ val isUpdating: Boolean,
+ val lastUpdated: Long,
+ val satsTotal: Int,
+ val radiosTotal: Int,
val updateFromWeb: () -> Unit,
val updateFromFile: (String) -> Unit,
val clearAllData: () -> Unit
diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsViewModel.kt
index e6c1875f..6c6d168c 100644
--- a/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsViewModel.kt
+++ b/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsViewModel.kt
@@ -25,6 +25,7 @@ import com.rtbishop.look4sat.domain.ILocationSource
import com.rtbishop.look4sat.domain.ISettingsSource
import com.rtbishop.look4sat.model.DataState
import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -37,11 +38,8 @@ class SettingsViewModel @Inject constructor(
) : ViewModel() {
private val defaultLocationSettings = LocationSettings(false,
- locationSource.stationPosition.value.timestamp,
- locationSource.stationPosition.value.latitude,
- locationSource.stationPosition.value.longitude,
- locationSource.stationPosition.value.qthLocator,
- { locationSource.setGpsPosition() },
+ locationSource.stationPosition.value,
+ { updateStationPosition() },
{ lat, lon -> locationSource.setGeoPosition(lat, lon) },
{ locationSource.setQthPosition(it) })
val locationSettings = mutableStateOf(defaultLocationSettings)
@@ -66,22 +64,34 @@ class SettingsViewModel @Inject constructor(
val otherSettings = mutableStateOf(defaultOtherSettings)
init {
+ viewModelScope.launch {
+ locationSource.stationPosition.collect { stationPos ->
+ delay(125)
+ locationSettings.value = locationSettings.value.copy(
+ isUpdating = false, stationPos = stationPos
+ )
+ }
+ }
viewModelScope.launch {
repository.updateState.collect {
val isUpdating = it is DataState.Loading
dataSettings.value = dataSettings.value.copy(
- getUpdating = isUpdating, getLastUpdated = settings.getLastUpdateTime()
+ isUpdating = isUpdating, lastUpdated = settings.getLastUpdateTime()
)
}
}
viewModelScope.launch {
combine(repository.getEntriesTotal(), repository.getRadiosTotal()) { sats, radios ->
- dataSettings.value =
- dataSettings.value.copy(getSatellites = sats, getRadios = radios)
+ dataSettings.value = dataSettings.value.copy(satsTotal = sats, radiosTotal = radios)
}.collect {}
}
}
+ private fun updateStationPosition() {
+ val isSuccessful = locationSource.setGpsPosition()
+ locationSettings.value = locationSettings.value.copy(isUpdating = isSuccessful)
+ }
+
private fun setUtc(value: Boolean) {
settings.setUtcState(value)
otherSettings.value = otherSettings.value.copy(getUtc = value)
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index d11510fe..7bfb23f2 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -158,24 +158,23 @@
Формат данных
Нет разрешения использовать bluetooth
- Другие настройки
- Показывать время по UTC
- Обновлять данные автоматически
- Показывать анимацию радара
- Использовать сенсоры устройства
+ • Показывать время по UTC
+ • Обновлять данные автоматически
+ • Показывать анимацию радара
+ • Использовать сенсоры устройства
Я хотел бы сказать спасибо:
- • Вам за использование этого приложения! \nЖелаю всегда чистого неба над головой!
- \n • David A. B. Johnson и
+ • Вам за использование этого приложения! \nЖелаю всегда чистого неба над головой!
+ \n• David A. B. Johnson и
Dave Moten за работу над predict4java и доступ
к ней по GNU GPLv2
- \n • Alexandru Csete за его программу
+ \n• Alexandru Csete за его программу
Gpredict, которая послужила для меня вдохновением.
- \n • Доктору T.S. Kelso за его сайт
+ \n• Доктору T.S. Kelso за его сайт
Celestrak и доступ к файлам орбит Two-Line Element.
- \n • Libre Space Foundation за проект
+ \n• Libre Space Foundation за проект
SatNOGS, API и базу данных с информацией о спутниках.
- \n • DownloadAstro
+ \n• DownloadAstro
за интерес к приложению и публикацию интервью на сайте.
Это ПО поставляется без гарантий.
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 9ab3f9b6..c870ada7 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -158,25 +158,24 @@
数据格式
请检查蓝牙权限
- 其他偏好
- 以 UTC 时间显示
- 启用卫星数据自动更新
- 启用雷达扫描动画
- 使用传感器旋转雷达视图
+ • 以 UTC 时间显示
+ • 启用卫星数据自动更新
+ • 启用雷达扫描动画
+ • 使用传感器旋转雷达视图
我要感谢:
• 感谢下载和使用 Look4Sat!愿你的天空永远晴朗!
- \n • 简体中文版翻译由 BA7LWN 于 2022.5.10 创建。
- \n • David A. B. Johnson
+ \n• 简体中文版翻译由 BA7LWN 于 2022.5.10 创建。
+ \n• David A. B. Johnson
and Dave Moten for creating predict4java lib
under the GNU GPLv2.
- \n • Alexandru Csete for creating Gpredict
+ \n• Alexandru Csete for creating Gpredict
satellite tracker that inspired the creation of Look4Sat.
- \n • Dr T.S. Kelso for maintaining his
+ \n• Dr T.S. Kelso for maintaining his
Celestrak website that provides access to the TLE data.
- \n • Libre Space Foundation for their
+ \n• Libre Space Foundation for their
SatNOGS API and DB providing a huge amount of satellite data.
- \n • DownloadAstro
+ \n• DownloadAstro
team for their interest to the app and the interview published.
该应用程序不提供任何保修.
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index eae6accc..c770b002 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -147,6 +147,8 @@
Update completed successfully
Data was cleared successfully
+ d MMM yyyy - HH:mm:ss
+
Rotator preferences
Enable remote control
IP address
@@ -158,24 +160,22 @@
Data format
Check your bluetooth permission
- Other preferences
- Show pass time in UTC
- Enable automatic data update
- Enable radar sweep animation
- Use sensors to rotate radar view
+ • Show pass time in UTC
+ • Enable automatic data update
+ • Enable radar sweep animation
+ • Use sensors to rotate radar view
I would like to say thanks to:
• You for downloading and using Look4Sat! \nMay your sky always be clear!
- \n\n• David A. B. Johnson
- and Dave Moten for creating predict4java lib
- under the GNU GPLv2.
- \n\n• Alexandru Csete for creating Gpredict
- satellite tracker that inspired the creation of Look4Sat.
- \n\n• Dr T.S. Kelso for maintaining his
+ \n• David A. B. Johnson
+ and Dave Moten for creating a super useful predict4java library.
+ \n• Alexandru Csete for creating Gpredict
+ tracker that inspired the creation of Look4Sat.
+ \n• Dr T.S. Kelso for maintaining his
Celestrak website that provides access to the TLE data.
- \n\n• Libre Space Foundation for their
+ \n• Libre Space Foundation for their
SatNOGS API and DB providing a huge amount of data.
- \n\n• DownloadAstro
+ \n• DownloadAstro
team for their interest to the app and the interview published.
The app comes with no warranty.