PairingProRequired.kt

5.1 KB · raw

1package com.peachpasswords.ui.pairing23import android.content.Intent4import android.net.Uri5import androidx.compose.foundation.layout.Column6import androidx.compose.foundation.layout.Row7import androidx.compose.foundation.layout.Spacer8import androidx.compose.foundation.layout.fillMaxWidth9import androidx.compose.foundation.layout.height10import androidx.compose.foundation.layout.padding11import androidx.compose.foundation.shape.RoundedCornerShape12import androidx.compose.material3.HorizontalDivider13import androidx.compose.material3.Surface14import androidx.compose.material3.Text15import androidx.compose.runtime.Composable16import androidx.compose.ui.Modifier17import androidx.compose.ui.platform.LocalContext18import androidx.compose.ui.semantics.heading19import androidx.compose.ui.semantics.semantics20import androidx.compose.ui.text.font.FontStyle21import androidx.compose.ui.unit.dp22import androidx.compose.ui.unit.em23import androidx.compose.ui.unit.sp24import com.peachpasswords.ui.theme.LocalPeachAccent25import com.peachpasswords.ui.theme.PeachSpacing26import com.peachpasswords.ui.theme.PeachType27import com.peachpasswords.ui.theme.peachColors2829internal const val PEACH_PRO_PURCHASE_URL =30    "https://buy.polar.sh/polar_cl_IXSFIPojx67rcOTksn8LkH5mnU3osPHtYqBIl1eyuIz"3132private val pairingProFeatures = listOf(33    "01" to ("Peach Sync" to "Encrypted sync across every paired device"),34    "02" to ("One-time purchase" to "$39 once · yours forever"),35    "03" to ("One shared key" to "Pro transfers during authenticated pairing"),36)3738/**39 * Terminal pairing fallback derived from Settings' Peach Pro card. A tonal40 * Surface provides the MD3 container while Peach typography and spacing keep41 * it visually native to the rest of the app.42 */43@Composable44internal fun PairingProRequired(45    onRetry: () -> Unit,46    onOpenPro: (() -> Unit)? = null,47) {48    val context = LocalContext.current49    val accent = LocalPeachAccent.current5051    Surface(52        modifier = Modifier.fillMaxWidth(),53        shape = RoundedCornerShape(24.dp),54        color = peachColors.SurfaceElevated,55        tonalElevation = 3.dp,56    ) {57        Column(Modifier.padding(PeachSpacing.lg)) {58            Text(59                "PEACH PRO · SYNC",60                color = accent,61                fontFamily = PeachType.Mono,62                fontSize = 9.sp,63                letterSpacing = 0.18.em,64            )65            Spacer(Modifier.height(PeachSpacing.sm))66            Text(67                "Pair freely. Sync with Pro.",68                color = peachColors.T0,69                fontFamily = PeachType.Display,70                fontStyle = FontStyle.Italic,71                fontSize = 28.sp,72                modifier = Modifier.semantics { heading() },73            )74            Spacer(Modifier.height(PeachSpacing.sm))75            Text(76                "Pairing can start from any device, but at least one of these two " +77                    "devices needs a valid Peach Pro license before pairing can finish. " +78                    "No vault or device record was added.",79                color = peachColors.T1,80                fontFamily = PeachType.Body,81                fontSize = 13.sp,82                lineHeight = 19.sp,83            )84            Spacer(Modifier.height(PeachSpacing.md))8586            pairingProFeatures.forEach { (number, feature) ->87                HorizontalDivider(color = peachColors.T3.copy(alpha = 0.55f))88                Row(89                    Modifier90                        .fillMaxWidth()91                        .padding(vertical = PeachSpacing.sm),92                ) {93                    Text(94                        number,95                        color = accent,96                        fontFamily = PeachType.Mono,97                        fontSize = 10.sp,98                        modifier = Modifier.padding(end = PeachSpacing.md),99                    )100                    Column {101                        Text(102                            feature.first,103                            color = peachColors.T0,104                            fontFamily = PeachType.Body,105                            fontSize = 14.sp,106                        )107                        Text(108                            feature.second,109                            color = peachColors.T2,110                            fontFamily = PeachType.Body,111                            fontSize = 11.sp,112                        )113                    }114                }115            }116117            Spacer(Modifier.height(PeachSpacing.md))118            PillButton(119                if (onOpenPro == null) "Get Peach Pro" else "Open Peach Pro",120                accent,121                filled = true,122            ) {123                if (onOpenPro != null) {124                    onOpenPro()125                } else {126                    runCatching {127                        context.startActivity(128                            Intent(Intent.ACTION_VIEW, Uri.parse(PEACH_PRO_PURCHASE_URL)),129                        )130                    }131                }132            }133            Spacer(Modifier.height(PeachSpacing.xs))134            PillButton("Try another device", peachColors.T2, filled = false, onClick = onRetry)135        }136    }137}