mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Extracted a few UI actions into reusable use cases
This commit is contained in:
1 parent
01139f76e7
commit
11841ca3d7
9 files changed
+343
-147
No files matched your search
@@ -17,6 +17,8 @@ import com.rtbishop.look4sat.data.repository.SettingsRepo
|
|||||||
import com.rtbishop.look4sat.data.source.LocalSource
|
import com.rtbishop.look4sat.data.source.LocalSource
|
||||||
import com.rtbishop.look4sat.data.source.RemoteSource
|
import com.rtbishop.look4sat.data.source.RemoteSource
|
||||||
import com.rtbishop.look4sat.data.usecase.AddToCalendar
|
import com.rtbishop.look4sat.data.usecase.AddToCalendar
|
||||||
|
import com.rtbishop.look4sat.data.usecase.OpenWebUrl
|
||||||
|
import com.rtbishop.look4sat.data.usecase.ShowToast
|
||||||
import com.rtbishop.look4sat.domain.repository.IDatabaseRepo
|
import com.rtbishop.look4sat.domain.repository.IDatabaseRepo
|
||||||
import com.rtbishop.look4sat.domain.repository.ISatelliteRepo
|
import com.rtbishop.look4sat.domain.repository.ISatelliteRepo
|
||||||
import com.rtbishop.look4sat.domain.repository.ISelectionRepo
|
import com.rtbishop.look4sat.domain.repository.ISelectionRepo
|
||||||
@@ -25,6 +27,8 @@ import com.rtbishop.look4sat.domain.repository.ISettingsRepo
|
|||||||
import com.rtbishop.look4sat.domain.source.ILocalSource
|
import com.rtbishop.look4sat.domain.source.ILocalSource
|
||||||
import com.rtbishop.look4sat.domain.source.IRemoteSource
|
import com.rtbishop.look4sat.domain.source.IRemoteSource
|
||||||
import com.rtbishop.look4sat.domain.usecase.IAddToCalendar
|
import com.rtbishop.look4sat.domain.usecase.IAddToCalendar
|
||||||
|
import com.rtbishop.look4sat.domain.usecase.IOpenWebUrl
|
||||||
|
import com.rtbishop.look4sat.domain.usecase.IShowToast
|
||||||
import com.rtbishop.look4sat.domain.utility.DataParser
|
import com.rtbishop.look4sat.domain.utility.DataParser
|
||||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -36,17 +40,32 @@ import org.osmdroid.config.Configuration
|
|||||||
class MainContainer(private val context: Context) {
|
class MainContainer(private val context: Context) {
|
||||||
|
|
||||||
private val localSource = provideLocalSource()
|
private val localSource = provideLocalSource()
|
||||||
private val mainHandler = CoroutineExceptionHandler { _, error -> println("MainHandler: $error") }
|
private val mainHandler = CoroutineExceptionHandler { _, error ->
|
||||||
|
println("MainHandler: $error")
|
||||||
|
}
|
||||||
val appScope = CoroutineScope(SupervisorJob() + Dispatchers.Default + mainHandler)
|
val appScope = CoroutineScope(SupervisorJob() + Dispatchers.Default + mainHandler)
|
||||||
val settingsRepo = provideSettingsRepo()
|
val settingsRepo = provideSettingsRepo()
|
||||||
val selectionRepo = provideSelectionRepo()
|
val selectionRepo = provideSelectionRepo()
|
||||||
val satelliteRepo = provideSatelliteRepo()
|
val satelliteRepo = provideSatelliteRepo()
|
||||||
val databaseRepo = provideDatabaseRepo()
|
val databaseRepo = provideDatabaseRepo()
|
||||||
|
|
||||||
|
fun provideAppVersionName(): String {
|
||||||
|
val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
|
||||||
|
return packageInfo.versionName ?: "4.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
fun provideAddToCalendar(): IAddToCalendar {
|
fun provideAddToCalendar(): IAddToCalendar {
|
||||||
return AddToCalendar(context)
|
return AddToCalendar(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun provideOpenWebUrl(): IOpenWebUrl {
|
||||||
|
return OpenWebUrl(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun provideShowToast(): IShowToast {
|
||||||
|
return ShowToast(context)
|
||||||
|
}
|
||||||
|
|
||||||
fun provideBluetoothReporter(): BluetoothReporter {
|
fun provideBluetoothReporter(): BluetoothReporter {
|
||||||
val manager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
val manager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||||
return BluetoothReporter(manager, CoroutineScope(Dispatchers.IO))
|
return BluetoothReporter(manager, CoroutineScope(Dispatchers.IO))
|
||||||
@@ -63,15 +82,15 @@ class MainContainer(private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun provideDatabaseRepo(): IDatabaseRepo {
|
private fun provideDatabaseRepo(): IDatabaseRepo {
|
||||||
val dataParser = DataParser(Dispatchers.Default)
|
val dbDispatcher = Dispatchers.Default
|
||||||
|
val dataParser = DataParser(dbDispatcher)
|
||||||
val remoteSource = provideRemoteSource()
|
val remoteSource = provideRemoteSource()
|
||||||
return DatabaseRepo(Dispatchers.Default, dataParser, localSource, remoteSource, settingsRepo)
|
return DatabaseRepo(dbDispatcher, dataParser, localSource, remoteSource, settingsRepo)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun provideLocalSource(): ILocalSource {
|
private fun provideLocalSource(): ILocalSource {
|
||||||
val database = Room.databaseBuilder(context, Look4SatDb::class.java, "Look4SatDBv313").apply {
|
val builder = Room.databaseBuilder(context, Look4SatDb::class.java, "Look4SatDBv313")
|
||||||
fallbackToDestructiveMigration()
|
val database = builder.apply { fallbackToDestructiveMigration() }.build()
|
||||||
}.build()
|
|
||||||
return LocalSource(database.look4SatDao())
|
return LocalSource(database.look4SatDao())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.rtbishop.look4sat.presentation.components
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@@ -19,7 +18,6 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material3.CardDefaults
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.ElevatedButton
|
import androidx.compose.material3.ElevatedButton
|
||||||
import androidx.compose.material3.ElevatedCard
|
import androidx.compose.material3.ElevatedCard
|
||||||
@@ -219,22 +217,6 @@ fun CardIcon(onClick: () -> Unit, iconId: Int, modifier: Modifier = Modifier) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun StatusIcon(iconResId: Int, isEnabled: Boolean = false, description: String? = null, onClick: (() -> Unit)? = null) {
|
|
||||||
val cardColors = if (isEnabled) {
|
|
||||||
CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.primary)
|
|
||||||
} else {
|
|
||||||
CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)
|
|
||||||
}
|
|
||||||
val clickableModifier = if (onClick != null) Modifier.clickable { onClick.invoke() } else Modifier
|
|
||||||
val iconTint = if (isEnabled) MaterialTheme.colorScheme.surface else MaterialTheme.colorScheme.onSurface
|
|
||||||
ElevatedCard(modifier = Modifier.size(48.dp), colors = cardColors) {
|
|
||||||
Box(modifier = clickableModifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
|
||||||
Icon(imageVector = ImageVector.vectorResource(iconResId), tint = iconTint, contentDescription = description)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CardLoadingIndicator() {
|
fun CardLoadingIndicator() {
|
||||||
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) {
|
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) {
|
||||||
@@ -242,10 +224,6 @@ fun CardLoadingIndicator() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showToast(context: Context, message: String) {
|
|
||||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun gotoUrl(context: Context, url: String) {
|
fun gotoUrl(context: Context, url: String) {
|
||||||
context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
|
context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.rtbishop.look4sat.presentation.settings
|
package com.rtbishop.look4sat.presentation.settings
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
import android.os.Build
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@@ -25,7 +26,6 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
@@ -42,60 +42,62 @@ import com.rtbishop.look4sat.domain.predict.GeoPos
|
|||||||
import com.rtbishop.look4sat.presentation.MainTheme
|
import com.rtbishop.look4sat.presentation.MainTheme
|
||||||
import com.rtbishop.look4sat.presentation.Screen
|
import com.rtbishop.look4sat.presentation.Screen
|
||||||
import com.rtbishop.look4sat.presentation.components.CardButton
|
import com.rtbishop.look4sat.presentation.components.CardButton
|
||||||
import com.rtbishop.look4sat.presentation.components.gotoUrl
|
|
||||||
import com.rtbishop.look4sat.presentation.components.showToast
|
|
||||||
import org.osmdroid.library.BuildConfig
|
import org.osmdroid.library.BuildConfig
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
private const val GITHUB_URL = "https://github.com/rt-bishop/Look4Sat/"
|
|
||||||
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/"
|
|
||||||
|
|
||||||
fun NavGraphBuilder.settingsDestination() {
|
fun NavGraphBuilder.settingsDestination() {
|
||||||
composable(Screen.Settings.route) { SettingsScreen() }
|
composable(Screen.Settings.route) {
|
||||||
|
val viewModel = viewModel(
|
||||||
|
modelClass = SettingsViewModel::class.java,
|
||||||
|
factory = SettingsViewModel.Factory
|
||||||
|
)
|
||||||
|
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
|
||||||
|
SettingsScreen(uiState)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun SettingsScreen() {
|
private fun SettingsScreen(uiState: SettingsState) {
|
||||||
val viewModel = viewModel(SettingsViewModel::class.java, factory = SettingsViewModel.Factory)
|
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
// Permissions setup
|
// Permissions setup
|
||||||
// val bluetoothContract = ActivityResultContracts.RequestPermission()
|
val bluetoothContract = ActivityResultContracts.RequestPermission()
|
||||||
// val bluetoothError = stringResource(R.string.BTremote_perm_error)
|
val bluetoothError = stringResource(R.string.BTremote_perm_error)
|
||||||
// val bluetoothPerm = when {
|
val bluetoothPerm = when {
|
||||||
// Build.VERSION.SDK_INT < Build.VERSION_CODES.S -> Manifest.permission.BLUETOOTH
|
Build.VERSION.SDK_INT < Build.VERSION_CODES.S -> Manifest.permission.BLUETOOTH
|
||||||
// else -> Manifest.permission.BLUETOOTH_CONNECT
|
else -> Manifest.permission.BLUETOOTH_CONNECT
|
||||||
// }
|
}
|
||||||
// val bluetoothRequest = rememberLauncherForActivityResult(bluetoothContract) { isGranted ->
|
val bluetoothRequest = rememberLauncherForActivityResult(bluetoothContract) { isGranted ->
|
||||||
// viewModel.setBTEnabled(isGranted)
|
uiState.sendRCAction(RCAction.SetBluetoothState(isGranted))
|
||||||
// if (!isGranted) showToast(context, bluetoothError)
|
if (!isGranted) uiState.sendSystemAction(SystemAction.ShowToast(bluetoothError))
|
||||||
// }
|
}
|
||||||
val locationContract = ActivityResultContracts.RequestMultiplePermissions()
|
val locationContract = ActivityResultContracts.RequestMultiplePermissions()
|
||||||
val locationError = stringResource(R.string.location_gps_error)
|
val locationError = stringResource(R.string.location_gps_error)
|
||||||
val locationPermCoarse = Manifest.permission.ACCESS_COARSE_LOCATION
|
val locationPermCoarse = Manifest.permission.ACCESS_COARSE_LOCATION
|
||||||
val locationPermFine = Manifest.permission.ACCESS_FINE_LOCATION
|
val locationPermFine = Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
val locationRequest = rememberLauncherForActivityResult(locationContract) { permissions ->
|
val locationRequest = rememberLauncherForActivityResult(locationContract) { permissions ->
|
||||||
when {
|
when {
|
||||||
permissions[locationPermFine] == true -> viewModel.setGpsPosition()
|
permissions[locationPermFine] == true -> uiState.sendAction(SettingsAction.SetGpsPosition)
|
||||||
permissions[locationPermCoarse] == true -> viewModel.setGpsPosition()
|
permissions[locationPermCoarse] == true -> uiState.sendAction(SettingsAction.SetGpsPosition)
|
||||||
else -> showToast(context, locationError)
|
else -> uiState.sendSystemAction(SystemAction.ShowToast(locationError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val contentContract = ActivityResultContracts.GetContent()
|
val contentContract = ActivityResultContracts.GetContent()
|
||||||
val contentRequest = rememberLauncherForActivityResult(contentContract) { uri ->
|
val contentRequest = rememberLauncherForActivityResult(contentContract) { uri ->
|
||||||
uri?.let { viewModel.updateFromFile(uri.toString()) }
|
uri?.let { uiState.sendAction(SettingsAction.UpdateFromFile(uri.toString())) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position settings
|
// Position settings
|
||||||
val positionSettings = viewModel.positionSettings.collectAsStateWithLifecycle().value
|
val positionSettings = uiState.positionSettings
|
||||||
val stationPos = positionSettings.stationPos
|
val stationPos = positionSettings.stationPos
|
||||||
val setGpsPos = { locationRequest.launch(arrayOf(locationPermCoarse, locationPermFine)) }
|
val setGpsPos = { locationRequest.launch(arrayOf(locationPermCoarse, locationPermFine)) }
|
||||||
val setGeoPos = { lat: Double, lon: Double -> viewModel.setGeoPosition(lat, lon) }
|
val setGeoPos = { lat: Double, lon: Double ->
|
||||||
val setQthPos = { locator: String -> viewModel.setQthPosition(locator) }
|
uiState.sendAction(SettingsAction.SetGeoPosition(lat, lon))
|
||||||
val dismissPos = { viewModel.dismissPosMessage() }
|
}
|
||||||
|
val setQthPos = { locator: String ->
|
||||||
|
uiState.sendAction(SettingsAction.SetQthPosition(locator))
|
||||||
|
}
|
||||||
|
val dismissPos = { uiState.sendAction(SettingsAction.DismissPosMessages) }
|
||||||
val posDialogState = rememberSaveable { mutableStateOf(false) }
|
val posDialogState = rememberSaveable { mutableStateOf(false) }
|
||||||
val showPosDialog = { posDialogState.value = posDialogState.value.not() }
|
val showPosDialog = { posDialogState.value = posDialogState.value.not() }
|
||||||
if (posDialogState.value) {
|
if (posDialogState.value) {
|
||||||
@@ -108,26 +110,48 @@ private fun SettingsScreen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Data settings
|
// Data settings
|
||||||
val dataSettings = viewModel.dataSettings.collectAsStateWithLifecycle().value
|
val dataSettings = uiState.dataSettings
|
||||||
val updateFromWeb: () -> Unit = { viewModel.updateFromWeb() }
|
val updateFromWeb: () -> Unit = { uiState.sendAction(SettingsAction.UpdateFromWeb) }
|
||||||
val updateFromFile = { contentRequest.launch("*/*") }
|
val updateFromFile = { contentRequest.launch("*/*") }
|
||||||
val clearAllData: () -> Unit = { viewModel.clearAllData() }
|
val clearAllData: () -> Unit = { uiState.sendAction(SettingsAction.ClearAllData) }
|
||||||
|
|
||||||
// Other settings
|
// Other settings
|
||||||
val otherSettings = viewModel.otherSettings.collectAsStateWithLifecycle().value
|
val otherSettings = uiState.otherSettings
|
||||||
val toggleUtc = { value: Boolean -> viewModel.toggleUtc(value) }
|
val toggleUtc = { value: Boolean -> uiState.sendAction(SettingsAction.ToggleUtc(value)) }
|
||||||
val toggleUpdate = { value: Boolean -> viewModel.toggleUpdate(value) }
|
val toggleUpdate = { value: Boolean -> uiState.sendAction(SettingsAction.ToggleUpdate(value)) }
|
||||||
val toggleSweep = { value: Boolean -> viewModel.toggleSweep(value) }
|
val toggleSweep = { value: Boolean -> uiState.sendAction(SettingsAction.ToggleSweep(value)) }
|
||||||
val toggleSensor = { value: Boolean -> viewModel.toggleSensor(value) }
|
val toggleSensor = { value: Boolean -> uiState.sendAction(SettingsAction.ToggleSensor(value)) }
|
||||||
val toggleLightTheme = { value: Boolean -> viewModel.toggleLightTheme(value)}
|
val toggleLightTheme = { value: Boolean ->
|
||||||
|
uiState.sendAction(SettingsAction.ToggleLightTheme(value))
|
||||||
|
}
|
||||||
|
|
||||||
// Screen setup
|
// Screen setup
|
||||||
val versionName = context.packageManager.getPackageInfo(context.packageName, 0).versionName ?: "4.0.0"
|
LazyColumn(
|
||||||
LazyColumn(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
modifier = Modifier.padding(6.dp),
|
||||||
item { CardAbout(versionName) }
|
verticalArrangement = Arrangement.spacedBy(6.dp)
|
||||||
item { LocationCard(positionSettings, setGpsPos, showPosDialog, showLocDialog, dismissPos) }
|
) {
|
||||||
|
item { CardAbout(uiState.appVersionName, uiState.sendSystemAction) }
|
||||||
|
item {
|
||||||
|
LocationCard(
|
||||||
|
positionSettings,
|
||||||
|
setGpsPos,
|
||||||
|
showPosDialog,
|
||||||
|
showLocDialog,
|
||||||
|
dismissPos,
|
||||||
|
uiState.sendSystemAction
|
||||||
|
)
|
||||||
|
}
|
||||||
item { DataCard(dataSettings, updateFromWeb, updateFromFile, clearAllData) }
|
item { DataCard(dataSettings, updateFromWeb, updateFromFile, clearAllData) }
|
||||||
item { OtherCard(otherSettings, toggleUtc, toggleUpdate, toggleSweep, toggleSensor,toggleLightTheme) }
|
item {
|
||||||
|
OtherCard(
|
||||||
|
otherSettings,
|
||||||
|
toggleUtc,
|
||||||
|
toggleUpdate,
|
||||||
|
toggleSweep,
|
||||||
|
toggleSensor,
|
||||||
|
toggleLightTheme
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,9 +160,8 @@ private fun SettingsScreen() {
|
|||||||
private fun CardAboutPreview() = MainTheme { CardAbout(version = "4.0.0") }
|
private fun CardAboutPreview() = MainTheme { CardAbout(version = "4.0.0") }
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun CardAbout(version: String, modifier: Modifier = Modifier) {
|
private fun CardAbout(version: String, sendUrlAction: (SystemAction) -> Unit = {}) {
|
||||||
val context = LocalContext.current
|
ElevatedCard(modifier = Modifier.fillMaxWidth()) {
|
||||||
ElevatedCard(modifier = modifier.fillMaxWidth()) {
|
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
|
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||||
@@ -167,23 +190,23 @@ private fun CardAbout(version: String, modifier: Modifier = Modifier) {
|
|||||||
Text(
|
Text(
|
||||||
text = stringResource(id = R.string.app_subtitle),
|
text = stringResource(id = R.string.app_subtitle),
|
||||||
fontSize = 20.sp,
|
fontSize = 20.sp,
|
||||||
modifier = modifier.padding(top = 4.dp, bottom = 2.dp)
|
modifier = Modifier.padding(top = 4.dp, bottom = 2.dp)
|
||||||
)
|
)
|
||||||
Row(horizontalArrangement = Arrangement.SpaceEvenly) {
|
Row(horizontalArrangement = Arrangement.SpaceEvenly) {
|
||||||
CardButton(
|
CardButton(
|
||||||
onClick = { gotoUrl(context, GITHUB_URL) },
|
onClick = { sendUrlAction(SystemAction.OpenGitHub) },
|
||||||
text = stringResource(id = R.string.btn_github),
|
text = stringResource(id = R.string.btn_github),
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(6.dp))
|
Spacer(modifier = Modifier.width(6.dp))
|
||||||
CardButton(
|
CardButton(
|
||||||
onClick = { gotoUrl(context, DONATE_URL) },
|
onClick = { sendUrlAction(SystemAction.OpenDonate) },
|
||||||
text = stringResource(id = R.string.btn_donate),
|
text = stringResource(id = R.string.btn_donate),
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(6.dp))
|
Spacer(modifier = Modifier.width(6.dp))
|
||||||
CardButton(
|
CardButton(
|
||||||
onClick = { gotoUrl(context, FDROID_URL) },
|
onClick = { sendUrlAction(SystemAction.OpenFDroid) },
|
||||||
text = stringResource(id = R.string.btn_fdroid),
|
text = stringResource(id = R.string.btn_fdroid),
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
@@ -197,7 +220,7 @@ private fun CardAbout(version: String, modifier: Modifier = Modifier) {
|
|||||||
private fun LocationCardPreview() = MainTheme {
|
private fun LocationCardPreview() = MainTheme {
|
||||||
val stationPos = GeoPos(0.0, 0.0, 0.0, "IO91vl", 0L)
|
val stationPos = GeoPos(0.0, 0.0, 0.0, "IO91vl", 0L)
|
||||||
val settings = PositionSettings(true, stationPos, 0)
|
val settings = PositionSettings(true, stationPos, 0)
|
||||||
LocationCard(settings = settings, setGpsPos = {}, showPosDialog = {}, {}) {}
|
LocationCard(settings = settings, setGpsPos = {}, showPosDialog = {}, {}, {}) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -206,7 +229,8 @@ private fun LocationCard(
|
|||||||
setGpsPos: () -> Unit,
|
setGpsPos: () -> Unit,
|
||||||
showPosDialog: () -> Unit,
|
showPosDialog: () -> Unit,
|
||||||
showLocDialog: () -> Unit,
|
showLocDialog: () -> Unit,
|
||||||
dismissPosMessage: () -> Unit
|
dismissPosMessage: () -> Unit,
|
||||||
|
sendSystemAction: (SystemAction) -> Unit
|
||||||
) {
|
) {
|
||||||
ElevatedCard(modifier = Modifier.fillMaxWidth()) {
|
ElevatedCard(modifier = Modifier.fillMaxWidth()) {
|
||||||
Column(
|
Column(
|
||||||
@@ -263,10 +287,9 @@ private fun LocationCard(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (settings.messageResId != 0) {
|
if (settings.messageResId != 0) {
|
||||||
val context = LocalContext.current
|
|
||||||
val errorString = stringResource(id = settings.messageResId)
|
val errorString = stringResource(id = settings.messageResId)
|
||||||
LaunchedEffect(key1 = settings.messageResId) {
|
LaunchedEffect(key1 = settings.messageResId) {
|
||||||
showToast(context, errorString)
|
sendSystemAction(SystemAction.ShowToast(errorString))
|
||||||
dismissPosMessage()
|
dismissPosMessage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -383,8 +406,9 @@ private fun OtherCardPreview() = MainTheme {
|
|||||||
stateOfSensors = true,
|
stateOfSensors = true,
|
||||||
stateOfSweep = true,
|
stateOfSweep = true,
|
||||||
stateOfUtc = false,
|
stateOfUtc = false,
|
||||||
stateOfLightTheme = false)
|
stateOfLightTheme = false
|
||||||
OtherCard(settings = values, {}, {}, {}, {},{})
|
)
|
||||||
|
OtherCard(settings = values, {}, {}, {}, {}, {})
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -437,7 +461,10 @@ private fun OtherCard(
|
|||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(id = R.string.other_switch_light_theme))
|
Text(text = stringResource(id = R.string.other_switch_light_theme))
|
||||||
Switch(checked = settings.stateOfLightTheme, onCheckedChange = { toggleLightTheme(it) })
|
Switch(
|
||||||
|
checked = settings.stateOfLightTheme,
|
||||||
|
onCheckedChange = { toggleLightTheme(it) }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,65 @@
|
|||||||
package com.rtbishop.look4sat.presentation.settings
|
package com.rtbishop.look4sat.presentation.settings
|
||||||
|
|
||||||
|
import com.rtbishop.look4sat.domain.model.OtherSettings
|
||||||
import com.rtbishop.look4sat.domain.predict.GeoPos
|
import com.rtbishop.look4sat.domain.predict.GeoPos
|
||||||
|
|
||||||
data class PositionSettings(val isUpdating: Boolean, val stationPos: GeoPos, val messageResId: Int)
|
data class PositionSettings(
|
||||||
|
val isUpdating: Boolean, val stationPos: GeoPos, val messageResId: Int
|
||||||
|
)
|
||||||
|
|
||||||
data class DataSettings(val isUpdating: Boolean, val entriesTotal: Int, val radiosTotal: Int, val timestamp: Long)
|
data class DataSettings(
|
||||||
|
val isUpdating: Boolean, val entriesTotal: Int, val radiosTotal: Int, val timestamp: Long
|
||||||
|
)
|
||||||
|
|
||||||
|
data class RCSettings(
|
||||||
|
val rotatorState: Boolean,
|
||||||
|
val rotatorAddress: String,
|
||||||
|
val rotatorPort: String,
|
||||||
|
val bluetoothState: Boolean,
|
||||||
|
val bluetoothFormat: String,
|
||||||
|
val bluetoothName: String,
|
||||||
|
val bluetoothAddress: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class SettingsState(
|
||||||
|
val appVersionName: String,
|
||||||
|
val positionSettings: PositionSettings,
|
||||||
|
val dataSettings: DataSettings,
|
||||||
|
val otherSettings: OtherSettings,
|
||||||
|
val rcSettings: RCSettings,
|
||||||
|
val sendAction: (SettingsAction) -> Unit,
|
||||||
|
val sendRCAction: (RCAction) -> Unit,
|
||||||
|
val sendSystemAction: (SystemAction) -> Unit
|
||||||
|
)
|
||||||
|
|
||||||
|
sealed class SettingsAction {
|
||||||
|
data object SetGpsPosition : SettingsAction()
|
||||||
|
data class SetGeoPosition(val latitude: Double, val longitude: Double) : SettingsAction()
|
||||||
|
data class SetQthPosition(val locator: String) : SettingsAction()
|
||||||
|
data object DismissPosMessages : SettingsAction()
|
||||||
|
data object UpdateFromWeb : SettingsAction()
|
||||||
|
data class UpdateFromFile(val uri: String) : SettingsAction()
|
||||||
|
data object ClearAllData : SettingsAction()
|
||||||
|
data class ToggleUtc(val value: Boolean) : SettingsAction()
|
||||||
|
data class ToggleUpdate(val value: Boolean) : SettingsAction()
|
||||||
|
data class ToggleSweep(val value: Boolean) : SettingsAction()
|
||||||
|
data class ToggleSensor(val value: Boolean) : SettingsAction()
|
||||||
|
data class ToggleLightTheme(val value: Boolean) : SettingsAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class SystemAction {
|
||||||
|
data object OpenGitHub : SystemAction()
|
||||||
|
data object OpenDonate : SystemAction()
|
||||||
|
data object OpenFDroid : SystemAction()
|
||||||
|
data class ShowToast(val message: String) : SystemAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class RCAction {
|
||||||
|
data class SetRotatorState(val value: Boolean) : RCAction()
|
||||||
|
data class SetRotatorAddress(val value: String) : RCAction()
|
||||||
|
data class SetRotatorPort(val value: String) : RCAction()
|
||||||
|
data class SetBluetoothState(val value: Boolean) : RCAction()
|
||||||
|
data class SetBluetoothFormat(val value: String) : RCAction()
|
||||||
|
data class SetBluetoothName(val value: String) : RCAction()
|
||||||
|
data class SetBluetoothAddress(val value: String) : RCAction()
|
||||||
|
}
|
||||||
+134
-59
@@ -24,134 +24,209 @@ import androidx.lifecycle.viewmodel.initializer
|
|||||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||||
import com.rtbishop.look4sat.MainApplication
|
import com.rtbishop.look4sat.MainApplication
|
||||||
import com.rtbishop.look4sat.R
|
import com.rtbishop.look4sat.R
|
||||||
import com.rtbishop.look4sat.domain.model.OtherSettings
|
|
||||||
import com.rtbishop.look4sat.domain.repository.IDatabaseRepo
|
import com.rtbishop.look4sat.domain.repository.IDatabaseRepo
|
||||||
import com.rtbishop.look4sat.domain.repository.ISettingsRepo
|
import com.rtbishop.look4sat.domain.repository.ISettingsRepo
|
||||||
|
import com.rtbishop.look4sat.domain.usecase.IOpenWebUrl
|
||||||
|
import com.rtbishop.look4sat.domain.usecase.IShowToast
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class SettingsViewModel(
|
class SettingsViewModel(
|
||||||
private val databaseRepo: IDatabaseRepo, private val settingsRepo: ISettingsRepo
|
private val databaseRepo: IDatabaseRepo,
|
||||||
|
private val settingsRepo: ISettingsRepo,
|
||||||
|
private val openWebUrl: IOpenWebUrl,
|
||||||
|
private val showToast: IShowToast,
|
||||||
|
appVersionName: String
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
|
private val githubUrl = "https://github.com/rt-bishop/Look4Sat/"
|
||||||
|
private val donateUrl = "https://ko-fi.com/rt_bishop"
|
||||||
|
private val fdroidUrl = "https://f-droid.org/en/packages/com.rtbishop.look4sat/"
|
||||||
private val defaultPosSettings = PositionSettings(false, settingsRepo.stationPosition.value, 0)
|
private val defaultPosSettings = PositionSettings(false, settingsRepo.stationPosition.value, 0)
|
||||||
private val _positionSettings = MutableStateFlow(defaultPosSettings)
|
|
||||||
val positionSettings: StateFlow<PositionSettings> = _positionSettings
|
|
||||||
|
|
||||||
private val defaultDataSettings = DataSettings(false, 0, 0, 0L)
|
private val defaultDataSettings = DataSettings(false, 0, 0, 0L)
|
||||||
private val _dataSettings = MutableStateFlow(defaultDataSettings)
|
private val defaultRCSettings = RCSettings(
|
||||||
val dataSettings: StateFlow<DataSettings> = _dataSettings
|
rotatorState = settingsRepo.getRotatorState(),
|
||||||
|
rotatorAddress = settingsRepo.getRotatorAddress(),
|
||||||
private val _otherSettings = MutableStateFlow(settingsRepo.otherSettings.value)
|
rotatorPort = settingsRepo.getRotatorPort(),
|
||||||
val otherSettings: StateFlow<OtherSettings> = _otherSettings
|
bluetoothState = settingsRepo.getBluetoothState(),
|
||||||
|
bluetoothFormat = settingsRepo.getBluetoothFormat(),
|
||||||
|
bluetoothName = settingsRepo.getBluetoothName(),
|
||||||
|
bluetoothAddress = settingsRepo.getBluetoothAddress()
|
||||||
|
)
|
||||||
|
private val _uiState = MutableStateFlow(
|
||||||
|
SettingsState(
|
||||||
|
appVersionName = appVersionName,
|
||||||
|
positionSettings = defaultPosSettings,
|
||||||
|
dataSettings = defaultDataSettings,
|
||||||
|
otherSettings = settingsRepo.otherSettings.value,
|
||||||
|
rcSettings = defaultRCSettings,
|
||||||
|
sendAction = ::handleAction,
|
||||||
|
sendRCAction = ::handleAction,
|
||||||
|
sendSystemAction = ::handleAction
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val uiState: StateFlow<SettingsState> = _uiState
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
settingsRepo.stationPosition.collect { geoPos ->
|
settingsRepo.stationPosition.collect { geoPos ->
|
||||||
_positionSettings.update { it.copy(isUpdating = false, stationPos = geoPos) }
|
val newPosSettings = _uiState.value.positionSettings.copy(
|
||||||
|
isUpdating = false, stationPos = geoPos
|
||||||
|
)
|
||||||
|
_uiState.update { it.copy(positionSettings = newPosSettings) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
settingsRepo.databaseState.collect { state ->
|
settingsRepo.databaseState.collect { state ->
|
||||||
_dataSettings.update {
|
val newDataSettings = _uiState.value.dataSettings.copy(
|
||||||
it.copy(
|
isUpdating = false,
|
||||||
isUpdating = false,
|
entriesTotal = state.numberOfSatellites,
|
||||||
entriesTotal = state.numberOfSatellites,
|
radiosTotal = state.numberOfRadios,
|
||||||
radiosTotal = state.numberOfRadios,
|
timestamp = state.updateTimestamp
|
||||||
timestamp = state.updateTimestamp
|
)
|
||||||
)
|
_uiState.update { it.copy(dataSettings = newDataSettings) }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
settingsRepo.otherSettings.collect { settings -> _otherSettings.update { settings } }
|
settingsRepo.otherSettings.collect { settings ->
|
||||||
|
_uiState.update { it.copy(otherSettings = settings) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setGpsPosition() {
|
private fun handleAction(action: SettingsAction) {
|
||||||
|
when (action) {
|
||||||
|
SettingsAction.SetGpsPosition -> setGpsPosition()
|
||||||
|
is SettingsAction.SetGeoPosition -> setGeoPosition(action.latitude, action.longitude)
|
||||||
|
is SettingsAction.SetQthPosition -> setQthPosition(action.locator)
|
||||||
|
SettingsAction.DismissPosMessages -> dismissPosMessage()
|
||||||
|
SettingsAction.UpdateFromWeb -> updateFromWeb()
|
||||||
|
is SettingsAction.UpdateFromFile -> updateFromFile(action.uri)
|
||||||
|
SettingsAction.ClearAllData -> clearAllData()
|
||||||
|
is SettingsAction.ToggleUtc -> settingsRepo.setStateOfUtc(action.value)
|
||||||
|
is SettingsAction.ToggleUpdate -> settingsRepo.setStateOfAutoUpdate(action.value)
|
||||||
|
is SettingsAction.ToggleSweep -> settingsRepo.setStateOfSweep(action.value)
|
||||||
|
is SettingsAction.ToggleSensor -> settingsRepo.setStateOfSensors(action.value)
|
||||||
|
is SettingsAction.ToggleLightTheme -> settingsRepo.setStateOfLightTheme(action.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleAction(action: RCAction) {
|
||||||
|
when (action) {
|
||||||
|
is RCAction.SetRotatorState -> settingsRepo.setRotatorState(action.value)
|
||||||
|
is RCAction.SetRotatorAddress -> settingsRepo.setRotatorAddress(action.value)
|
||||||
|
is RCAction.SetRotatorPort -> settingsRepo.setRotatorPort(action.value)
|
||||||
|
is RCAction.SetBluetoothState -> settingsRepo.setBluetoothState(action.value)
|
||||||
|
is RCAction.SetBluetoothAddress -> settingsRepo.setBluetoothAddress(action.value)
|
||||||
|
is RCAction.SetBluetoothFormat -> settingsRepo.setBluetoothFormat(action.value)
|
||||||
|
is RCAction.SetBluetoothName -> settingsRepo.setBluetoothName(action.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleAction(action: SystemAction) {
|
||||||
|
when (action) {
|
||||||
|
SystemAction.OpenGitHub -> openWebUrl(githubUrl)
|
||||||
|
SystemAction.OpenDonate -> openWebUrl(donateUrl)
|
||||||
|
SystemAction.OpenFDroid -> openWebUrl(fdroidUrl)
|
||||||
|
is SystemAction.ShowToast -> showToast(action.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setGpsPosition() {
|
||||||
if (settingsRepo.setStationPositionGps()) {
|
if (settingsRepo.setStationPositionGps()) {
|
||||||
val messageResId = R.string.location_success
|
val messageResId = R.string.location_success
|
||||||
_positionSettings.update { it.copy(isUpdating = true, messageResId = messageResId) }
|
val newPosSettings = _uiState.value.positionSettings.copy(
|
||||||
|
isUpdating = true, messageResId = messageResId
|
||||||
|
)
|
||||||
|
_uiState.update { it.copy(positionSettings = newPosSettings) }
|
||||||
} else {
|
} else {
|
||||||
val errorResId = R.string.location_gps_error
|
val errorResId = R.string.location_gps_error
|
||||||
_positionSettings.update { it.copy(messageResId = errorResId) }
|
val newPosSettings = _uiState.value.positionSettings.copy(
|
||||||
|
isUpdating = false, messageResId = errorResId
|
||||||
|
)
|
||||||
|
_uiState.update { it.copy(positionSettings = newPosSettings) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setGeoPosition(latitude: Double, longitude: Double) {
|
private fun setGeoPosition(latitude: Double, longitude: Double) {
|
||||||
if (settingsRepo.setStationPositionGeo(latitude, longitude, 0.0)) {
|
if (settingsRepo.setStationPositionGeo(latitude, longitude, 0.0)) {
|
||||||
val messageResId = R.string.location_success
|
val messageResId = R.string.location_success
|
||||||
_positionSettings.update { it.copy(messageResId = messageResId) }
|
val newPosSettings = _uiState.value.positionSettings.copy(
|
||||||
|
isUpdating = false, messageResId = messageResId
|
||||||
|
)
|
||||||
|
_uiState.update { it.copy(positionSettings = newPosSettings) }
|
||||||
} else {
|
} else {
|
||||||
val errorResId = R.string.location_manual_error
|
val errorResId = R.string.location_manual_error
|
||||||
_positionSettings.update { it.copy(messageResId = errorResId) }
|
val newPosSettings = _uiState.value.positionSettings.copy(
|
||||||
|
isUpdating = false, messageResId = errorResId
|
||||||
|
)
|
||||||
|
_uiState.update { it.copy(positionSettings = newPosSettings) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setQthPosition(locator: String) {
|
private fun setQthPosition(locator: String) {
|
||||||
if (settingsRepo.setStationPositionQth(locator)) {
|
if (settingsRepo.setStationPositionQth(locator)) {
|
||||||
val messageResId = R.string.location_success
|
val messageResId = R.string.location_success
|
||||||
_positionSettings.update { it.copy(messageResId = messageResId) }
|
val newPosSettings = _uiState.value.positionSettings.copy(
|
||||||
|
isUpdating = false, messageResId = messageResId
|
||||||
|
)
|
||||||
|
_uiState.update { it.copy(positionSettings = newPosSettings) }
|
||||||
} else {
|
} else {
|
||||||
val errorResId = R.string.location_qth_error
|
val errorResId = R.string.location_qth_error
|
||||||
_positionSettings.update { it.copy(messageResId = errorResId) }
|
val newPosSettings = _uiState.value.positionSettings.copy(
|
||||||
|
isUpdating = false, messageResId = errorResId
|
||||||
|
)
|
||||||
|
_uiState.update { it.copy(positionSettings = newPosSettings) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dismissPosMessage() {
|
private fun dismissPosMessage() {
|
||||||
_positionSettings.update { it.copy(messageResId = 0) }
|
val newPosSettings = _uiState.value.positionSettings.copy(
|
||||||
|
isUpdating = false, messageResId = 0
|
||||||
|
)
|
||||||
|
_uiState.update { it.copy(positionSettings = newPosSettings) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateFromWeb() = viewModelScope.launch {
|
private fun updateFromWeb() = viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
_dataSettings.update { it.copy(isUpdating = true) }
|
val newDataSettings = _uiState.value.dataSettings.copy(isUpdating = true)
|
||||||
|
_uiState.update { it.copy(dataSettings = newDataSettings) }
|
||||||
databaseRepo.updateFromRemote()
|
databaseRepo.updateFromRemote()
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
_dataSettings.update { it.copy(isUpdating = false) }
|
val newDataSettings = _uiState.value.dataSettings.copy(isUpdating = false)
|
||||||
|
_uiState.update { it.copy(dataSettings = newDataSettings) }
|
||||||
println(exception)
|
println(exception)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateFromFile(uri: String) = viewModelScope.launch {
|
private fun updateFromFile(uri: String) = viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
_dataSettings.update { it.copy(isUpdating = true) }
|
val newDataSettings = _uiState.value.dataSettings.copy(isUpdating = true)
|
||||||
|
_uiState.update { it.copy(dataSettings = newDataSettings) }
|
||||||
databaseRepo.updateFromFile(uri)
|
databaseRepo.updateFromFile(uri)
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
_dataSettings.update { it.copy(isUpdating = false) }
|
val newDataSettings = _uiState.value.dataSettings.copy(isUpdating = false)
|
||||||
|
_uiState.update { it.copy(dataSettings = newDataSettings) }
|
||||||
println(exception)
|
println(exception)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearAllData() = viewModelScope.launch { databaseRepo.clearAllData() }
|
private fun clearAllData() = viewModelScope.launch { databaseRepo.clearAllData() }
|
||||||
|
|
||||||
fun toggleUtc(value: Boolean) = settingsRepo.setStateOfUtc(value)
|
|
||||||
fun toggleUpdate(value: Boolean) = settingsRepo.setStateOfAutoUpdate(value)
|
|
||||||
fun toggleSweep(value: Boolean) = settingsRepo.setStateOfSweep(value)
|
|
||||||
fun toggleSensor(value: Boolean) = settingsRepo.setStateOfSensors(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()
|
|
||||||
// fun setRotatorServer(value: String) = settings.setRotatorServer(value)
|
|
||||||
// fun getRotatorPort(): String = settings.getRotatorPort()
|
|
||||||
// fun setRotatorPort(value: String) = settings.setRotatorPort(value)
|
|
||||||
// fun getBTEnabled(): Boolean = settings.getBTEnabled()
|
|
||||||
// fun setBTEnabled(value: Boolean) = settings.setBTEnabled(value)
|
|
||||||
// fun getBTFormat(): String = settings.getBTFormat()
|
|
||||||
// fun setBTFormat(value: String) = settings.setBTFormat(value)
|
|
||||||
// fun getBTDeviceName(): String = settings.getBTDeviceName()
|
|
||||||
// fun setBTDeviceName(value: String) = settings.setBTDeviceName(value)
|
|
||||||
// fun getBTDeviceAddr(): String = settings.getBTDeviceAddr()
|
|
||||||
// fun setBTDeviceAddr(value: String) = settings.setBTDeviceAddr(value)
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val Factory: ViewModelProvider.Factory = viewModelFactory {
|
val Factory: ViewModelProvider.Factory = viewModelFactory {
|
||||||
val applicationKey = ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY
|
val applicationKey = ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY
|
||||||
initializer {
|
initializer {
|
||||||
val container = (this[applicationKey] as MainApplication).container
|
val container = (this[applicationKey] as MainApplication).container
|
||||||
SettingsViewModel(container.databaseRepo, container.settingsRepo)
|
SettingsViewModel(
|
||||||
|
container.databaseRepo,
|
||||||
|
container.settingsRepo,
|
||||||
|
container.provideOpenWebUrl(),
|
||||||
|
container.provideShowToast(),
|
||||||
|
container.provideAppVersionName()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.rtbishop.look4sat.data.usecase
|
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import com.rtbishop.look4sat.domain.usecase.IOpenWebUrl
|
||||||
|
|
||||||
|
class OpenWebUrl(private val context: Context) : IOpenWebUrl {
|
||||||
|
override fun invoke(url: String) {
|
||||||
|
try {
|
||||||
|
context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply {
|
||||||
|
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
})
|
||||||
|
} catch (_: ActivityNotFoundException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.rtbishop.look4sat.data.usecase
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.widget.Toast
|
||||||
|
import com.rtbishop.look4sat.domain.usecase.IShowToast
|
||||||
|
|
||||||
|
class ShowToast(private val context: Context) : IShowToast {
|
||||||
|
override fun invoke(message: String) {
|
||||||
|
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.rtbishop.look4sat.domain.usecase
|
||||||
|
|
||||||
|
interface IOpenWebUrl {
|
||||||
|
operator fun invoke(url: String)
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.rtbishop.look4sat.domain.usecase
|
||||||
|
|
||||||
|
interface IShowToast {
|
||||||
|
operator fun invoke(message: String)
|
||||||
|
}
|
||||||
Reference in new issue
Block a user