BackgroundSyncDialog.kt

4.5 KB · raw

1package com.peachpasswords.ui.pairing23import android.Manifest4import android.content.Intent5import android.os.Build6import android.provider.Settings7import androidx.activity.compose.rememberLauncherForActivityResult8import androidx.activity.result.contract.ActivityResultContracts9import androidx.activity.compose.BackHandler10import androidx.compose.material3.AlertDialog11import androidx.compose.material3.Text12import androidx.compose.material3.TextButton13import androidx.compose.runtime.Composable14import androidx.compose.runtime.getValue15import androidx.compose.runtime.mutableStateOf16import androidx.compose.runtime.remember17import androidx.compose.runtime.setValue18import androidx.compose.ui.platform.LocalContext19import androidx.compose.ui.text.font.FontWeight20import com.peachpasswords.sync.canShowBackgroundSyncNotification21import com.peachpasswords.ui.theme.LocalPeachAccent22import com.peachpasswords.ui.theme.peachColors23import com.peachpasswords.ui.theme.PeachType2425enum class BackgroundSyncAction { ALLOW, MANUAL_ONLY, DISMISS }2627internal fun shouldPromptForBackgroundSync(pairingSucceeded: Boolean): Boolean = pairingSucceeded2829internal fun backgroundSyncChoice(30    action: BackgroundSyncAction,31    notificationsAvailable: Boolean,32): Boolean = action != BackgroundSyncAction.MANUAL_ONLY && notificationsAvailable3334@Composable35fun BackgroundSyncDialog(36    onChoice: (Boolean) -> Unit,37) {38    val context = LocalContext.current39    var permissionDenied by remember { mutableStateOf(false) }40    val permissionLauncher = rememberLauncherForActivityResult(41        ActivityResultContracts.RequestPermission(),42    ) { granted ->43        if (granted && canShowBackgroundSyncNotification(context)) {44            onChoice(true)45        } else {46            permissionDenied = true47        }48    }49    val settingsLauncher = rememberLauncherForActivityResult(50        ActivityResultContracts.StartActivityForResult(),51    ) {52        if (canShowBackgroundSyncNotification(context)) {53            onChoice(true)54        } else {55            permissionDenied = true56        }57    }58    val dismiss = {59        onChoice(60            backgroundSyncChoice(61                BackgroundSyncAction.DISMISS,62                canShowBackgroundSyncNotification(context),63            ),64        )65    }66    val allow = {67        when {68            canShowBackgroundSyncNotification(context) -> onChoice(true)69            permissionDenied -> settingsLauncher.launch(70                Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)71                    .putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName),72            )73            Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU ->74                permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)75            else -> permissionDenied = true76        }77    }7879    // Dismissal may retain the recommended default only when Android can show80    // its required ongoing notification. Otherwise it honestly stays off.81    BackHandler(onBack = dismiss)82    AlertDialog(83        onDismissRequest = dismiss,84        title = {85            Text("Sync in the background?", fontFamily = PeachType.Display)86        },87        text = {88            Text(89                if (permissionDenied) {90                    "Android notifications are off, so background sync stayed off. " +91                        "Open Peach's notification settings and allow notifications to keep this phone reachable."92                } else {93                    "Allow Peach to keep your devices in step in the background, even when the app isn't open. " +94                        "Android will ask to show the small ongoing notification this requires."95                },96                fontFamily = PeachType.Body,97                color = if (permissionDenied) peachColors.Breach else peachColors.T1,98            )99        },100        confirmButton = {101            TextButton(onClick = allow) {102                Text(103                    if (permissionDenied) "Open Android settings" else "Allow background sync",104                    color = LocalPeachAccent.current,105                    fontWeight = FontWeight.Bold,106                )107            }108        },109        dismissButton = {110            TextButton(onClick = {111                onChoice(112                    backgroundSyncChoice(113                        BackgroundSyncAction.MANUAL_ONLY,114                        canShowBackgroundSyncNotification(context),115                    ),116                )117            }) {118                Text("Sync manually only")119            }120        },121    )122}