diff --git a/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java b/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java index c890637ce7..472b7e159f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java +++ b/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java @@ -34,6 +34,7 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.TurnOnNotificationsBottomSheet; import org.thoughtcrime.securesms.profiles.AvatarHelper; import org.thoughtcrime.securesms.profiles.manage.EditProfileActivity; +import org.thoughtcrime.securesms.profiles.username.NewWaysToConnectDialogFragment; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.ServiceUtil; @@ -340,13 +341,13 @@ public final class Megaphones { public static @NonNull Megaphone buildSetUpYourUsernameMegaphone(@NonNull Context context) { return new Megaphone.Builder(Event.SET_UP_YOUR_USERNAME, Megaphone.Style.BASIC) - .setTitle(R.string.SetUpYourUsername__set_up_your_signal_username) - .setBody(R.string.SetUpYourUsername__usernames_let_others) - .setImage(R.drawable.usernames_64) - .setActionButton(R.string.SetUpYourUsername__continue, (megaphone, controller) -> { - controller.onMegaphoneNavigationRequested(EditProfileActivity.getIntentForUsernameEdit(context)); + .setTitle(R.string.NewWaysToConnectDialogFragment__new_ways_to_connect) + .setBody(R.string.SetUpYourUsername__introducing_phone_number_privacy) + .setImage(R.drawable.usernames_megaphone) + .setActionButton(R.string.SetUpYourUsername__learn_more, (megaphone, controller) -> { + controller.onMegaphoneDialogFragmentRequested(new NewWaysToConnectDialogFragment()); }) - .setSecondaryButton(R.string.SetUpYourUsername__not_now, (megaphone, controller) -> { + .setSecondaryButton(R.string.SetUpYourUsername__dismiss, (megaphone, controller) -> { controller.onMegaphoneCompleted(Event.SET_UP_YOUR_USERNAME); }) .build(); @@ -360,7 +361,7 @@ public final class Megaphones { .setActionButton(R.string.GrantFullScreenIntentPermission_megaphone_turn_on, (megaphone, controller) -> { controller.onMegaphoneDialogFragmentRequested(TurnOnNotificationsBottomSheet.turnOnFullScreenIntentFragment(context)); }) - .setSecondaryButton(R.string.SetUpYourUsername__not_now, (megaphone, controller) -> { + .setSecondaryButton(R.string.GrantFullScreenIntentPermission_megaphone_not_now, (megaphone, controller) -> { controller.onMegaphoneCompleted(Event.GRANT_FULL_SCREEN_INTENT); }) .build(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/username/NewWaysToConnectDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/profiles/username/NewWaysToConnectDialogFragment.kt new file mode 100644 index 0000000000..ee5ed6c157 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/username/NewWaysToConnectDialogFragment.kt @@ -0,0 +1,200 @@ +/* + * Copyright 2024 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.profiles.username + +import android.os.Bundle +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import org.signal.core.ui.Buttons +import org.signal.core.ui.Previews +import org.signal.core.ui.Scaffolds +import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.compose.ComposeDialogFragment +import org.thoughtcrime.securesms.profiles.manage.EditProfileActivity + +/** + * Displays an explanation page about usernames and gives the user + * the opportunity to set one up now. + */ +class NewWaysToConnectDialogFragment : ComposeDialogFragment() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setStyle(STYLE_NO_FRAME, R.style.Signal_DayNight_Dialog_FullScreen) + } + + @Composable + override fun DialogContent() { + NewWaysToConnectDialogContent( + onSetUpUsernameClick = { + startActivity(EditProfileActivity.getIntentForUsernameEdit(requireContext())) + dismissAllowingStateLoss() + }, + onNotNowClick = { dismissAllowingStateLoss() } + ) + } +} + +@Preview +@Composable +private fun PreviewNewWaysToConnectDialogContent() { + Previews.Preview { + NewWaysToConnectDialogContent( + onSetUpUsernameClick = {}, + onNotNowClick = {} + ) + } +} + +@Composable +private fun NewWaysToConnectDialogContent( + onSetUpUsernameClick: () -> Unit, + onNotNowClick: () -> Unit +) { + Scaffolds.Settings( + title = "", + onNavigationClick = onNotNowClick, + navigationIconPainter = painterResource(id = R.drawable.symbol_x_24) + ) { + Column(modifier = Modifier.padding(it)) { + Text( + text = stringResource(id = R.string.NewWaysToConnectDialogFragment__new_ways_to_connect), + style = MaterialTheme.typography.headlineMedium, + textAlign = TextAlign.Center, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = dimensionResource(id = R.dimen.core_ui__gutter)) + .padding(top = 16.dp, bottom = 36.dp) + ) + + LazyColumn(modifier = Modifier.weight(1f)) { + item { + NewWaysToConnectRowItem( + title = stringResource(id = R.string.NewWaysToConnectDialogFragment__phone_number_privacy), + description = stringResource(id = R.string.NewWaysToConnectDialogFragment__your_phone_number_is_no_longer_shared), + image = painterResource(id = R.drawable.phone_48_color) + ) + } + + item { + NewWaysToConnectRowItem( + title = stringResource(id = R.string.NewWaysToConnectDialogFragment__usernames), + description = stringResource(id = R.string.NewWaysToConnectDialogFragment__people_can_now_message_you_using_your_optional_username), + image = painterResource(id = R.drawable.usernames_48_color) + ) + } + + item { + NewWaysToConnectRowItem( + title = stringResource(id = R.string.NewWaysToConnectDialogFragment__qr_codes_and_links), + description = stringResource(id = R.string.NewWaysToConnectDialogFragment__usernames_have_a_unique_qr_code), + image = painterResource(id = R.drawable.qr_codes_48_color) + ) + } + } + + Buttons.LargeTonal( + onClick = onSetUpUsernameClick, + modifier = Modifier + .padding(horizontal = dimensionResource(id = R.dimen.core_ui__gutter)) + .padding(top = 36.dp) + .defaultMinSize(minWidth = 221.dp) + .align(alignment = Alignment.CenterHorizontally) + ) { + Text( + text = stringResource(id = R.string.NewWaysToConnectDialogFragment__set_up_your_username) + ) + } + + TextButton( + onClick = onNotNowClick, + modifier = Modifier + .padding( + horizontal = dimensionResource(id = R.dimen.core_ui__gutter), + vertical = 36.dp + ) + .defaultMinSize(minWidth = 221.dp) + .align(alignment = Alignment.CenterHorizontally) + ) { + Text(text = stringResource(id = R.string.NewWaysToConnectDialogFragment__not_now)) + } + } + } +} + +@Preview +@Composable +private fun PreviewNewWaysToConnectRowItem() { + Previews.Preview { + NewWaysToConnectRowItem( + title = "Example Item", + description = "Sample text for the subtitle of the example", + image = painterResource(id = R.drawable.symbol_album_tilt_24) + ) + } +} + +@Composable +private fun NewWaysToConnectRowItem( + title: String, + description: String, + image: Painter, + modifier: Modifier = Modifier +) { + Row( + modifier = modifier + .padding( + horizontal = dimensionResource(id = R.dimen.core_ui__gutter) + ) + .padding( + bottom = 40.dp + ) + ) { + Image( + painter = image, + contentDescription = null, + modifier = Modifier + .padding( + start = 12.dp, + top = 4.dp, + end = 24.dp + ) + .size(48.dp) + ) + Column { + Text( + text = title, + style = MaterialTheme.typography.titleMedium + ) + Text( + text = description, + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(top = 2.dp, end = 8.dp) + ) + } + } +} diff --git a/app/src/main/res/drawable-night/phone_48_color.xml b/app/src/main/res/drawable-night/phone_48_color.xml new file mode 100644 index 0000000000..df1c074f83 --- /dev/null +++ b/app/src/main/res/drawable-night/phone_48_color.xml @@ -0,0 +1,36 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable-night/qr_codes_48_color.xml b/app/src/main/res/drawable-night/qr_codes_48_color.xml new file mode 100644 index 0000000000..0a655fd194 --- /dev/null +++ b/app/src/main/res/drawable-night/qr_codes_48_color.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable-night/usernames_48_color.xml b/app/src/main/res/drawable-night/usernames_48_color.xml new file mode 100644 index 0000000000..70175a9921 --- /dev/null +++ b/app/src/main/res/drawable-night/usernames_48_color.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/app/src/main/res/drawable/phone_48_color.xml b/app/src/main/res/drawable/phone_48_color.xml new file mode 100644 index 0000000000..68b0f26d48 --- /dev/null +++ b/app/src/main/res/drawable/phone_48_color.xml @@ -0,0 +1,25 @@ + + + + + + + diff --git a/app/src/main/res/drawable/qr_codes_48_color.xml b/app/src/main/res/drawable/qr_codes_48_color.xml new file mode 100644 index 0000000000..95b4c5e308 --- /dev/null +++ b/app/src/main/res/drawable/qr_codes_48_color.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/usernames_48_color.xml b/app/src/main/res/drawable/usernames_48_color.xml new file mode 100644 index 0000000000..95e8d5bf2f --- /dev/null +++ b/app/src/main/res/drawable/usernames_48_color.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/app/src/main/res/drawable/usernames_64.xml b/app/src/main/res/drawable/usernames_64.xml deleted file mode 100644 index 9248c4a4a5..0000000000 --- a/app/src/main/res/drawable/usernames_64.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/usernames_megaphone.xml b/app/src/main/res/drawable/usernames_megaphone.xml new file mode 100644 index 0000000000..0346c9df92 --- /dev/null +++ b/app/src/main/res/drawable/usernames_megaphone.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e0cb89dba9..613d083f1c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2427,6 +2427,26 @@ %1$s • Story + + + New ways to connect + + Phone number privacy + + Your phone number is no longer shared with chats. If your number is saved to a friend\'s contacts, they will still see it. + + Usernames + + People can now message you using your optional username so you don\'t have to give out your phone number. Usernames aren\'t visible on your profile. + + QR codes and links + + Usernames have a unique QR code and link you can share with friends to quickly start a chat with you. + + Not now + + Set up your username + Play video Has a caption @@ -6213,11 +6233,11 @@ Set up your Signal username - Usernames let others message you without needing your phone number + Introducing phone number privacy, optional usernames and links. - Not now + Dismiss - Continue + Learn more @@ -6562,6 +6582,8 @@ Never miss a call from your contacts and groups. Turn on + + Not now Turn on full screen notifications diff --git a/core-ui/src/main/java/org/signal/core/ui/Previews.kt b/core-ui/src/main/java/org/signal/core/ui/Previews.kt new file mode 100644 index 0000000000..7394b3528c --- /dev/null +++ b/core-ui/src/main/java/org/signal/core/ui/Previews.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.signal.core.ui + +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import org.signal.core.ui.theme.SignalTheme + +object Previews { + @Composable + fun Preview( + content: @Composable () -> Unit + ) { + SignalTheme { + Surface { + content() + } + } + } +}