diff --git a/i18n/src/main/res/values-de/strings.xml b/i18n/src/main/res/values-de/strings.xml index 64e6079c..78045354 100644 --- a/i18n/src/main/res/values-de/strings.xml +++ b/i18n/src/main/res/values-de/strings.xml @@ -471,6 +471,7 @@ Kalenderzugriff wird benötigt um Termine abzurufen Speicher-Berechtigung wird benötigt um lokale Dateien zu durchsuchen Alle Dateien verwalten-Berechtigung wird benötigt um lokale Dateien zu durchsuchen + Benachrichtigungszugriff wird benötigt um Benachrichtigungsplaketten anzuzeigen Websuche hinzufügen Websuche bearbeiten diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml index e63145b0..a4799e55 100644 --- a/i18n/src/main/res/values/strings.xml +++ b/i18n/src/main/res/values/strings.xml @@ -437,6 +437,8 @@ This widget requires calendar permission Manage all files permission is required to search local files External storage permission is required to search local files + Notification access is requried to display notification badges + Set location Debug diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/badges/BadgeSettingsScreen.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/badges/BadgeSettingsScreen.kt index 3e04216f..861a2e21 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/settings/badges/BadgeSettingsScreen.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/badges/BadgeSettingsScreen.kt @@ -1,55 +1,76 @@ package de.mm20.launcher2.ui.settings.badges +import androidx.appcompat.app.AppCompatActivity +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState +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.lifecycle.viewmodel.compose.viewModel import de.mm20.launcher2.ui.R +import de.mm20.launcher2.ui.component.MissingPermissionBanner +import de.mm20.launcher2.ui.component.preferences.PreferenceCategory import de.mm20.launcher2.ui.component.preferences.PreferenceScreen import de.mm20.launcher2.ui.component.preferences.SwitchPreference @Composable fun BadgeSettingsScreen() { val viewModel: BadgeSettingsScreenVM = viewModel() + val context = LocalContext.current PreferenceScreen(title = stringResource(R.string.preference_screen_badges)) { item { - val notifications by viewModel.notifications.observeAsState() - SwitchPreference( - title = stringResource(R.string.preference_notification_badges), - summary = stringResource(R.string.preference_notification_badges_summary), - value = notifications == true, - onValueChanged = { - viewModel.setNotifications(it) + PreferenceCategory { + val notifications by viewModel.notifications.observeAsState() + val hasNotificationsPermission by viewModel.hasNotificationsPermission.observeAsState() + AnimatedVisibility(hasNotificationsPermission == false) { + MissingPermissionBanner( + text = stringResource(R.string.missing_permission_notification_badges), + onClick = { + viewModel.requestNotificationsPermission(context as AppCompatActivity) + }, + modifier = Modifier.padding(16.dp) + ) } - ) - val cloudFiles by viewModel.cloudFiles.observeAsState() - SwitchPreference( - title = stringResource(R.string.preference_cloud_badges), - summary = stringResource(R.string.preference_cloud_badges_summary), - value = cloudFiles == true, - onValueChanged = { - viewModel.setCloudFiles(it) - } - ) - val suspendedApps by viewModel.suspendedApps.observeAsState() - SwitchPreference( - title = stringResource(R.string.preference_suspended_badges), - summary = stringResource(R.string.preference_suspended_badges_summary), - value = suspendedApps == true, - onValueChanged = { - viewModel.setSuspendedApps(it) - } - ) - val shortcuts by viewModel.shortcuts.observeAsState() - SwitchPreference( - title = stringResource(R.string.preference_shortcut_badges), - summary = stringResource(R.string.preference_shortcut_badges_summary), - value = shortcuts == true, - onValueChanged = { - viewModel.setShortcuts(it) - } - ) + SwitchPreference( + title = stringResource(R.string.preference_notification_badges), + summary = stringResource(R.string.preference_notification_badges_summary), + value = notifications == true && hasNotificationsPermission == false, + onValueChanged = { + viewModel.setNotifications(it) + } + ) + val cloudFiles by viewModel.cloudFiles.observeAsState() + SwitchPreference( + title = stringResource(R.string.preference_cloud_badges), + summary = stringResource(R.string.preference_cloud_badges_summary), + value = cloudFiles == true, + onValueChanged = { + viewModel.setCloudFiles(it) + } + ) + val suspendedApps by viewModel.suspendedApps.observeAsState() + SwitchPreference( + title = stringResource(R.string.preference_suspended_badges), + summary = stringResource(R.string.preference_suspended_badges_summary), + value = suspendedApps == true, + onValueChanged = { + viewModel.setSuspendedApps(it) + } + ) + val shortcuts by viewModel.shortcuts.observeAsState() + SwitchPreference( + title = stringResource(R.string.preference_shortcut_badges), + summary = stringResource(R.string.preference_shortcut_badges_summary), + value = shortcuts == true, + onValueChanged = { + viewModel.setShortcuts(it) + } + ) + } } } } \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/badges/BadgeSettingsScreenVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/badges/BadgeSettingsScreenVM.kt index dbf54b8d..d3cb1db4 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/settings/badges/BadgeSettingsScreenVM.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/badges/BadgeSettingsScreenVM.kt @@ -1,8 +1,11 @@ package de.mm20.launcher2.ui.settings.badges +import androidx.appcompat.app.AppCompatActivity 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 kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @@ -12,6 +15,9 @@ import org.koin.core.component.inject class BadgeSettingsScreenVM : ViewModel(), KoinComponent { private val dataStore: LauncherDataStore by inject() + private val permissionsManager: PermissionsManager by inject() + + val hasNotificationsPermission = permissionsManager.hasPermission(PermissionGroup.Notifications).asLiveData() val notifications = dataStore.data.map { it.badges.notifications }.asLiveData() fun setNotifications(notifications: Boolean) { @@ -27,6 +33,10 @@ class BadgeSettingsScreenVM : ViewModel(), KoinComponent { } } + fun requestNotificationsPermission(context: AppCompatActivity) { + permissionsManager.requestPermission(context, PermissionGroup.Notifications) + } + val cloudFiles = dataStore.data.map { it.badges.cloudFiles }.asLiveData() fun setCloudFiles(cloudFiles: Boolean) { viewModelScope.launch {