darkmode
This commit is contained in:
@@ -14,6 +14,7 @@ import com.google.android.gms.location.Priority
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
private const val THEME_MODE = "theme_mode"
|
||||
private val Context.dataStore by preferencesDataStore(name = "settings")
|
||||
|
||||
class SettingsDataStore(private val context: Context) {
|
||||
@@ -31,6 +32,7 @@ class SettingsDataStore(private val context: Context) {
|
||||
val STATIC_LNG_KEY = doublePreferencesKey("static_lng")
|
||||
val GPS_LAT_KEY = doublePreferencesKey("gps_lat")
|
||||
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 ->
|
||||
@@ -178,4 +180,15 @@ class SettingsDataStore(private val context: Context) {
|
||||
}.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.material.icons.Icons
|
||||
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.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -15,6 +17,7 @@ import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.example.tank.data.SettingsDataStore
|
||||
import com.example.tank.di.NetworkModule
|
||||
import com.example.tank.ui.theme.TankTheme
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -53,31 +56,54 @@ fun MainScreen() {
|
||||
@Composable
|
||||
private fun MainContent() {
|
||||
val navController = rememberNavController()
|
||||
val context = LocalContext.current
|
||||
val settingsDataStore = remember { SettingsDataStore(context) }
|
||||
var isDarkTheme by remember { mutableStateOf(false) }
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
title = { Text("Fuel Prices") },
|
||||
actions = {
|
||||
IconButton(onClick = {
|
||||
navController.navigate("settings") {
|
||||
launchSingleTop = true
|
||||
}
|
||||
}) {
|
||||
Icon(Icons.Default.Settings, contentDescription = "Settings")
|
||||
}
|
||||
}
|
||||
)
|
||||
// Load saved theme preference
|
||||
LaunchedEffect(Unit) {
|
||||
settingsDataStore.isDarkTheme.collect { isDark ->
|
||||
isDarkTheme = isDark
|
||||
}
|
||||
) { padding ->
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = "prices",
|
||||
modifier = Modifier.padding(padding)
|
||||
) {
|
||||
composable("prices") { PricesScreen() }
|
||||
composable("settings") { SettingsScreen(navController = navController) }
|
||||
composable("map") { MapScreen(navController = navController) }
|
||||
}
|
||||
|
||||
TankTheme(darkTheme = isDarkTheme) {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
title = { Text("Fuel Prices") },
|
||||
actions = {
|
||||
IconButton(onClick = {
|
||||
navController.navigate("settings") {
|
||||
launchSingleTop = true
|
||||
}
|
||||
}) {
|
||||
Icon(Icons.Default.Settings, contentDescription = "Settings")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
) { padding ->
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = "prices",
|
||||
modifier = Modifier.padding(padding)
|
||||
) {
|
||||
composable("prices") { PricesScreen() }
|
||||
composable("settings") {
|
||||
SettingsScreen(
|
||||
navController = navController,
|
||||
isDarkTheme = isDarkTheme,
|
||||
onThemeChanged = { newTheme ->
|
||||
scope.launch {
|
||||
settingsDataStore.saveThemeMode(newTheme)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
composable("map") { MapScreen(navController = navController) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,4 +551,30 @@ 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)
|
||||
@Composable
|
||||
fun SettingsScreen(navController: NavController) {
|
||||
fun SettingsScreen(
|
||||
navController: NavController,
|
||||
isDarkTheme: Boolean,
|
||||
onThemeChanged: (Boolean) -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val settingsDataStore = remember { SettingsDataStore(context) }
|
||||
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))
|
||||
|
||||
// Save Button
|
||||
|
||||
Reference in New Issue
Block a user