darkmode
This commit is contained in:
@@ -14,6 +14,7 @@ import com.google.android.gms.location.Priority
|
|||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
|
|
||||||
|
private const val THEME_MODE = "theme_mode"
|
||||||
private val Context.dataStore by preferencesDataStore(name = "settings")
|
private val Context.dataStore by preferencesDataStore(name = "settings")
|
||||||
|
|
||||||
class SettingsDataStore(private val context: Context) {
|
class SettingsDataStore(private val context: Context) {
|
||||||
@@ -31,6 +32,7 @@ class SettingsDataStore(private val context: Context) {
|
|||||||
val STATIC_LNG_KEY = doublePreferencesKey("static_lng")
|
val STATIC_LNG_KEY = doublePreferencesKey("static_lng")
|
||||||
val GPS_LAT_KEY = doublePreferencesKey("gps_lat")
|
val GPS_LAT_KEY = doublePreferencesKey("gps_lat")
|
||||||
val GPS_LNG_KEY = doublePreferencesKey("gps_lng")
|
val GPS_LNG_KEY = doublePreferencesKey("gps_lng")
|
||||||
|
val THEME_MODE_KEY = booleanPreferencesKey(THEME_MODE)
|
||||||
}
|
}
|
||||||
|
|
||||||
val selectedLocation: Flow<Pair<Double, Double>> = context.dataStore.data.map { preferences ->
|
val selectedLocation: Flow<Pair<Double, Double>> = context.dataStore.data.map { preferences ->
|
||||||
@@ -178,4 +180,15 @@ class SettingsDataStore(private val context: Context) {
|
|||||||
}.first()
|
}.first()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val isDarkTheme: Flow<Boolean> = context.dataStore.data
|
||||||
|
.map { preferences ->
|
||||||
|
preferences[PreferencesKeys.THEME_MODE_KEY] ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun saveThemeMode(isDark: Boolean) {
|
||||||
|
context.dataStore.edit { preferences ->
|
||||||
|
preferences[PreferencesKeys.THEME_MODE_KEY] = isDark
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,8 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Settings
|
import androidx.compose.material.icons.filled.Settings
|
||||||
|
import androidx.compose.material.icons.filled.DarkMode
|
||||||
|
import androidx.compose.material.icons.filled.LightMode
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
@@ -15,6 +17,7 @@ import androidx.navigation.compose.composable
|
|||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.example.tank.data.SettingsDataStore
|
import com.example.tank.data.SettingsDataStore
|
||||||
import com.example.tank.di.NetworkModule
|
import com.example.tank.di.NetworkModule
|
||||||
|
import com.example.tank.ui.theme.TankTheme
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -53,7 +56,19 @@ fun MainScreen() {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun MainContent() {
|
private fun MainContent() {
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
|
val context = LocalContext.current
|
||||||
|
val settingsDataStore = remember { SettingsDataStore(context) }
|
||||||
|
var isDarkTheme by remember { mutableStateOf(false) }
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
// Load saved theme preference
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
settingsDataStore.isDarkTheme.collect { isDark ->
|
||||||
|
isDarkTheme = isDark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TankTheme(darkTheme = isDarkTheme) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
CenterAlignedTopAppBar(
|
CenterAlignedTopAppBar(
|
||||||
@@ -76,10 +91,21 @@ private fun MainContent() {
|
|||||||
modifier = Modifier.padding(padding)
|
modifier = Modifier.padding(padding)
|
||||||
) {
|
) {
|
||||||
composable("prices") { PricesScreen() }
|
composable("prices") { PricesScreen() }
|
||||||
composable("settings") { SettingsScreen(navController = navController) }
|
composable("settings") {
|
||||||
|
SettingsScreen(
|
||||||
|
navController = navController,
|
||||||
|
isDarkTheme = isDarkTheme,
|
||||||
|
onThemeChanged = { newTheme ->
|
||||||
|
scope.launch {
|
||||||
|
settingsDataStore.saveThemeMode(newTheme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
composable("map") { MapScreen(navController = navController) }
|
composable("map") { MapScreen(navController = navController) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
@@ -552,3 +552,29 @@ private fun FavoriteStationCard(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun SelectionButton(
|
||||||
|
text: String,
|
||||||
|
isSelected: Boolean,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Button(
|
||||||
|
onClick = onClick,
|
||||||
|
modifier = modifier
|
||||||
|
.padding(4.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = if (isSelected)
|
||||||
|
MaterialTheme.colorScheme.primary
|
||||||
|
else
|
||||||
|
MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
contentColor = if (isSelected)
|
||||||
|
MaterialTheme.colorScheme.onPrimary
|
||||||
|
else
|
||||||
|
MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,7 +30,11 @@ import androidx.compose.foundation.rememberScrollState
|
|||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsScreen(navController: NavController) {
|
fun SettingsScreen(
|
||||||
|
navController: NavController,
|
||||||
|
isDarkTheme: Boolean,
|
||||||
|
onThemeChanged: (Boolean) -> Unit
|
||||||
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val settingsDataStore = remember { SettingsDataStore(context) }
|
val settingsDataStore = remember { SettingsDataStore(context) }
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
@@ -380,6 +384,26 @@ fun SettingsScreen(navController: NavController) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add Theme Section
|
||||||
|
SettingsSection(title = "Appearance") {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Dark Theme",
|
||||||
|
style = MaterialTheme.typography.bodyLarge
|
||||||
|
)
|
||||||
|
Switch(
|
||||||
|
checked = isDarkTheme,
|
||||||
|
onCheckedChange = { onThemeChanged(it) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
// Save Button
|
// Save Button
|
||||||
|
|||||||
Reference in New Issue
Block a user