diff --git a/app/src/main/java/com/rtbishop/look4sat/MainActivity.kt b/app/src/main/java/com/rtbishop/look4sat/MainActivity.kt index 190c2233..3a8ded66 100644 --- a/app/src/main/java/com/rtbishop/look4sat/MainActivity.kt +++ b/app/src/main/java/com/rtbishop/look4sat/MainActivity.kt @@ -19,12 +19,21 @@ package com.rtbishop.look4sat import android.content.Context import android.content.res.Configuration +import android.graphics.ColorMatrix +import android.graphics.ColorMatrixColorFilter +import android.graphics.Paint import android.os.Bundle +import android.view.View import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen +import androidx.lifecycle.lifecycleScope +import com.rtbishop.look4sat.core.domain.repository.IContainerProvider import com.rtbishop.look4sat.core.presentation.MainTheme +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch class MainActivity : ComponentActivity() { @@ -38,8 +47,37 @@ class MainActivity : ComponentActivity() { installSplashScreen() enableEdgeToEdge() super.onCreate(savedInstanceState) + observeNightFilterState() setContent { MainTheme(isDarkTheme = true) { MainScreen() } } } + + private fun observeNightFilterState() { + val mainContainer = (applicationContext as IContainerProvider).getMainContainer() + lifecycleScope.launch { + mainContainer.settingsRepo.otherSettings + .map { it.stateOfNightMode } + .distinctUntilChanged() + .collect { nightMode -> applyNightFilter(nightMode) } + } + } + + private fun applyNightFilter(enabled: Boolean) { + if (enabled) { + val nightMatrix = ColorMatrix( + floatArrayOf( + 1f, 0f, 0f, 0f, 0f, // R → R + 0f, 0f, 0f, 0f, 0f, // G → 0 + 0f, 0f, 0f, 0f, 0f, // B → 0 + 0f, 0f, 0f, 1f, 0f // A → A + ) + ) + window.decorView.setLayerType(View.LAYER_TYPE_HARDWARE, Paint().apply { + colorFilter = ColorMatrixColorFilter(nightMatrix) + }) + } else { + window.decorView.setLayerType(View.LAYER_TYPE_NONE, null) + } + } } diff --git a/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/SettingsRepo.kt b/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/SettingsRepo.kt index 263f2245..c9b72dc8 100644 --- a/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/SettingsRepo.kt +++ b/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/SettingsRepo.kt @@ -72,6 +72,7 @@ class SettingsRepo( private val keyStateOfSweep = "stateOfSweep" private val keyStateOfUtc = "stateOfUtc" private val keyStateOfLightTheme = "stateOfLightTheme" + private val keyStateOfNightMode = "stateOfNightMode" private val keyStationAltitude = "stationAltitude" private val keyStationLatitude = "stationLatitude" private val keyStationLongitude = "stationLongitude" @@ -329,6 +330,7 @@ class SettingsRepo( putBoolean(keyStateOfSweep, new.stateOfSweep) putBoolean(keyStateOfUtc, new.stateOfUtc) putBoolean(keyStateOfLightTheme, new.stateOfLightTheme) + putBoolean(keyStateOfNightMode, new.stateOfNightMode) putBoolean(keyShouldSeeWarning, new.shouldSeeWarning) putBoolean(keyShouldSeeWhatsNew, new.shouldSeeWhatsNew) } @@ -342,6 +344,7 @@ class SettingsRepo( stateOfSweep = preferences.getBoolean(keyStateOfSweep, true), stateOfUtc = preferences.getBoolean(keyStateOfUtc, false), stateOfLightTheme = preferences.getBoolean(keyStateOfLightTheme, false), + stateOfNightMode = preferences.getBoolean(keyStateOfNightMode, false), shouldSeeWarning = preferences.getBoolean(keyShouldSeeWarning, true), shouldSeeWhatsNew = preferences.getBoolean(keyShouldSeeWhatsNew, true) ) diff --git a/core/domain/src/main/java/com/rtbishop/look4sat/core/domain/model/Settings.kt b/core/domain/src/main/java/com/rtbishop/look4sat/core/domain/model/Settings.kt index 11cb77ed..509e0ecd 100644 --- a/core/domain/src/main/java/com/rtbishop/look4sat/core/domain/model/Settings.kt +++ b/core/domain/src/main/java/com/rtbishop/look4sat/core/domain/model/Settings.kt @@ -54,6 +54,7 @@ data class OtherSettings( val stateOfSweep: Boolean, val stateOfUtc: Boolean, val stateOfLightTheme: Boolean, + val stateOfNightMode: Boolean = false, val shouldSeeWarning: Boolean, val shouldSeeWhatsNew: Boolean ) diff --git a/core/presentation/src/main/res/values/strings.xml b/core/presentation/src/main/res/values/strings.xml index 800bc812..f7fd4a0d 100644 --- a/core/presentation/src/main/res/values/strings.xml +++ b/core/presentation/src/main/res/values/strings.xml @@ -181,6 +181,7 @@ Enable automatic data update Enable radar sweep animation Use sensors to rotate radar view + Enable red night mode filter I would like to say thanks to diff --git a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsScreen.kt b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsScreen.kt index 42ba052d..996f62f4 100644 --- a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsScreen.kt +++ b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsScreen.kt @@ -422,6 +422,7 @@ private fun OtherCardPreview() = MainTheme { stateOfSweep = true, stateOfUtc = false, stateOfLightTheme = false, + stateOfNightMode = false, shouldSeeWarning = false, shouldSeeWhatsNew = false ) @@ -433,7 +434,7 @@ private fun OtherCard(settings: OtherSettings, onAction: (SettingsAction) -> Uni ElevatedCard( modifier = Modifier .fillMaxWidth() - .height(220.dp) + .height(268.dp) ) { Column(modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)) { Text( @@ -452,6 +453,9 @@ private fun OtherCard(settings: OtherSettings, onAction: (SettingsAction) -> Uni SwitchRow(R.string.prefs_other_switch_sensors, settings.stateOfSensors) { onAction(SettingsAction.ToggleSensor(it)) } + SwitchRow(R.string.prefs_other_switch_night_mode, settings.stateOfNightMode) { + onAction(SettingsAction.ToggleNightMode(it)) + } } } } @@ -502,7 +506,7 @@ private fun CardCredits(modifier: Modifier = Modifier) { ElevatedCard( modifier = modifier .fillMaxWidth() - .height(220.dp) + .height(268.dp) ) { Column( verticalArrangement = Arrangement.SpaceBetween, diff --git a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsState.kt b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsState.kt index 7b3461d5..8943ab2d 100644 --- a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsState.kt +++ b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsState.kt @@ -60,6 +60,7 @@ sealed interface SettingsAction { data class ToggleSweep(val value: Boolean) : SettingsAction data class ToggleSensor(val value: Boolean) : SettingsAction data class ToggleLightTheme(val value: Boolean) : SettingsAction + data class ToggleNightMode(val value: Boolean) : SettingsAction // Remote control data class UpdateRC(val settings: RCSettings) : SettingsAction diff --git a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsViewModel.kt b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsViewModel.kt index cf8bcc00..ca17941d 100644 --- a/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsViewModel.kt +++ b/feature/settings/src/main/java/com/rtbishop/look4sat/feature/settings/SettingsViewModel.kt @@ -121,6 +121,7 @@ class SettingsViewModel( is SettingsAction.ToggleSweep -> settingsRepo.updateOtherSettings { it.copy(stateOfSweep = action.value) } is SettingsAction.ToggleSensor -> settingsRepo.updateOtherSettings { it.copy(stateOfSensors = action.value) } is SettingsAction.ToggleLightTheme -> settingsRepo.updateOtherSettings { it.copy(stateOfLightTheme = action.value) } + is SettingsAction.ToggleNightMode -> settingsRepo.updateOtherSettings { it.copy(stateOfNightMode = action.value) } // Remote control & data sources is SettingsAction.UpdateRC -> settingsRepo.updateRCSettings(action.settings) is SettingsAction.UpdateRadioControl -> settingsRepo.updateRadioControlSettings(action.settings)