Rewrite PermissionsIntroPage to M3 (#758)

* Migrated to M3

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Replaced preview theme

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Fixed theme

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Forced all sets to be private

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Moved Composables and Model to individual files

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Fixed naming

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Theme / M3 changes

* Observe lifecycle from within Screen

* Minor changes

---------

Signed-off-by: Arnau Mora <arnyminerz@proton.me>
Co-authored-by: Ricki Hirner <hirner@bitfire.at>
This commit is contained in:
Arnau Mora 2024-05-04 13:46:32 +02:00 committed by GitHub
parent e6eb90861e
commit 4cffbe7b40
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 329 additions and 273 deletions

View file

@ -4,273 +4,22 @@
package at.bitfire.davdroid.ui
import android.Manifest
import android.app.Application
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.widget.Toast
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.annotation.MainThread
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedButton
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import at.bitfire.davdroid.BuildConfig
import at.bitfire.davdroid.R
import at.bitfire.davdroid.log.Logger
import at.bitfire.davdroid.ui.composable.BasicTopAppBar
import at.bitfire.davdroid.ui.composable.CardWithImage
import at.bitfire.davdroid.ui.composable.PermissionSwitchRow
import at.bitfire.davdroid.util.PermissionUtils
import at.bitfire.davdroid.util.packageChangedFlow
import at.bitfire.ical4android.TaskProvider
import kotlinx.coroutines.launch
import java.util.logging.Level
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class PermissionsActivity: AppCompatActivity() {
val model by viewModels<Model>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
M2Theme {
Scaffold(
topBar = {
BasicTopAppBar(
titleStringRes = R.string.app_settings_security_app_permissions
)
}
) { paddingValues ->
PermissionsContent(modifier = Modifier.padding(paddingValues), model)
}
}
PermissionsScreen(
onNavigateUp = ::onSupportNavigateUp
)
}
}
override fun onResume() {
super.onResume()
model.checkPermissions()
}
class Model(app: Application): AndroidViewModel(app) {
var needKeepPermissions by mutableStateOf(false)
var openTasksAvailable by mutableStateOf(false)
var tasksOrgAvailable by mutableStateOf(false)
var jtxAvailable by mutableStateOf(false)
init {
viewModelScope.launch {
packageChangedFlow(app).collect {
checkPermissions()
}
}
}
@MainThread
fun checkPermissions() {
val pm = getApplication<Application>().packageManager
// auto-reset permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
needKeepPermissions = pm.isAutoRevokeWhitelisted
}
openTasksAvailable = pm.resolveContentProvider(TaskProvider.ProviderName.OpenTasks.authority, 0) != null
tasksOrgAvailable = pm.resolveContentProvider(TaskProvider.ProviderName.TasksOrg.authority, 0) != null
jtxAvailable = pm.resolveContentProvider(TaskProvider.ProviderName.JtxBoard.authority, 0) != null
}
}
}
@Composable
fun PermissionsContent(
modifier: Modifier = Modifier,
model: PermissionsActivity.Model
) {
val context = LocalContext.current
PermissionsCardContent(
keepPermissions = model.needKeepPermissions,
onKeepPermissionsRequested = {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val intent = Intent(
Intent.ACTION_AUTO_REVOKE_PERMISSIONS,
Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)
)
try {
context.startActivity(intent)
Toast.makeText(context, R.string.permissions_autoreset_instruction, Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Logger.log.log(Level.WARNING, "Couldn't start Keep Permissions activity", e)
}
}
},
openTasksAvailable = model.openTasksAvailable,
tasksOrgAvailable = model.tasksOrgAvailable,
jtxAvailable = model.jtxAvailable,
modifier = modifier
)
}
@Preview(showBackground = true, showSystemUi = true)
@Composable
fun PermissionsCard_Preview() {
M2Theme {
PermissionsCardContent(
keepPermissions = true,
onKeepPermissionsRequested = {},
openTasksAvailable = true,
tasksOrgAvailable = true,
jtxAvailable = true
)
}
}
@Composable
fun PermissionsCardContent(
keepPermissions: Boolean?,
onKeepPermissionsRequested: () -> Unit,
openTasksAvailable: Boolean?,
tasksOrgAvailable: Boolean?,
jtxAvailable: Boolean?,
modifier: Modifier = Modifier
) {
val context = LocalContext.current
Column(
modifier = modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
CardWithImage(
title = stringResource(R.string.permissions_title),
message = stringResource(
R.string.permissions_text,
stringResource(R.string.app_name)
),
image = painterResource(R.drawable.intro_permissions),
modifier = Modifier.padding(8.dp)
) {
if (keepPermissions != null) {
PermissionSwitchRow(
text = stringResource(R.string.permissions_autoreset_title),
summaryWhenGranted = stringResource(R.string.permissions_autoreset_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_autoreset_status_off),
allPermissionsGranted = keepPermissions,
onLaunchRequest = onKeepPermissionsRequested,
modifier = Modifier.padding(vertical = 4.dp)
)
}
val allPermissions = mutableListOf<String>()
allPermissions.addAll(PermissionUtils.CONTACT_PERMISSIONS)
allPermissions.addAll(PermissionUtils.CALENDAR_PERMISSIONS)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
allPermissions += Manifest.permission.POST_NOTIFICATIONS
if (openTasksAvailable == true)
allPermissions.addAll(TaskProvider.PERMISSIONS_OPENTASKS)
if (tasksOrgAvailable == true)
allPermissions.addAll(TaskProvider.PERMISSIONS_TASKS_ORG)
if (jtxAvailable == true)
allPermissions.addAll(TaskProvider.PERMISSIONS_JTX)
PermissionSwitchRow(
text = stringResource(R.string.permissions_all_title),
permissions = allPermissions,
summaryWhenGranted = stringResource(R.string.permissions_all_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_all_status_off),
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(vertical = 4.dp)
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
PermissionSwitchRow(
text = stringResource(R.string.permissions_notification_title),
summaryWhenGranted = stringResource(R.string.permissions_notification_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_notification_status_off),
permissions = listOf(Manifest.permission.POST_NOTIFICATIONS),
modifier = Modifier.padding(vertical = 4.dp)
)
PermissionSwitchRow(
text = stringResource(R.string.permissions_calendar_title),
summaryWhenGranted = stringResource(R.string.permissions_calendar_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_calendar_status_off),
permissions = PermissionUtils.CALENDAR_PERMISSIONS.toList(),
modifier = Modifier.padding(vertical = 4.dp)
)
PermissionSwitchRow(
text = stringResource(R.string.permissions_contacts_title),
summaryWhenGranted = stringResource(R.string.permissions_contacts_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_contacts_status_off),
permissions = PermissionUtils.CONTACT_PERMISSIONS.toList(),
modifier = Modifier.padding(vertical = 4.dp)
)
if (jtxAvailable == true)
PermissionSwitchRow(
text = stringResource(R.string.permissions_jtx_title),
summaryWhenGranted = stringResource(R.string.permissions_tasks_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_tasks_status_off),
permissions = TaskProvider.PERMISSIONS_JTX.toList(),
modifier = Modifier.padding(vertical = 4.dp)
)
if (openTasksAvailable == true)
PermissionSwitchRow(
text = stringResource(R.string.permissions_opentasks_title),
summaryWhenGranted = stringResource(R.string.permissions_tasks_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_tasks_status_off),
permissions = TaskProvider.PERMISSIONS_OPENTASKS.toList(),
modifier = Modifier.padding(vertical = 4.dp)
)
if (tasksOrgAvailable == true)
PermissionSwitchRow(
text = stringResource(R.string.permissions_tasksorg_title),
summaryWhenGranted = stringResource(R.string.permissions_tasks_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_tasks_status_off),
permissions = TaskProvider.PERMISSIONS_TASKS_ORG.toList(),
modifier = Modifier.padding(vertical = 4.dp)
)
Text(
text = stringResource(R.string.permissions_app_settings_hint),
style = MaterialTheme.typography.body1,
modifier = Modifier.padding(top = 24.dp)
)
OutlinedButton(
modifier = Modifier.padding(top = 8.dp),
onClick = { PermissionUtils.showAppSettings(context) }
) {
Text(stringResource(R.string.permissions_app_settings).uppercase())
}
}
}
}

View file

@ -0,0 +1,52 @@
package at.bitfire.davdroid.ui
import android.app.Application
import android.os.Build
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import at.bitfire.davdroid.util.packageChangedFlow
import at.bitfire.ical4android.TaskProvider
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class PermissionsModel @Inject constructor(
val context: Application
): ViewModel() {
var needKeepPermissions by mutableStateOf(false)
private set
var openTasksAvailable by mutableStateOf(false)
private set
var tasksOrgAvailable by mutableStateOf(false)
private set
var jtxAvailable by mutableStateOf(false)
private set
init {
viewModelScope.launch {
// check permissions when a package (e.g. tasks app) is (un)installed
packageChangedFlow(context).collect {
checkPermissions()
}
}
}
fun checkPermissions() {
val pm = context.packageManager
// auto-reset permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
needKeepPermissions = pm.isAutoRevokeWhitelisted
}
openTasksAvailable = pm.resolveContentProvider(TaskProvider.ProviderName.OpenTasks.authority, 0) != null
tasksOrgAvailable = pm.resolveContentProvider(TaskProvider.ProviderName.TasksOrg.authority, 0) != null
jtxAvailable = pm.resolveContentProvider(TaskProvider.ProviderName.JtxBoard.authority, 0) != null
}
}

