package com.peachpasswords.ui.pairing import android.Manifest import android.content.Intent import android.os.Build import android.provider.Settings import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.compose.BackHandler import androidx.compose.material3.AlertDialog import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import com.peachpasswords.sync.canShowBackgroundSyncNotification import com.peachpasswords.ui.theme.LocalPeachAccent import com.peachpasswords.ui.theme.peachColors import com.peachpasswords.ui.theme.PeachType enum class BackgroundSyncAction { ALLOW, MANUAL_ONLY, DISMISS } internal fun shouldPromptForBackgroundSync(pairingSucceeded: Boolean): Boolean = pairingSucceeded internal fun backgroundSyncChoice( action: BackgroundSyncAction, notificationsAvailable: Boolean, ): Boolean = action != BackgroundSyncAction.MANUAL_ONLY && notificationsAvailable @Composable fun BackgroundSyncDialog( onChoice: (Boolean) -> Unit, ) { val context = LocalContext.current var permissionDenied by remember { mutableStateOf(false) } val permissionLauncher = rememberLauncherForActivityResult( ActivityResultContracts.RequestPermission(), ) { granted -> if (granted && canShowBackgroundSyncNotification(context)) { onChoice(true) } else { permissionDenied = true } } val settingsLauncher = rememberLauncherForActivityResult( ActivityResultContracts.StartActivityForResult(), ) { if (canShowBackgroundSyncNotification(context)) { onChoice(true) } else { permissionDenied = true } } val dismiss = { onChoice( backgroundSyncChoice( BackgroundSyncAction.DISMISS, canShowBackgroundSyncNotification(context), ), ) } val allow = { when { canShowBackgroundSyncNotification(context) -> onChoice(true) permissionDenied -> settingsLauncher.launch( Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS) .putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName), ) Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) else -> permissionDenied = true } } // Dismissal may retain the recommended default only when Android can show // its required ongoing notification. Otherwise it honestly stays off. BackHandler(onBack = dismiss) AlertDialog( onDismissRequest = dismiss, title = { Text("Sync in the background?", fontFamily = PeachType.Display) }, text = { Text( if (permissionDenied) { "Android notifications are off, so background sync stayed off. " + "Open Peach's notification settings and allow notifications to keep this phone reachable." } else { "Allow Peach to keep your devices in step in the background, even when the app isn't open. " + "Android will ask to show the small ongoing notification this requires." }, fontFamily = PeachType.Body, color = if (permissionDenied) peachColors.Breach else peachColors.T1, ) }, confirmButton = { TextButton(onClick = allow) { Text( if (permissionDenied) "Open Android settings" else "Allow background sync", color = LocalPeachAccent.current, fontWeight = FontWeight.Bold, ) } }, dismissButton = { TextButton(onClick = { onChoice( backgroundSyncChoice( BackgroundSyncAction.MANUAL_ONLY, canShowBackgroundSyncNotification(context), ), ) }) { Text("Sync manually only") } }, ) }