Move osm settings to its own settings page

This commit is contained in:
MM20 2024-06-30 14:38:33 +02:00
parent 429025e5ac
commit e96a382b00
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
10 changed files with 145 additions and 62 deletions

View File

@ -243,5 +243,6 @@ class SearchableItemVM : ListItemViewModel(), KoinComponent {
.stateIn(viewModelScope, SharingStarted.Lazily, false)
val mapTileServerUrl = locationSearchSettings.tileServer
.map { it ?: LocationSearchSettings.DefaultTileServerUrl }
.stateIn(viewModelScope, SharingStarted.Lazily, "")
}

View File

@ -55,6 +55,7 @@ import de.mm20.launcher2.ui.settings.log.LogScreen
import de.mm20.launcher2.ui.settings.main.MainSettingsScreen
import de.mm20.launcher2.ui.settings.media.MediaIntegrationSettingsScreen
import de.mm20.launcher2.ui.settings.nextcloud.NextcloudSettingsScreen
import de.mm20.launcher2.ui.settings.osm.OsmSettingsScreen
import de.mm20.launcher2.ui.settings.owncloud.OwncloudSettingsScreen
import de.mm20.launcher2.ui.settings.plugins.PluginSettingsScreen
import de.mm20.launcher2.ui.settings.plugins.PluginsSettingsScreen
@ -106,7 +107,7 @@ class SettingsActivity : BaseActivity() {
navController = navController,
startDestination = "settings",
exitTransition = {
slideOutHorizontally { it / 4 }
slideOutHorizontally {-it / 4 }
},
enterTransition = {
slideInHorizontally { it / 2 } + scaleIn(initialScale = 0.9f) + fadeIn()
@ -162,6 +163,9 @@ class SettingsActivity : BaseActivity() {
composable("settings/search/locations") {
LocationsSettingsScreen()
}
composable("settings/search/locations/osm") {
OsmSettingsScreen()
}
composable("settings/search/files") {
FileSearchSettingsScreen()
}

View File

@ -29,20 +29,22 @@ import de.mm20.launcher2.ui.component.Banner
import de.mm20.launcher2.ui.component.preferences.ListPreference
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
import de.mm20.launcher2.ui.component.preferences.PreferenceWithSwitch
import de.mm20.launcher2.ui.component.preferences.SliderPreference
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
import de.mm20.launcher2.ui.component.preferences.TextPreference
import de.mm20.launcher2.ui.ktx.metersToLocalizedString
import de.mm20.launcher2.ui.locals.LocalNavController
@Composable
fun LocationsSettingsScreen() {
val viewModel: LocationsSettingsScreenVM = viewModel()
val navController = LocalNavController.current
val osmLocations by viewModel.osmLocations.collectAsState()
val imperialUnits by viewModel.imperialUnits.collectAsState()
val hideUncategorized by viewModel.hideUncategorized.collectAsState()
val radius by viewModel.radius.collectAsState()
val customOverpassUrl by viewModel.customOverpassUrl.collectAsState()
val showMap by viewModel.showMap.collectAsState()
val themeMap by viewModel.themeMap.collectAsState()
val customTileServerUrl by viewModel.customTileServerUrl.collectAsState()
@ -59,12 +61,15 @@ fun LocationsSettingsScreen() {
PreferenceScreen(title = stringResource(R.string.preference_search_locations)) {
item {
PreferenceCategory {
SwitchPreference(
PreferenceWithSwitch(
title = stringResource(R.string.preference_search_osm_locations),
summary = stringResource(R.string.preference_search_osm_locations_summary),
value = osmLocations == true,
onValueChanged = {
switchValue = osmLocations == true,
onSwitchChanged = {
viewModel.setOsmLocations(it)
},
onClick = {
navController?.navigate("settings/search/locations/osm")
}
)
AnimatedVisibility(plugins.isNotEmpty()) {
@ -150,15 +155,6 @@ fun LocationsSettingsScreen() {
.metersToLocalizedString(LocalContext.current, imperialUnits)
}
)
SwitchPreference(
title = stringResource(R.string.preference_search_locations_hide_uncategorized),
summary = stringResource(R.string.preference_search_locations_hide_uncategorized_summary),
value = hideUncategorized == true,
enabled = anyLocationProviderEnabled,
onValueChanged = {
viewModel.setHideUncategorized(it)
}
)
}
}
item {
@ -186,22 +182,11 @@ fun LocationsSettingsScreen() {
}
item {
PreferenceCategory(stringResource(R.string.preference_category_advanced)) {
TextPreference(
title = stringResource(R.string.preference_search_location_custom_overpass_url),
value = customOverpassUrl,
placeholder = LocationSearchSettings.DefaultOverpassUrl,
summary = customOverpassUrl.takeIf { it.isNotBlank() }
?: LocationSearchSettings.DefaultOverpassUrl,
onValueChanged = {
viewModel.setCustomOverpassUrl(it)
},
enabled = osmLocations == true,
)
TextPreference(
title = stringResource(R.string.preference_search_location_custom_tile_server_url),
value = customTileServerUrl ?: "",
placeholder = LocationSearchSettings.DefaultTileServerUrl,
summary = customTileServerUrl.takeIf { !it.isNullOrBlank() }
summary = customTileServerUrl?.takeIf { it.isNotBlank() }
?: LocationSearchSettings.DefaultTileServerUrl,
onValueChanged = {
viewModel.setCustomTileServerUrl(it)

View File

@ -42,21 +42,6 @@ class LocationsSettingsScreenVM : ViewModel(), KoinComponent {
settings.setSearchRadius(radius)
}
val customOverpassUrl = settings.overpassUrl
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), "")
fun setCustomOverpassUrl(customUrl: String) {
var url = customUrl
if (url.endsWith('/')) {
url = url.substringBeforeLast('/')
}
if (url.endsWith("/api/interpreter")) {
url = url.substringBeforeLast("/api/interpreter")
}
settings.setOverpassUrl(url)
}
val showMap = settings.showMap
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
@ -68,14 +53,7 @@ class LocationsSettingsScreenVM : ViewModel(), KoinComponent {
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setCustomTileServerUrl(customTileServerUrl: String) {
settings.setTileServer(customTileServerUrl)
}
val hideUncategorized = settings.hideUncategorized
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setHideUncategorized(hideUncategorized: Boolean) {
settings.setHideUncategorized(hideUncategorized)
settings.setTileServer(customTileServerUrl.takeIf { it.isNotBlank() })
}
val themeMap = settings.themeMap

View File

@ -6,14 +6,12 @@ import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.Login
import androidx.compose.material.icons.automirrored.rounded.Logout
import androidx.compose.material.icons.rounded.Logout
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.HorizontalDivider

View File

@ -0,0 +1,61 @@
package de.mm20.launcher2.ui.settings.osm
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.preferences.search.LocationSearchSettings
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
import de.mm20.launcher2.ui.component.preferences.TextPreference
@Composable
fun OsmSettingsScreen() {
val viewModel: OsmSettingsScreenVM = viewModel()
val osmLocations by viewModel.osmLocations.collectAsState()
val hideUncategorized by viewModel.hideUncategorized.collectAsState()
val customOverpassUrl by viewModel.customOverpassUrl.collectAsState()
PreferenceScreen(title = stringResource(R.string.preference_search_osm_locations)) {
item {
PreferenceCategory {
SwitchPreference(
title = stringResource(R.string.preference_search_osm_locations),
summary = stringResource(R.string.preference_search_osm_locations_summary),
value = osmLocations == true,
onValueChanged = {
viewModel.setOsmLocations(it)
},
)
SwitchPreference(
title = stringResource(R.string.preference_search_locations_hide_uncategorized),
summary = stringResource(R.string.preference_search_locations_hide_uncategorized_summary),
value = hideUncategorized == true,
enabled = osmLocations == true,
onValueChanged = {
viewModel.setHideUncategorized(it)
}
)
}
}
item {
PreferenceCategory(stringResource(R.string.preference_category_advanced)) {
TextPreference(
title = stringResource(R.string.preference_search_location_custom_overpass_url),
value = customOverpassUrl ?: "",
placeholder = LocationSearchSettings.DefaultOverpassUrl,
summary = customOverpassUrl?.takeIf { it.isNotBlank() }
?: LocationSearchSettings.DefaultOverpassUrl,
onValueChanged = {
viewModel.setCustomOverpassUrl(it)
},
enabled = osmLocations == true,
)
}
}
}
}

View File

@ -0,0 +1,36 @@
package de.mm20.launcher2.ui.settings.osm
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.plugins.PluginService
import de.mm20.launcher2.preferences.search.LocationSearchSettings
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.stateIn
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class OsmSettingsScreenVM: ViewModel(), KoinComponent {
private val settings: LocationSearchSettings by inject()
private val pluginService: PluginService by inject()
val osmLocations = settings.osmLocations
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setOsmLocations(osmLocations: Boolean) {
settings.setOsmLocations(osmLocations)
}
val hideUncategorized = settings.hideUncategorized
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setHideUncategorized(hideUncategorized: Boolean) {
settings.setHideUncategorized(hideUncategorized)
}
val customOverpassUrl = settings.overpassUrl
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), "")
fun setCustomOverpassUrl(customUrl: String) {
settings.setOverpassUrl(customUrl)
}
}

View File

@ -141,8 +141,8 @@ data class LauncherSettingsData internal constructor(
val locationSearchImperialUnits: Boolean = false,
val locationSearchRadius: Int = 1500,
val locationSearchHideUncategorized: Boolean = true,
val locationSearchOverpassUrl: String = LocationSearchSettings.DefaultOverpassUrl,
val locationSearchTileServer: String = LocationSearchSettings.DefaultTileServerUrl,
val locationSearchOverpassUrl: String? = null,
val locationSearchTileServer: String? = null,
val locationSearchShowMap: Boolean = true,
val locationSearchShowPositionOnMap: Boolean = false,
val locationSearchThemeMap: Boolean = true,

View File

@ -72,18 +72,39 @@ class LocationSearchSettings internal constructor(
val overpassUrl
get() = launcherDataStore.data.map { it.locationSearchOverpassUrl }
fun setOverpassUrl(overpassUrl: String) {
fun setOverpassUrl(overpassUrl: String?) {
var url = overpassUrl
if (url != null) {
if (!url.startsWith("http://") && !url.startsWith("https://")) {
url = "https://$url"
}
if (url.endsWith('/')) {
url = url.substringBeforeLast('/')
}
if (url.endsWith("/api/interpreter")) {
url = url.substringBeforeLast("/api/interpreter")
}
}
launcherDataStore.update {
it.copy(locationSearchOverpassUrl = overpassUrl)
it.copy(locationSearchOverpassUrl = url)
}
}
val tileServer
get() = launcherDataStore.data.map { it.locationSearchTileServer }
fun setTileServer(tileServer: String) {
fun setTileServer(tileServer: String?) {
var url = tileServer
if (url != null) {
if (!url.startsWith("http://") && !url.startsWith("https://")) {
url = "https://$url"
}
if (!url.contains("\${z}") || !url.contains("\${x}") || !url.contains("\${y}")) {
url = "$url/\${z}/\${x}/\${y}.png"
}
}
launcherDataStore.update {
it.copy(locationSearchTileServer = tileServer)
it.copy(locationSearchTileServer = url)
}
}
@ -125,8 +146,8 @@ data class LocationSearchSettingsData(
val providers: Set<String> = setOf("openstreetmaps"),
val searchRadius: Int = 1500,
val hideUncategorized: Boolean = true,
val overpassUrl: String = LocationSearchSettings.DefaultOverpassUrl,
val tileServer: String = LocationSearchSettings.DefaultTileServerUrl,
val overpassUrl: String? = null,
val tileServer: String? = null,
val imperialUnits: Boolean = false,
val showMap: Boolean = false,
val showPositionOnMap: Boolean = false,

View File

@ -38,8 +38,7 @@ internal class OsmLocationProvider(
try {
Retrofit.Builder()
.client(HttpClient)
.baseUrl(it.takeIf { it.isNotBlank() }
?: LocationSearchSettings.DefaultOverpassUrl)
.baseUrl(it?.takeIf { it.isNotBlank() } ?: LocationSearchSettings.DefaultOverpassUrl)
.addConverterFactory(OverpassQueryConverterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build()