diff --git a/core/ui/src/main/java/org/signal/core/ui/compose/theme/SignalTheme.kt b/core/ui/src/main/java/org/signal/core/ui/compose/theme/SignalTheme.kt index fac68475a5..97d2b84368 100644 --- a/core/ui/src/main/java/org/signal/core/ui/compose/theme/SignalTheme.kt +++ b/core/ui/src/main/java/org/signal/core/ui/compose/theme/SignalTheme.kt @@ -86,6 +86,7 @@ private val lightColorScheme = lightColorScheme( secondary = Color(0xFF586071), secondaryContainer = Color(0xFFDCE5F9), surface = Color(0xFFFBFCFF), + surfaceContainerLow = Color(0xFFF2F5F9), surfaceVariant = Color(0xFFE7EBF3), background = Color(0xFFFBFCFF), error = Color(0xFFBA1B1B), @@ -156,6 +157,7 @@ private val darkColorScheme = darkColorScheme( secondary = Color(0xFFC1C6DD), secondaryContainer = Color(0xFF414659), surface = Color(0xFF1B1C1F), + surfaceContainerLow = Color(0xFF23242A), surfaceVariant = Color(0xFF303133), background = Color(0xFF1B1C1F), error = Color(0xFFFFB4A9), diff --git a/feature/registration/src/main/java/org/signal/registration/NetworkController.kt b/feature/registration/src/main/java/org/signal/registration/NetworkController.kt index 8c3db71f19..987696f569 100644 --- a/feature/registration/src/main/java/org/signal/registration/NetworkController.kt +++ b/feature/registration/src/main/java/org/signal/registration/NetworkController.kt @@ -179,21 +179,6 @@ interface NetworkController { */ suspend fun setAccountAttributes(attributes: AccountAttributes): RegistrationNetworkResult - // TODO -// /** -// * Validates the provided SVR2 auth credentials, returning information on their usability. -// * -// * `POST /v2/svr/auth/check` -// */ -// suspend fun validateSvr2AuthCredential(e164: String, usernamePasswords: List) -// -// /** -// * Validates the provided SVR3 auth credentials, returning information on their usability. -// * -// * `POST /v3/backup/auth/check` -// */ -// suspend fun validateSvr3AuthCredential(e164: String, usernamePasswords: List) -// // /** // * Set [RestoreMethod] enum on the server for use by the old device to update UX. // */ diff --git a/feature/registration/src/main/java/org/signal/registration/RegistrationNavigation.kt b/feature/registration/src/main/java/org/signal/registration/RegistrationNavigation.kt index 204586c654..3be4b22b01 100644 --- a/feature/registration/src/main/java/org/signal/registration/RegistrationNavigation.kt +++ b/feature/registration/src/main/java/org/signal/registration/RegistrationNavigation.kt @@ -67,7 +67,7 @@ sealed interface RegistrationRoute : NavKey, Parcelable { data object Welcome : RegistrationRoute @Serializable - data class Permissions(val forRestore: Boolean = false) : RegistrationRoute + data class Permissions(val nextRoute: RegistrationRoute) : RegistrationRoute @Serializable data object PhoneNumberEntry : RegistrationRoute @@ -100,10 +100,13 @@ sealed interface RegistrationRoute : NavKey, Parcelable { data object PinCreate : RegistrationRoute @Serializable - data object Restore : RegistrationRoute + data object ChooseRestoreOptionBeforeRegistration : RegistrationRoute @Serializable - data object RestoreViaQr : RegistrationRoute + data object ChooseRestoreOptionAfterRegistration : RegistrationRoute + + @Serializable + data object QuickRestoreQrScan : RegistrationRoute @Serializable data object Transfer : RegistrationRoute @@ -203,9 +206,9 @@ private fun EntryProviderScope.navigationEntries( WelcomeScreen( onEvent = { event -> when (event) { - WelcomeScreenEvents.Continue -> parentEventEmitter.navigateTo(RegistrationRoute.Permissions(forRestore = false)) - WelcomeScreenEvents.DoesNotHaveOldPhone -> parentEventEmitter.navigateTo(RegistrationRoute.Restore) - WelcomeScreenEvents.HasOldPhone -> parentEventEmitter.navigateTo(RegistrationRoute.Permissions(forRestore = true)) + WelcomeScreenEvents.Continue -> parentEventEmitter.navigateTo(RegistrationRoute.Permissions(nextRoute = RegistrationRoute.PhoneNumberEntry)) + WelcomeScreenEvents.HasOldPhone -> parentEventEmitter.navigateTo(RegistrationRoute.Permissions(nextRoute = RegistrationRoute.QuickRestoreQrScan)) + WelcomeScreenEvents.DoesNotHaveOldPhone -> parentEventEmitter.navigateTo(RegistrationRoute.Permissions(nextRoute = RegistrationRoute.ChooseRestoreOptionBeforeRegistration)) } } ) @@ -216,11 +219,7 @@ private fun EntryProviderScope.navigationEntries( PermissionsScreen( permissionsState = permissionsState, onProceed = { - if (key.forRestore) { - parentEventEmitter.navigateTo(RegistrationRoute.RestoreViaQr) - } else { - parentEventEmitter.navigateTo(RegistrationRoute.PhoneNumberEntry) - } + parentEventEmitter.navigateTo(key.nextRoute) } ) } @@ -399,11 +398,11 @@ private fun EntryProviderScope.navigationEntries( ) } - entry { + entry { // TODO: Implement RestoreScreen } - entry { + entry { RestoreViaQrScreen( state = RestoreViaQrState(), onEvent = { event -> diff --git a/feature/registration/src/main/java/org/signal/registration/screens/welcome/WelcomeScreen.kt b/feature/registration/src/main/java/org/signal/registration/screens/welcome/WelcomeScreen.kt index 3b835ea2a5..0598ec5116 100644 --- a/feature/registration/src/main/java/org/signal/registration/screens/welcome/WelcomeScreen.kt +++ b/feature/registration/src/main/java/org/signal/registration/screens/welcome/WelcomeScreen.kt @@ -8,14 +8,20 @@ package org.signal.registration.screens.welcome import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SheetState import androidx.compose.material3.Text @@ -29,6 +35,8 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource @@ -40,7 +48,9 @@ import org.signal.core.ui.compose.BottomSheets import org.signal.core.ui.compose.Buttons import org.signal.core.ui.compose.DayNightPreviews import org.signal.core.ui.compose.Previews +import org.signal.core.ui.compose.SignalIcons import org.signal.core.ui.compose.dismissWithAnimation +import org.signal.core.ui.compose.horizontalGutters import org.signal.core.ui.compose.theme.SignalTheme import org.signal.registration.R import org.signal.registration.test.TestTags @@ -169,40 +179,79 @@ private fun RestoreOrTransferBottomSheetContent( onEvent: (WelcomeScreenEvents) -> Unit ) { Column( + horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .fillMaxWidth() - .padding(horizontal = 24.dp, vertical = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally + .padding(bottom = 54.dp) ) { - Buttons.LargeTonal( - onClick = { + Spacer(modifier = Modifier.size(26.dp)) + + RestoreActionRow( + icon = SignalIcons.QrCode.painter, + title = stringResource(R.string.WelcomeFragment_restore_action_i_have_my_old_phone), + subtitle = stringResource(R.string.WelcomeFragment_restore_action_scan_qr), + modifier = Modifier.testTag(TestTags.WELCOME_RESTORE_HAS_OLD_PHONE_BUTTON), + onRowClick = { sheetState.dismissWithAnimation(scope) { onEvent(WelcomeScreenEvents.HasOldPhone) } - }, - modifier = Modifier - .fillMaxWidth() - .testTag(TestTags.WELCOME_RESTORE_HAS_OLD_PHONE_BUTTON) - ) { - Text("I have my old phone") - } + } + ) - Spacer(modifier = Modifier.height(12.dp)) - - Buttons.LargeTonal( - onClick = { + RestoreActionRow( + icon = painterResource(R.drawable.symbol_no_phone_44), + title = stringResource(R.string.WelcomeFragment_restore_action_i_dont_have_my_old_phone), + subtitle = stringResource(R.string.WelcomeFragment_restore_action_reinstalling), + modifier = Modifier.testTag(TestTags.WELCOME_RESTORE_NO_OLD_PHONE_BUTTON), + onRowClick = { sheetState.dismissWithAnimation(scope) { onEvent(WelcomeScreenEvents.DoesNotHaveOldPhone) } - }, - modifier = Modifier - .fillMaxWidth() - .testTag(TestTags.WELCOME_RESTORE_NO_OLD_PHONE_BUTTON) - ) { - Text("I don't have my old phone") - } + } + ) + } +} - Spacer(modifier = Modifier.height(16.dp)) +@Composable +private fun RestoreActionRow( + icon: Painter, + title: String, + subtitle: String, + modifier: Modifier = Modifier, + onRowClick: () -> Unit = {} +) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = modifier + .horizontalGutters() + .padding(vertical = 8.dp) + .fillMaxWidth() + .clip(RoundedCornerShape(18.dp)) + .background(MaterialTheme.colorScheme.background) + .clickable(enabled = true, onClick = onRowClick) + .padding(horizontal = 24.dp, vertical = 16.dp) + ) { + Icon( + painter = icon, + tint = MaterialTheme.colorScheme.primary, + contentDescription = null, + modifier = Modifier.size(44.dp) + ) + + Column( + modifier = Modifier.padding(start = 16.dp) + ) { + Text( + text = title, + style = MaterialTheme.typography.bodyLarge + ) + + Text( + text = subtitle, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } } } @@ -217,7 +266,7 @@ private fun WelcomeScreenPreview() { @DayNightPreviews @Composable private fun RestoreOrTransferBottomSheetPreview() { - Previews.BottomSheetPreview(forceRtl = true) { + Previews.BottomSheetPreview { RestoreOrTransferBottomSheetContent( sheetState = rememberModalBottomSheetState(), scope = rememberCoroutineScope(), diff --git a/feature/registration/src/main/res/drawable/symbol_no_phone_44.xml b/feature/registration/src/main/res/drawable/symbol_no_phone_44.xml new file mode 100644 index 0000000000..92f3477421 --- /dev/null +++ b/feature/registration/src/main/res/drawable/symbol_no_phone_44.xml @@ -0,0 +1,11 @@ + + + diff --git a/feature/registration/src/main/res/values/strings.xml b/feature/registration/src/main/res/values/strings.xml index 982a83df9c..4bc371c119 100644 --- a/feature/registration/src/main/res/values/strings.xml +++ b/feature/registration/src/main/res/values/strings.xml @@ -84,4 +84,14 @@ Registration failed. Please try again. Having trouble? + + + + I have my old phone + + Scan a QR code from your current Signal account to get started quickly + + I don\'t have my old phone + + Or you\'re reinstalling Signal on the same device