diff --git a/i18n/src/main/res/values-de/strings.xml b/i18n/src/main/res/values-de/strings.xml
index 4f49e5ca..e6cfa307 100644
--- a/i18n/src/main/res/values-de/strings.xml
+++ b/i18n/src/main/res/values-de/strings.xml
@@ -420,4 +420,7 @@
Raster
Spaltenanzahl
+
+ Gewähren
+ Standortzugriff wird benötigt, um den Standort automatisch zu ermitteln
\ No newline at end of file
diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml
index d4be9850..b36cd965 100644
--- a/i18n/src/main/res/values/strings.xml
+++ b/i18n/src/main/res/values/strings.xml
@@ -458,4 +458,7 @@
Grid
Number of columns
+
+ Grant
+ Location access is required to determine the location automatically
diff --git a/ui/src/main/java/de/mm20/launcher2/ui/component/MissingPermissionBanner.kt b/ui/src/main/java/de/mm20/launcher2/ui/component/MissingPermissionBanner.kt
index b184e859..1187a36c 100644
--- a/ui/src/main/java/de/mm20/launcher2/ui/component/MissingPermissionBanner.kt
+++ b/ui/src/main/java/de/mm20/launcher2/ui/component/MissingPermissionBanner.kt
@@ -11,7 +11,9 @@ import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
+import de.mm20.launcher2.ui.R
@Composable
fun MissingPermissionBanner(
@@ -53,7 +55,7 @@ fun MissingPermissionBanner(
TextButton(
modifier = Modifier.padding(start = 8.dp),
onClick = onClick) {
- Text("Grant", style = MaterialTheme.typography.labelLarge)
+ Text(stringResource(R.string.grant_permission), style = MaterialTheme.typography.labelLarge)
}
}
diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherScreen.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherScreen.kt
index 63721785..df885d72 100644
--- a/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherScreen.kt
+++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherScreen.kt
@@ -1,5 +1,7 @@
package de.mm20.launcher2.ui.settings.weather
+import androidx.appcompat.app.AppCompatActivity
+import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
@@ -18,12 +20,14 @@ import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.preferences.Settings.WeatherSettings.WeatherProvider
import de.mm20.launcher2.ui.R
+import de.mm20.launcher2.ui.component.MissingPermissionBanner
import de.mm20.launcher2.ui.component.preferences.*
import de.mm20.launcher2.weather.WeatherLocation
import kotlinx.coroutines.launch
@@ -31,6 +35,7 @@ import kotlinx.coroutines.launch
@Composable
fun WeatherScreen() {
val viewModel: WeatherScreenVM = viewModel()
+ val context = LocalContext.current
PreferenceScreen(title = stringResource(R.string.preference_screen_weather)) {
item {
@@ -62,6 +67,16 @@ fun WeatherScreen() {
}
item {
PreferenceCategory(title = stringResource(R.string.preference_category_location)) {
+ val hasPermission by viewModel.hasLocationPermission.observeAsState()
+ AnimatedVisibility(hasPermission == false) {
+ MissingPermissionBanner(
+ text = stringResource(R.string.missing_permission_auto_location),
+ onClick = {
+ viewModel.requestLocationPermission(context as AppCompatActivity)
+ },
+ modifier = Modifier.padding(16.dp)
+ )
+ }
val autoLocation by viewModel.autoLocation.observeAsState(false)
SwitchPreference(
title = stringResource(R.string.preference_automatic_location),
@@ -181,7 +196,9 @@ fun LocationPreference(
}
TextButton(
onClick = { showDialog = false },
- modifier = Modifier.align(Alignment.End).padding(24.dp)
+ modifier = Modifier
+ .align(Alignment.End)
+ .padding(24.dp)
) {
Text(
text = stringResource(R.string.close),
diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherScreenVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherScreenVM.kt
index c286fe6e..af52e0e6 100644
--- a/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherScreenVM.kt
+++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherScreenVM.kt
@@ -1,9 +1,12 @@
package de.mm20.launcher2.ui.settings.weather
+import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
+import de.mm20.launcher2.permissions.PermissionGroup
+import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings.WeatherSettings
import de.mm20.launcher2.weather.WeatherLocation
@@ -19,6 +22,7 @@ import kotlin.coroutines.coroutineContext
class WeatherScreenVM : ViewModel(), KoinComponent {
private val repository: WeatherRepository by inject()
private val dataStore: LauncherDataStore by inject()
+ private val permissionsManager: PermissionsManager by inject()
val imperialUnits = dataStore.data.map { it.weather.imperialUnits }.asLiveData()
fun setImperialUnits(imperialUnits: Boolean) {
@@ -65,6 +69,12 @@ class WeatherScreenVM : ViewModel(), KoinComponent {
}
}
+ val hasLocationPermission = permissionsManager.hasPermission(PermissionGroup.Location).asLiveData()
+
+ fun requestLocationPermission(activity: AppCompatActivity) {
+ permissionsManager.requestPermission(activity, PermissionGroup.Location)
+ }
+
val isSearchingLocation = MutableLiveData(false)
val locationResults = MutableLiveData>(emptyList())