DataStore Manager
This commit is contained in:
@@ -4,7 +4,7 @@ import android.app.Application
|
||||
import android.content.Context
|
||||
import com.kouros.navigation.data.ObjectBox
|
||||
import com.kouros.navigation.di.appModule
|
||||
import com.kouros.navigation.model.ViewModel
|
||||
import com.kouros.navigation.model.NavigationViewModel
|
||||
import com.kouros.navigation.utils.NavigationUtils.getViewModel
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.android.ext.koin.androidLogger
|
||||
@@ -15,7 +15,7 @@ class MainApplication : Application() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
ObjectBox.init(this);
|
||||
ObjectBox.init(this)
|
||||
appContext = applicationContext
|
||||
navigationViewModel = getViewModel(appContext!!)
|
||||
startKoin {
|
||||
@@ -30,6 +30,6 @@ class MainApplication : Application() {
|
||||
var appContext: Context? = null
|
||||
private set
|
||||
|
||||
lateinit var navigationViewModel : ViewModel
|
||||
lateinit var navigationViewModel : NavigationViewModel
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
package com.kouros.navigation.di
|
||||
|
||||
import com.kouros.navigation.data.NavigationRepository
|
||||
import com.kouros.navigation.data.osrm.OsrmRepository
|
||||
import com.kouros.navigation.data.tomtom.TomTomRepository
|
||||
import com.kouros.navigation.data.valhalla.ValhallaRepository
|
||||
import com.kouros.navigation.model.BaseStyleModel
|
||||
import com.kouros.navigation.model.ViewModel
|
||||
import com.kouros.navigation.model.NavigationViewModel
|
||||
import com.kouros.navigation.model.SettingsViewModel
|
||||
import com.kouros.navigation.repository.SettingsRepository
|
||||
import org.koin.core.module.dsl.singleOf
|
||||
import org.koin.core.module.dsl.viewModel
|
||||
import org.koin.core.module.dsl.viewModelOf
|
||||
import org.koin.dsl.module
|
||||
import kotlin.math.sin
|
||||
|
||||
val appModule = module {
|
||||
viewModelOf(::ViewModel)
|
||||
viewModelOf(::NavigationViewModel)
|
||||
viewModelOf(::SettingsViewModel)
|
||||
singleOf(::ValhallaRepository)
|
||||
singleOf(::OsrmRepository)
|
||||
singleOf(::TomTomRepository)
|
||||
|
||||
@@ -43,26 +43,27 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.google.android.gms.location.FusedLocationProviderClient
|
||||
import com.google.android.gms.location.LocationServices
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.MainApplication.Companion.navigationViewModel
|
||||
import com.kouros.navigation.data.Constants
|
||||
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
||||
import com.kouros.navigation.data.Constants.homeVogelhart
|
||||
import com.kouros.navigation.data.StepData
|
||||
import com.kouros.navigation.data.datastore.DataStoreManager
|
||||
import com.kouros.navigation.model.BaseStyleModel
|
||||
import com.kouros.navigation.model.MockLocation
|
||||
import com.kouros.navigation.model.RouteModel
|
||||
import com.kouros.navigation.repository.SettingsRepository
|
||||
import com.kouros.navigation.ui.app.AppViewModel
|
||||
import com.kouros.navigation.ui.app.appViewModel
|
||||
import com.kouros.navigation.ui.navigation.AppNavGraph
|
||||
import com.kouros.navigation.ui.theme.NavigationTheme
|
||||
import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue
|
||||
import com.kouros.navigation.utils.bearing
|
||||
import com.kouros.navigation.utils.calculateZoom
|
||||
import com.kouros.navigation.utils.getSettingsViewModel
|
||||
import com.kouros.navigation.utils.location
|
||||
import io.ticofab.androidgpxparser.parser.GPXParser
|
||||
import io.ticofab.androidgpxparser.parser.domain.Gpx
|
||||
@@ -70,7 +71,9 @@ import io.ticofab.androidgpxparser.parser.domain.TrackSegment
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.joda.time.DateTime
|
||||
import org.maplibre.compose.camera.CameraPosition
|
||||
import org.maplibre.compose.location.DesiredAccuracy
|
||||
@@ -83,12 +86,13 @@ import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
||||
val routeData = MutableLiveData("")
|
||||
|
||||
val routeModel = RouteModel()
|
||||
var tilt = 50.0
|
||||
val useMock = false
|
||||
val type = 3 // simulate 2 test 3 gpx 4 testSingle
|
||||
val useMock = true
|
||||
val type = 3 // 1 simulate 2 test 3 gpx 4 testSingle
|
||||
|
||||
var currentIndex = 0
|
||||
val stepData: MutableLiveData<StepData> by lazy {
|
||||
@@ -134,8 +138,7 @@ class MainActivity : ComponentActivity() {
|
||||
@RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION])
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val darkModeSettings = getIntKeyValue(applicationContext, Constants.DARK_MODE_SETTINGS)
|
||||
baseStyle = BaseStyleModel().readStyle(applicationContext, darkModeSettings, false)
|
||||
|
||||
if (useMock) {
|
||||
checkMockLocationEnabled()
|
||||
}
|
||||
@@ -150,6 +153,11 @@ class MainActivity : ComponentActivity() {
|
||||
navigationViewModel.route.observe(this, observer)
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
getSettingsViewModel(applicationContext).routingEngine.collect {
|
||||
|
||||
}
|
||||
}
|
||||
enableEdgeToEdge()
|
||||
setContent {
|
||||
CheckPermissionScreen()
|
||||
@@ -186,9 +194,13 @@ class MainActivity : ComponentActivity() {
|
||||
@Composable
|
||||
fun StartScreen(
|
||||
navController: NavHostController
|
||||
|
||||
) {
|
||||
|
||||
val appViewModel: AppViewModel = appViewModel()
|
||||
val darkMode by appViewModel.darkMode.collectAsState()
|
||||
|
||||
baseStyle = BaseStyleModel().readStyle(applicationContext, darkMode, darkMode == 1)
|
||||
|
||||
val scaffoldState = rememberBottomSheetScaffoldState()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -212,7 +224,7 @@ class MainActivity : ComponentActivity() {
|
||||
sheetPeekHeightState.value = 128.dp
|
||||
}
|
||||
}
|
||||
NavigationTheme {
|
||||
NavigationTheme (useDarkTheme = darkMode == 1) {
|
||||
BottomSheetScaffold(
|
||||
snackbarHost = {
|
||||
SnackbarHost(hostState = snackbarHostState)
|
||||
@@ -249,13 +261,12 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
@Composable
|
||||
fun App() {
|
||||
val navController = rememberNavController()
|
||||
NavHost(navController = navController, startDestination = "startScreen") {
|
||||
composable("startScreen") { StartScreen(navController) }
|
||||
composable("settings") { SettingsScreen(navController) { navController.popBackStack() } }
|
||||
composable("display_settings") { DisplayScreenSettings(applicationContext) { navController.popBackStack() } }
|
||||
composable("nav_settings") { NavigationScreenSettings(applicationContext) { navController.popBackStack() } }
|
||||
}
|
||||
//val lastRoute = NavigationUtils.getStringKeyValue(applicationContext, Constants.LAST_ROUTE)
|
||||
//if (lastRoute!!.isNotEmpty()) {
|
||||
// routeModel.startNavigation(lastRoute, applicationContext)
|
||||
// routeData.value = routeModel.curRoute.routeGeoJson
|
||||
//}
|
||||
AppNavGraph(applicationContext = applicationContext, this)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -285,13 +296,15 @@ class MainActivity : ComponentActivity() {
|
||||
if (!routeModel.isNavigating()) {
|
||||
SearchSheet(applicationContext, navigationViewModel, lastLocation) { closeSheet() }
|
||||
} else {
|
||||
NavigationSheet(
|
||||
applicationContext,
|
||||
routeModel,
|
||||
step!!,
|
||||
nextStep!!,
|
||||
{ stopNavigation { closeSheet() } },
|
||||
{ simulateNavigation() })
|
||||
if (step != null && nextStep != null) {
|
||||
NavigationSheet(
|
||||
applicationContext,
|
||||
routeModel,
|
||||
step,
|
||||
nextStep,
|
||||
{ stopNavigation { closeSheet() } },
|
||||
{ simulateNavigation() })
|
||||
}
|
||||
}
|
||||
// For recomposition!
|
||||
Text("$locationState", fontSize = 12.sp)
|
||||
@@ -303,17 +316,18 @@ class MainActivity : ComponentActivity() {
|
||||
val bearing = bearing(lastLocation, currentLocation, cameraPosition.value!!.bearing)
|
||||
with(routeModel) {
|
||||
if (isNavigating()) {
|
||||
updateLocation(currentLocation, navigationViewModel)
|
||||
updateLocation(applicationContext,currentLocation, navigationViewModel)
|
||||
stepData.value = currentStep()
|
||||
nextStepData.value = nextStep()
|
||||
if (navState.maneuverType in 39..42 && routeCalculator.leftStepDistance() < DESTINATION_ARRIVAL_DISTANCE) {
|
||||
// stopNavigation()
|
||||
navState.copy(arrived = true)
|
||||
navState = navState.copy(arrived = true)
|
||||
routeData.value = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
val zoom = calculateZoom(location.speed)
|
||||
//val zoom = calculateZoom(location.speed)
|
||||
val zoom = 16.0
|
||||
cameraPosition.postValue(
|
||||
cameraPosition.value!!.copy(
|
||||
zoom = zoom, target = location.position, bearing = bearing
|
||||
@@ -331,7 +345,7 @@ class MainActivity : ComponentActivity() {
|
||||
val latitude = routeModel.curRoute.waypoints[0][1]
|
||||
val longitude = routeModel.curRoute.waypoints[0][0]
|
||||
closeSheet()
|
||||
routeModel.stopNavigation()
|
||||
routeModel.stopNavigation(applicationContext)
|
||||
if (useMock) {
|
||||
mock.setMockLocation(latitude, longitude)
|
||||
}
|
||||
@@ -370,7 +384,7 @@ class MainActivity : ComponentActivity() {
|
||||
val deviation = 0.0
|
||||
if (index in 0..routeModel.curRoute.waypoints.size) {
|
||||
mock.setMockLocation(waypoint[1], waypoint[0])
|
||||
Thread.sleep(500)
|
||||
Thread.sleep(1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -381,7 +395,7 @@ class MainActivity : ComponentActivity() {
|
||||
for ((index, step) in routeModel.curLeg.steps.withIndex()) {
|
||||
//if (index in 3..3) {
|
||||
for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
||||
routeModel.updateLocation(
|
||||
routeModel.updateLocation(applicationContext,
|
||||
location(waypoint[0], waypoint[1]), navigationViewModel
|
||||
)
|
||||
val step = routeModel.currentStep()
|
||||
@@ -402,7 +416,7 @@ class MainActivity : ComponentActivity() {
|
||||
if (1 == 1) {
|
||||
mock.setMockLocation(latitude, longitude)
|
||||
} else {
|
||||
routeModel.updateLocation(
|
||||
routeModel.updateLocation(applicationContext,
|
||||
location(longitude, latitude), navigationViewModel
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,18 +5,24 @@ import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.window.layout.WindowMetricsCalculator
|
||||
import com.kouros.navigation.car.ViewStyle
|
||||
import com.kouros.navigation.car.map.MapLibre
|
||||
import com.kouros.navigation.car.map.NavigationImage
|
||||
import com.kouros.navigation.car.map.rememberBaseStyle
|
||||
import com.kouros.navigation.data.StepData
|
||||
import com.kouros.navigation.data.tomtom.TrafficData
|
||||
import com.kouros.navigation.ui.app.AppViewModel
|
||||
import com.kouros.navigation.ui.app.appViewModel
|
||||
import org.maplibre.compose.camera.CameraPosition
|
||||
import org.maplibre.compose.camera.rememberCameraState
|
||||
import org.maplibre.compose.location.LocationTrackingEffect
|
||||
@@ -57,7 +63,11 @@ fun MapView(
|
||||
)
|
||||
)
|
||||
|
||||
val rememberBaseStyle = rememberBaseStyle( baseStyle)
|
||||
val rememberBaseStyle = rememberBaseStyle(baseStyle)
|
||||
|
||||
val appViewModel: AppViewModel = appViewModel()
|
||||
val showBuildings by appViewModel.threedBuilding.collectAsState()
|
||||
|
||||
Column {
|
||||
NavigationInfo(step, nextStep)
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
@@ -67,7 +77,9 @@ fun MapView(
|
||||
rememberBaseStyle,
|
||||
route,
|
||||
emptyMap(),
|
||||
ViewStyle.VIEW
|
||||
ViewStyle.VIEW,
|
||||
speedCameras = "",
|
||||
showBuildings
|
||||
)
|
||||
LocationTrackingEffect(
|
||||
locationState = userLocationState,
|
||||
@@ -87,6 +99,3 @@ fun MapView(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,10 +2,15 @@ package com.kouros.navigation.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -17,39 +22,43 @@ import com.kouros.data.R
|
||||
import com.kouros.navigation.data.StepData
|
||||
import com.kouros.navigation.utils.round
|
||||
|
||||
|
||||
@Composable
|
||||
fun NavigationInfo(step: StepData?, nextStep: StepData?) {
|
||||
if (step != null && step.instruction.isNotEmpty()) {
|
||||
Card(modifier = Modifier.padding(top = 60.dp)) {
|
||||
Column() {
|
||||
ElevatedCard(
|
||||
elevation = CardDefaults.cardElevation(
|
||||
defaultElevation = 6.dp
|
||||
|
||||
), modifier = Modifier
|
||||
.padding(top = 60.dp)
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Column {
|
||||
Icon(
|
||||
painter = painterResource(step.icon),
|
||||
contentDescription = stringResource(id = R.string.accept_action_title),
|
||||
modifier = Modifier.size(48.dp, 48.dp),
|
||||
)
|
||||
if (step.currentManeuverType == 46
|
||||
|| step.currentManeuverType == 45
|
||||
) {
|
||||
Text(text = "Exit ${step.exitNumber}", fontSize = 18.sp)
|
||||
}
|
||||
Row {
|
||||
Icon(
|
||||
painter = painterResource(step.icon),
|
||||
contentDescription = stringResource(id = R.string.accept_action_title),
|
||||
modifier = Modifier.size(48.dp, 48.dp),
|
||||
)
|
||||
if (step.currentManeuverType == 46
|
||||
|| step.currentManeuverType == 45) {
|
||||
Text(text ="Exit ${step.exitNumber}", fontSize = 20.sp)
|
||||
}
|
||||
Column {
|
||||
if (step.leftStepDistance < 1000) {
|
||||
Text(text = "${step.leftStepDistance.toInt()} m", fontSize = 25.sp)
|
||||
} else {
|
||||
Text(
|
||||
text = "${(step.leftStepDistance / 1000).round(1)} km",
|
||||
fontSize = 25.sp
|
||||
)
|
||||
}
|
||||
Text(text = step.instruction, fontSize = 20.sp)
|
||||
}
|
||||
if (nextStep != null && step.icon != nextStep.icon) {
|
||||
Icon(
|
||||
painter = painterResource(nextStep.icon),
|
||||
contentDescription = stringResource(id = R.string.accept_action_title),
|
||||
modifier = Modifier.size(48.dp, 48.dp),
|
||||
if (step.leftStepDistance < 1000) {
|
||||
Text(text = "${step.leftStepDistance.toInt()} m", fontSize = 24.sp, color = MaterialTheme.colorScheme.primary)
|
||||
} else {
|
||||
Text(
|
||||
text = "${(step.leftStepDistance / 1000).round(1)} km",
|
||||
fontSize = 24.sp,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
Spacer(
|
||||
modifier = Modifier.padding(5.dp)
|
||||
)
|
||||
Text(text = step.instruction, fontSize = 24.sp, color = MaterialTheme.colorScheme.primary)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ fun NavigationSheet(
|
||||
val distance = (step.leftDistance / 1000).round(1)
|
||||
|
||||
if (step.lane.isNotEmpty()) {
|
||||
routeModel.navState.iconMapper.addLanes( step)
|
||||
// routeModel.navState.iconMapper.addLanes( step)
|
||||
}
|
||||
|
||||
Column {
|
||||
|
||||
@@ -4,10 +4,8 @@ import android.content.Context
|
||||
import android.location.Location
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
@@ -29,25 +27,21 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.semantics.isTraversalGroup
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.semantics.traversalIndex
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.data.Place
|
||||
import com.kouros.navigation.data.PlaceColor
|
||||
import com.kouros.navigation.data.nominatim.SearchResult
|
||||
import com.kouros.navigation.model.ViewModel
|
||||
import com.kouros.navigation.model.NavigationViewModel
|
||||
import com.kouros.navigation.utils.location
|
||||
|
||||
@Composable
|
||||
fun SearchSheet(
|
||||
applicationContext: Context,
|
||||
viewModel: ViewModel,
|
||||
viewModel: NavigationViewModel,
|
||||
location: Location,
|
||||
closeSheet: () -> Unit
|
||||
) {
|
||||
@@ -88,7 +82,7 @@ fun SearchSheet(
|
||||
@Composable
|
||||
fun Home(
|
||||
applicationContext: Context,
|
||||
viewModel: ViewModel,
|
||||
viewModel: NavigationViewModel,
|
||||
location: Location,
|
||||
closeSheet: () -> Unit
|
||||
) {
|
||||
@@ -125,7 +119,7 @@ fun SearchBar(
|
||||
searchPlaces: List<Place>,
|
||||
searchResults: List<SearchResult>,
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: ViewModel,
|
||||
viewModel: NavigationViewModel,
|
||||
context: Context,
|
||||
location: Location,
|
||||
closeSheet: () -> Unit
|
||||
@@ -166,14 +160,14 @@ fun SearchBar(
|
||||
}
|
||||
}
|
||||
|
||||
private fun searchPlaces(viewModel: ViewModel, location: Location, it: String) {
|
||||
private fun searchPlaces(viewModel: NavigationViewModel, location: Location, it: String) {
|
||||
viewModel.searchPlaces(it, location)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SearchPlaces(
|
||||
searchResults: List<SearchResult>,
|
||||
viewModel: ViewModel,
|
||||
viewModel: NavigationViewModel,
|
||||
context: Context,
|
||||
location: Location,
|
||||
closeSheet: () -> Unit
|
||||
@@ -222,7 +216,7 @@ private fun SearchPlaces(
|
||||
@Composable
|
||||
private fun RecentPlaces(
|
||||
recentPlaces: List<Place>,
|
||||
viewModel: ViewModel,
|
||||
viewModel: NavigationViewModel,
|
||||
context: Context,
|
||||
location: Location,
|
||||
closeSheet: () -> Unit
|
||||
|
||||
@@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
@@ -19,7 +20,6 @@ import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavHostController
|
||||
import com.alorma.compose.settings.ui.SettingsMenuLink
|
||||
import com.kouros.data.R
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||
@@ -53,34 +53,16 @@ fun SettingsScreen(navController: NavHostController, navigateBack: () -> Unit) {
|
||||
.verticalScroll(scrollState)
|
||||
.padding(top = padding.calculateTopPadding()),
|
||||
) {
|
||||
SettingsMenuLink(
|
||||
title = { Text(text = stringResource(R.string.display_settings)) },
|
||||
modifier = Modifier,
|
||||
enabled = true,
|
||||
onClick = { navController.navigate("display_settings")},
|
||||
icon = {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_place_white_24dp),
|
||||
contentDescription = stringResource(id = R.string.display_settings),
|
||||
modifier = Modifier.size(48.dp, 48.dp),
|
||||
)
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
|
||||
Button(onClick = { navController.navigate("display_settings") }) {
|
||||
Text(stringResource(R.string.display_settings))
|
||||
}
|
||||
)
|
||||
SettingsMenuLink(
|
||||
title = { Text(text = stringResource(R.string.navigation_settings)) },
|
||||
modifier = Modifier,
|
||||
enabled = true,
|
||||
onClick = { navController.navigate("nav_settings")},
|
||||
icon = {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.navigation_24px),
|
||||
contentDescription = stringResource(id = R.string.navigation_settings),
|
||||
modifier = Modifier.size(48.dp, 48.dp),
|
||||
)
|
||||
Button(onClick = { navController.navigate("nav_settings") }) {
|
||||
Text(stringResource(R.string.navigation_settings))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.kouros.navigation.ui.app
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.kouros.navigation.repository.SettingsRepository
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
|
||||
class AppViewModel(
|
||||
settingsRepository: SettingsRepository
|
||||
) : ViewModel() {
|
||||
|
||||
val darkMode = settingsRepository.darkModeFlow
|
||||
.stateIn(
|
||||
viewModelScope,
|
||||
SharingStarted.Eagerly,
|
||||
0
|
||||
)
|
||||
|
||||
val threedBuilding = settingsRepository.threedBuildingFlow
|
||||
.stateIn(
|
||||
viewModelScope,
|
||||
SharingStarted.Eagerly,
|
||||
false
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.kouros.navigation.ui.app
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.kouros.navigation.data.datastore.DataStoreManager
|
||||
import com.kouros.navigation.repository.SettingsRepository
|
||||
|
||||
|
||||
@Composable
|
||||
fun appViewModel(): AppViewModel {
|
||||
|
||||
val context = LocalContext.current
|
||||
|
||||
val dataStoreManager = remember { DataStoreManager(context) }
|
||||
val repository = remember { SettingsRepository(dataStoreManager) }
|
||||
|
||||
return viewModel(
|
||||
factory = object : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return AppViewModel(repository) as T
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.kouros.navigation.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.selection.selectable
|
||||
import androidx.compose.foundation.selection.selectableGroup
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.RadioButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
|
||||
@Composable
|
||||
fun RadioButtonSingleSelection(
|
||||
modifier: Modifier = Modifier,
|
||||
selectedOption: Int,
|
||||
radioOptions: List<String>,
|
||||
onClick: (Int) -> Unit,
|
||||
) {
|
||||
Column(modifier.selectableGroup()) {
|
||||
for ((index, text) in radioOptions.withIndex()) {
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.height(56.dp)
|
||||
.selectable(
|
||||
selected = (index == selectedOption),
|
||||
onClick = {
|
||||
onClick(index)
|
||||
},
|
||||
role = Role.RadioButton
|
||||
)
|
||||
.padding(horizontal = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
RadioButton(
|
||||
selected = (index == selectedOption),
|
||||
onClick = null
|
||||
)
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
modifier = Modifier.padding(start = 16.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.kouros.navigation.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun SectionTitle(title: String) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
modifier = Modifier.padding(top = 24.dp, bottom = 8.dp)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.kouros.navigation.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun SettingItem(
|
||||
title: String,
|
||||
value: String? = null
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 12.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text(text = title)
|
||||
value?.let {
|
||||
Text(text = it, color = MaterialTheme.colorScheme.primary)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.kouros.navigation.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.SwitchDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun SettingSwitch(
|
||||
title: String,
|
||||
checked: Boolean,
|
||||
onCheckedChange: (Boolean) -> Unit
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 12.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text(text = title)
|
||||
Switch(
|
||||
checked = checked,
|
||||
onCheckedChange = onCheckedChange,
|
||||
colors = SwitchDefaults.colors(
|
||||
checkedThumbColor = Color.White,
|
||||
uncheckedThumbColor = Color.White
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.kouros.navigation.ui.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.kouros.navigation.data.NavigationThemeColor
|
||||
|
||||
@Composable
|
||||
fun ThemeColorPicker(
|
||||
selectedColor: Long,
|
||||
onColorSelected: (Long) -> Unit
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
NavigationThemeColor.entries.forEach { themeColor ->
|
||||
|
||||
val isSelected = selectedColor == themeColor.color
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(36.dp)
|
||||
.clip(CircleShape)
|
||||
.background(Color(themeColor.color))
|
||||
.border(
|
||||
width = if (isSelected) 3.dp else 0.dp,
|
||||
color = if (isSelected) MaterialTheme.colorScheme.onSurface else Color.Transparent,
|
||||
shape = CircleShape
|
||||
)
|
||||
.clickable {
|
||||
onColorSelected(themeColor.color)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.kouros.navigation.ui.navigation
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.kouros.navigation.ui.MainActivity
|
||||
import com.kouros.navigation.ui.settings.NavigationScreenSettings
|
||||
import com.kouros.navigation.ui.SettingsScreen
|
||||
import com.kouros.navigation.ui.settings.DisplaySettings
|
||||
import com.kouros.navigation.ui.settings.SettingsRoute
|
||||
|
||||
|
||||
@Composable
|
||||
fun AppNavGraph(applicationContext: Context, mainActivity: MainActivity) {
|
||||
|
||||
val navController = rememberNavController()
|
||||
NavHost(navController = navController, startDestination = "startScreen") {
|
||||
composable("startScreen") { mainActivity.StartScreen(navController) }
|
||||
composable("settings") { SettingsScreen(navController) { navController.popBackStack() } }
|
||||
composable("settingsxx") {
|
||||
SettingsRoute("display_settings", navController) { navController.popBackStack() }
|
||||
}
|
||||
// old
|
||||
//composable("display_settings") { DisplaySettings(applicationContext) { navController.popBackStack() } }
|
||||
//composable("nav_settings") { NavigationScreenSettings(applicationContext) { navController.popBackStack() } }
|
||||
|
||||
// new
|
||||
composable("display_settings") { SettingsRoute("display_settings", navController) { navController.popBackStack() } }
|
||||
composable("nav_settings") { SettingsRoute("nav_settings", navController) { navController.popBackStack() } }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.kouros.navigation.ui
|
||||
package com.kouros.navigation.ui.settings
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@@ -32,13 +32,11 @@ import com.alorma.compose.settings.ui.SettingsRadioButton
|
||||
import com.alorma.compose.settings.ui.base.internal.LocalSettingsTileColors
|
||||
import com.alorma.compose.settings.ui.base.internal.SettingsTileDefaults
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.data.Constants.DARK_MODE_SETTINGS
|
||||
import com.kouros.navigation.data.Constants.SHOW_THREED_BUILDING
|
||||
import com.kouros.navigation.utils.NavigationUtils
|
||||
import com.kouros.navigation.utils.getSettingsViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun DisplayScreenSettings(context: Context, navigateBack: () -> Unit) {
|
||||
fun DisplaySettings(context: Context, navigateBack: () -> Unit) {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
@@ -75,13 +73,11 @@ fun DisplayScreenSettings(context: Context, navigateBack: () -> Unit) {
|
||||
|
||||
@Composable
|
||||
private fun DisplaySettings(context: Context) {
|
||||
val settingsViewModel = getSettingsViewModel(context)
|
||||
Section(title = "Anzeige") {
|
||||
val state = remember {
|
||||
mutableStateOf(
|
||||
NavigationUtils.getBooleanKeyValue(
|
||||
context,
|
||||
SHOW_THREED_BUILDING
|
||||
)
|
||||
settingsViewModel.threedBuilding.value
|
||||
)
|
||||
}
|
||||
SettingsCheckbox(
|
||||
@@ -89,17 +85,14 @@ private fun DisplaySettings(context: Context) {
|
||||
title = { Text(text = stringResource(R.string.threed_building)) },
|
||||
onCheckedChange = {
|
||||
state.value = it
|
||||
NavigationUtils.setBooleanKeyValue(context, it, SHOW_THREED_BUILDING)
|
||||
settingsViewModel.onThreedBuildingChanged(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
Section(title = "Dunkles Design") {
|
||||
val state = remember {
|
||||
mutableIntStateOf(
|
||||
NavigationUtils.getIntKeyValue(
|
||||
context,
|
||||
DARK_MODE_SETTINGS
|
||||
)
|
||||
settingsViewModel.darkMode.value
|
||||
)
|
||||
}
|
||||
DarkModeData(context).darkDesign.forEach { sampleItem ->
|
||||
@@ -108,7 +101,7 @@ private fun DisplaySettings(context: Context) {
|
||||
title = { Text(text = sampleItem.title) },
|
||||
onClick = {
|
||||
state.intValue = sampleItem.key
|
||||
NavigationUtils.setIntKeyValue(context, state.intValue, DARK_MODE_SETTINGS)
|
||||
settingsViewModel.onDarkModeChanged(state.intValue)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.kouros.navigation.ui
|
||||
package com.kouros.navigation.ui.settings
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -25,10 +25,10 @@ import com.alorma.compose.settings.ui.SettingsCheckbox
|
||||
import com.alorma.compose.settings.ui.SettingsRadioButton
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.data.Constants
|
||||
import com.kouros.navigation.data.Constants.DARK_MODE_SETTINGS
|
||||
import com.kouros.navigation.data.Constants.ROUTING_ENGINE
|
||||
import com.kouros.navigation.data.RouteEngine
|
||||
import com.kouros.navigation.utils.NavigationUtils
|
||||
import com.kouros.navigation.utils.getSettingsViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -68,13 +68,11 @@ fun NavigationScreenSettings(context: Context, navigateBack: () -> Unit) {
|
||||
|
||||
@Composable
|
||||
private fun NavigationSettings(context: Context) {
|
||||
val settingsViewModel = getSettingsViewModel(context)
|
||||
Section(title = stringResource(id = R.string.options)) {
|
||||
val avoidMotorwayState = remember {
|
||||
mutableStateOf(
|
||||
NavigationUtils.getBooleanKeyValue(
|
||||
context,
|
||||
Constants.AVOID_MOTORWAY
|
||||
)
|
||||
settingsViewModel.avoidMotorway.value
|
||||
)
|
||||
}
|
||||
SettingsCheckbox(
|
||||
@@ -82,16 +80,13 @@ private fun NavigationSettings(context: Context) {
|
||||
title = { Text(text = stringResource(id = R.string.avoid_highways_row_title)) },
|
||||
onCheckedChange = {
|
||||
avoidMotorwayState.value = it
|
||||
NavigationUtils.setBooleanKeyValue(context, it, Constants.AVOID_MOTORWAY)
|
||||
settingsViewModel.onAvoidMotorway(it)
|
||||
},
|
||||
)
|
||||
|
||||
val avoidTollwayState = remember {
|
||||
mutableStateOf(
|
||||
NavigationUtils.getBooleanKeyValue(
|
||||
context,
|
||||
Constants.AVOID_TOLLWAY
|
||||
)
|
||||
settingsViewModel.avoidTollway.value
|
||||
)
|
||||
}
|
||||
SettingsCheckbox(
|
||||
@@ -99,16 +94,13 @@ private fun NavigationSettings(context: Context) {
|
||||
title = { Text(text = stringResource(id = R.string.avoid_tolls_row_title)) },
|
||||
onCheckedChange = {
|
||||
avoidTollwayState.value = it
|
||||
NavigationUtils.setBooleanKeyValue(context, it, Constants.AVOID_TOLLWAY)
|
||||
settingsViewModel.onAvoidTollway(it)
|
||||
},
|
||||
)
|
||||
|
||||
val carLocationState = remember {
|
||||
mutableStateOf(
|
||||
NavigationUtils.getBooleanKeyValue(
|
||||
context,
|
||||
Constants.CAR_LOCATION
|
||||
)
|
||||
settingsViewModel.carLocation.value
|
||||
)
|
||||
}
|
||||
SettingsCheckbox(
|
||||
@@ -116,7 +108,7 @@ private fun NavigationSettings(context: Context) {
|
||||
title = { Text(text = stringResource(id = R.string.use_car_location)) },
|
||||
onCheckedChange = {
|
||||
carLocationState.value = it
|
||||
NavigationUtils.setBooleanKeyValue(context, it, Constants.CAR_LOCATION)
|
||||
settingsViewModel.onCarLocation(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -124,10 +116,7 @@ private fun NavigationSettings(context: Context) {
|
||||
Section(title = stringResource(id = R.string.routing_engine)) {
|
||||
val state = remember {
|
||||
mutableIntStateOf(
|
||||
NavigationUtils.getIntKeyValue(
|
||||
context,
|
||||
ROUTING_ENGINE
|
||||
)
|
||||
settingsViewModel.routingEngine.value
|
||||
)
|
||||
}
|
||||
RoutingEngineData.engines.forEach { sampleItem ->
|
||||
@@ -136,7 +125,7 @@ private fun NavigationSettings(context: Context) {
|
||||
title = { Text(text = sampleItem.title) },
|
||||
onClick = {
|
||||
state.intValue = sampleItem.key
|
||||
NavigationUtils.setIntKeyValue(context, state.intValue, ROUTING_ENGINE)
|
||||
settingsViewModel.onRoutingEngineChanged(state.intValue)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.kouros.navigation.ui.settings
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavHostController
|
||||
import com.kouros.navigation.data.datastore.DataStoreManager
|
||||
import com.kouros.navigation.model.SettingsViewModel
|
||||
import com.kouros.navigation.repository.SettingsRepository
|
||||
|
||||
@Composable
|
||||
fun SettingsRoute(route: String, navController: NavHostController, function: () -> Boolean) {
|
||||
|
||||
val context = LocalContext.current
|
||||
|
||||
val dataStoreManager = remember { DataStoreManager(context) }
|
||||
val repository = remember { SettingsRepository(dataStoreManager) }
|
||||
|
||||
val viewModel: SettingsViewModel = viewModel(
|
||||
factory = object : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return SettingsViewModel(repository) as T
|
||||
}
|
||||
}
|
||||
)
|
||||
if (route == "display_settings") {
|
||||
SettingsScreen(viewModel = viewModel)
|
||||
}
|
||||
if (route == "nav_settings") {
|
||||
SettingsScreen(viewModel = viewModel)
|
||||
}
|
||||
///DisplaySettings(context, viewModel, navController.popBackStack())
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package com.kouros.navigation.ui.settings
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.model.SettingsViewModel
|
||||
import com.kouros.navigation.ui.components.RadioButtonSingleSelection
|
||||
import com.kouros.navigation.ui.components.SectionTitle
|
||||
import com.kouros.navigation.ui.components.SettingSwitch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun SettingsScreen(viewModel: SettingsViewModel) {
|
||||
|
||||
val darkMode by viewModel.darkMode.collectAsState()
|
||||
val threedBuilding by viewModel.threedBuilding.collectAsState()
|
||||
val avoidMotorway by viewModel.avoidMotorway.collectAsState()
|
||||
val avoidTollway by viewModel.avoidTollway.collectAsState()
|
||||
val carLocation by viewModel.carLocation.collectAsState()
|
||||
val routingEngine by viewModel.routingEngine.collectAsState()
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
stringResource(id = R.string.display_settings),
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
// IconButton(onClick = navigateBack) {
|
||||
// Icon(
|
||||
// painter = painterResource(R.drawable.arrow_back_24px),
|
||||
// contentDescription = stringResource(id = R.string.accept_action_title),
|
||||
// modifier = Modifier.size(48.dp, 48.dp),
|
||||
// )
|
||||
// }
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
{ padding ->
|
||||
val scrollState = rememberScrollState()
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(top = 20.dp)
|
||||
.verticalScroll(scrollState)
|
||||
) {
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.settings_action_title),
|
||||
style = MaterialTheme.typography.headlineMedium
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
// Appearance
|
||||
SectionTitle(stringResource(R.string.threed_building))
|
||||
|
||||
SettingSwitch(
|
||||
title = stringResource(R.string.threed_building),
|
||||
checked = threedBuilding,
|
||||
onCheckedChange = viewModel::onThreedBuildingChanged
|
||||
)
|
||||
|
||||
SectionTitle(stringResource(R.string.dark_mode))
|
||||
|
||||
val radioOptions = listOf(
|
||||
stringResource(R.string.off_action_title),
|
||||
stringResource(R.string.on_action_title),
|
||||
stringResource(R.string.use_telephon_settings)
|
||||
)
|
||||
RadioButtonSingleSelection(
|
||||
modifier = Modifier.padding(),
|
||||
selectedOption = darkMode,
|
||||
radioOptions = radioOptions,
|
||||
onClick = viewModel::onDarkModeChanged
|
||||
)
|
||||
|
||||
// Appearance
|
||||
SectionTitle(stringResource(R.string.navigation_settings))
|
||||
|
||||
SettingSwitch(
|
||||
title = stringResource(R.string.avoid_highways_row_title),
|
||||
checked = avoidMotorway,
|
||||
onCheckedChange = viewModel::onAvoidMotorway
|
||||
)
|
||||
|
||||
SettingSwitch(
|
||||
title = stringResource(R.string.avoid_tolls_row_title),
|
||||
checked = avoidTollway,
|
||||
onCheckedChange = viewModel::onAvoidTollway
|
||||
)
|
||||
|
||||
SettingSwitch(
|
||||
title = stringResource(R.string.use_car_location),
|
||||
checked = carLocation,
|
||||
onCheckedChange = viewModel::onCarLocation
|
||||
)
|
||||
|
||||
SectionTitle(stringResource(R.string.routing_engine))
|
||||
|
||||
val routingEngineOptions = listOf(
|
||||
stringResource(R.string.valhalla),
|
||||
stringResource(R.string.osrm),
|
||||
stringResource(R.string.tomtom)
|
||||
)
|
||||
RadioButtonSingleSelection(
|
||||
modifier = Modifier.padding(),
|
||||
selectedOption = routingEngine,
|
||||
radioOptions = routingEngineOptions,
|
||||
onClick = viewModel::onRoutingEngineChanged
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ fun NavigationTheme(
|
||||
}
|
||||
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
colorScheme = if (useDarkTheme) darkColorScheme() else colorScheme,
|
||||
typography = typography,
|
||||
content = content,
|
||||
shapes = shapes,
|
||||
|
||||
Reference in New Issue
Block a user