View file

@ -0,0 +1,253 @@
package at.bitfire.davdroid.ui
import android.Manifest
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.widget.Toast
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.viewmodel.compose.viewModel
import at.bitfire.davdroid.BuildConfig
import at.bitfire.davdroid.R
import at.bitfire.davdroid.log.Logger
import at.bitfire.davdroid.ui.composable.CardWithImage
import at.bitfire.davdroid.ui.composable.PermissionSwitchRow
import at.bitfire.davdroid.util.PermissionUtils
import at.bitfire.ical4android.TaskProvider
import java.util.logging.Level
/**
* Used when "Manage permissions" is selected in the settings.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PermissionsScreen(
onNavigateUp: () -> Unit
) {
AppTheme {
Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(R.string.app_settings_security_app_permissions)) },
navigationIcon = {
IconButton(
onClick = onNavigateUp
) {
Icon(Icons.AutoMirrored.Default.ArrowBack, stringResource(R.string.navigate_up))
}
}
)
}
) { paddingValues ->
PermissionsScreen(modifier = Modifier.padding(paddingValues))
}
}
}
/**
* Used by [PermissionsScreen] and directly embedded in [at.bitfire.davdroid.ui.intro.PermissionsIntroPage].
*/
@Composable
fun PermissionsScreen(
modifier: Modifier = Modifier,
model: PermissionsModel = viewModel()
) {
// check permissions when the lifecycle owner (for instance Activity) is resumed
val lifecycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifecycle) {
val observer = object: DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
model.checkPermissions()
}
}
lifecycle.addObserver(observer)
onDispose {
lifecycle.removeObserver(observer)
}
}
val context = LocalContext.current
PermissionsScreen(
keepPermissions = model.needKeepPermissions,
onKeepPermissionsRequested = {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val intent = Intent(
Intent.ACTION_AUTO_REVOKE_PERMISSIONS,
Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)
)
try {
context.startActivity(intent)
Toast.makeText(context, R.string.permissions_autoreset_instruction, Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Logger.log.log(Level.WARNING, "Couldn't start Keep Permissions activity", e)
}
}
},
openTasksAvailable = model.openTasksAvailable,
tasksOrgAvailable = model.tasksOrgAvailable,
jtxAvailable = model.jtxAvailable,
modifier = modifier
)
}
@Composable
fun PermissionsScreen(
keepPermissions: Boolean?,
onKeepPermissionsRequested: () -> Unit,
openTasksAvailable: Boolean?,
tasksOrgAvailable: Boolean?,
jtxAvailable: Boolean?,
modifier: Modifier = Modifier
) {
Column(
modifier = modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
CardWithImage(
title = stringResource(R.string.permissions_title),
message = stringResource(
R.string.permissions_text,
stringResource(R.string.app_name)
),
image = painterResource(R.drawable.intro_permissions),
modifier = Modifier.padding(8.dp)
) {
if (keepPermissions != null) {
PermissionSwitchRow(
text = stringResource(R.string.permissions_autoreset_title),
summaryWhenGranted = stringResource(R.string.permissions_autoreset_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_autoreset_status_off),
allPermissionsGranted = keepPermissions,
onLaunchRequest = onKeepPermissionsRequested,
modifier = Modifier.padding(vertical = 4.dp)
)
}
val allPermissions = mutableListOf<String>()
allPermissions.addAll(PermissionUtils.CONTACT_PERMISSIONS)
allPermissions.addAll(PermissionUtils.CALENDAR_PERMISSIONS)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
allPermissions += Manifest.permission.POST_NOTIFICATIONS
if (openTasksAvailable == true)
allPermissions.addAll(TaskProvider.PERMISSIONS_OPENTASKS)
if (tasksOrgAvailable == true)
allPermissions.addAll(TaskProvider.PERMISSIONS_TASKS_ORG)
if (jtxAvailable == true)
allPermissions.addAll(TaskProvider.PERMISSIONS_JTX)
PermissionSwitchRow(
text = stringResource(R.string.permissions_all_title),
permissions = allPermissions,
summaryWhenGranted = stringResource(R.string.permissions_all_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_all_status_off),
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(vertical = 4.dp)
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
PermissionSwitchRow(
text = stringResource(R.string.permissions_notification_title),
summaryWhenGranted = stringResource(R.string.permissions_notification_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_notification_status_off),
permissions = listOf(Manifest.permission.POST_NOTIFICATIONS),
modifier = Modifier.padding(vertical = 4.dp)
)
PermissionSwitchRow(
text = stringResource(R.string.permissions_calendar_title),
summaryWhenGranted = stringResource(R.string.permissions_calendar_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_calendar_status_off),
permissions = PermissionUtils.CALENDAR_PERMISSIONS.toList(),
modifier = Modifier.padding(vertical = 4.dp)
)
PermissionSwitchRow(
text = stringResource(R.string.permissions_contacts_title),
summaryWhenGranted = stringResource(R.string.permissions_contacts_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_contacts_status_off),
permissions = PermissionUtils.CONTACT_PERMISSIONS.toList(),
modifier = Modifier.padding(vertical = 4.dp)
)
if (jtxAvailable == true)
PermissionSwitchRow(
text = stringResource(R.string.permissions_jtx_title),
summaryWhenGranted = stringResource(R.string.permissions_tasks_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_tasks_status_off),
permissions = TaskProvider.PERMISSIONS_JTX.toList(),
modifier = Modifier.padding(vertical = 4.dp)
)
if (openTasksAvailable == true)
PermissionSwitchRow(
text = stringResource(R.string.permissions_opentasks_title),
summaryWhenGranted = stringResource(R.string.permissions_tasks_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_tasks_status_off),
permissions = TaskProvider.PERMISSIONS_OPENTASKS.toList(),
modifier = Modifier.padding(vertical = 4.dp)
)
if (tasksOrgAvailable == true)
PermissionSwitchRow(
text = stringResource(R.string.permissions_tasksorg_title),
summaryWhenGranted = stringResource(R.string.permissions_tasks_status_on),
summaryWhenNotGranted = stringResource(R.string.permissions_tasks_status_off),
permissions = TaskProvider.PERMISSIONS_TASKS_ORG.toList(),
modifier = Modifier.padding(vertical = 4.dp)
)
Text(
text = stringResource(R.string.permissions_app_settings_hint),
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier.padding(top = 24.dp)
)
val context = LocalContext.current
OutlinedButton(
modifier = Modifier.padding(vertical = 8.dp),
onClick = { PermissionUtils.showAppSettings(context) }
) {
Text(stringResource(R.string.permissions_app_settings))
}
}
}
}
@Composable
@Preview
fun PermissionsCard_Preview() {
AppTheme {
PermissionsScreen(
keepPermissions = true,
onKeepPermissionsRequested = {},
openTasksAvailable = true,
tasksOrgAvailable = true,
jtxAvailable = true
)
}
}

View file

@ -17,6 +17,7 @@ import androidx.compose.ui.res.stringResource
import at.bitfire.davdroid.R
@Composable
@Deprecated("Directly use TopAppBar instead.", replaceWith = ReplaceWith("TopAppBar"))
fun BasicTopAppBar(
@StringRes titleStringRes: Int,
onNavigateUp: () -> Unit

View file

@ -12,12 +12,12 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.Card
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.TabletAndroid
import androidx.compose.material3.Card
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -85,13 +85,13 @@ fun CardWithImage(
Text(
text = title,
modifier = Modifier.fillMaxWidth(),
style = MaterialTheme.typography.h6
style = MaterialTheme.typography.titleLarge
)
subtitle?.let {
Text(
text = it,
modifier = Modifier.fillMaxWidth(),
style = MaterialTheme.typography.subtitle1
style = MaterialTheme.typography.titleMedium
)
}
}
@ -102,7 +102,7 @@ fun CardWithImage(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
style = MaterialTheme.typography.body1
style = MaterialTheme.typography.bodyLarge
)
}

View file

@ -7,9 +7,9 @@ package at.bitfire.davdroid.ui.composable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Switch
import androidx.compose.material.Text
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -40,12 +40,12 @@ fun PermissionSwitchRow(
text = text,
modifier = Modifier.fillMaxWidth(),
fontWeight = fontWeight,
style = MaterialTheme.typography.body1
style = MaterialTheme.typography.bodyMedium
)
Text(
text = if (allPermissionsGranted) summaryWhenGranted else summaryWhenNotGranted,
modifier = Modifier.fillMaxWidth(),
style = MaterialTheme.typography.body2
style = MaterialTheme.typography.bodyLarge
)
}
Switch(

View file

@ -7,15 +7,16 @@ package at.bitfire.davdroid.ui.intro
import android.app.Application
import androidx.compose.runtime.Composable
import androidx.lifecycle.viewmodel.compose.viewModel
import at.bitfire.davdroid.ui.PermissionsActivity
import at.bitfire.davdroid.ui.PermissionsContent
import at.bitfire.davdroid.ui.PermissionsScreen
import at.bitfire.davdroid.ui.PermissionsModel
import at.bitfire.davdroid.util.PermissionUtils
import at.bitfire.davdroid.util.PermissionUtils.CALENDAR_PERMISSIONS
import at.bitfire.davdroid.util.PermissionUtils.CONTACT_PERMISSIONS
import at.bitfire.ical4android.TaskProvider
class PermissionsIntroPage: IntroPage {
var model: PermissionsActivity.Model? = null
var model: PermissionsModel? = null
override fun getShowPolicy(application: Application): IntroPage.ShowPolicy {
// show PermissionsFragment as intro fragment when no permissions are granted
@ -31,10 +32,10 @@ class PermissionsIntroPage: IntroPage {
@Composable
override fun ComposePage() {
val newModel: PermissionsActivity.Model = viewModel()
val newModel: PermissionsModel = viewModel()
model = newModel
PermissionsContent(model = newModel)
PermissionsScreen(model = newModel)
}
// Check whether permissions have changed after user comes back from settings app