This commit is contained in:
inhale-dir
2024-12-12 20:57:38 +01:00
parent 9c0e2fd071
commit 333b779c73
4 changed files with 113 additions and 24 deletions
@@ -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) }
}
}
}
}
@@ -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)
@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