Move osm settings to its own settings page
This commit is contained in:
parent
429025e5ac
commit
e96a382b00
@ -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, "")
|
||||
}
|
||||
@ -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()
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user