Add a QR code link and tooltip in the profile settings.

This commit is contained in:
Greyson Parrelli
2023-11-03 10:47:35 -04:00
parent 528ccc1e9d
commit 29350ab7b0
15 changed files with 346 additions and 159 deletions

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="12dp"
android:viewportWidth="20"
android:viewportHeight="12">
<path
android:pathData="M10,-0L1,9L19,9L10,-0Z"
android:fillColor="#000000"/>
</vector>

View File

@@ -17,6 +17,6 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/manage_profile" />
app:navGraph="@navigation/edit_profile" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -12,7 +12,8 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:animateLayoutChanges="true">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
@@ -170,7 +171,40 @@
app:layout_goneMarginEnd="48dp"
tools:text="\@spiderman" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/username_link_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:minHeight="72dp"
android:paddingStart="@dimen/dsl_settings_gutter"
android:paddingEnd="@dimen/safety_number_recipient_row_item_gutter"
app:layout_constraintTop_toBottomOf="@id/manage_profile_username_container">
<ImageView
android:id="@+id/username_link_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/symbol_qrcode_24"
app:tint="@color/signal_text_primary" />
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/username_link_text"
style="@style/Signal.Text.Body"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:textAlignment="viewStart"
android:text="@string/ManageProfileFragment_link_setting_text"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/username_link_icon"
app:layout_goneMarginEnd="48dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -183,7 +217,7 @@
android:paddingTop="16dp"
android:paddingEnd="@dimen/dsl_settings_gutter"
android:paddingBottom="16dp"
app:layout_constraintTop_toBottomOf="@id/manage_profile_username_container">
app:layout_constraintTop_toBottomOf="@id/username_link_container">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/manage_profile_about_icon"
@@ -267,6 +301,95 @@
app:layout_constraintTop_toBottomOf="@+id/manage_profile_badges_container"
app:layout_constraintVertical_bias="1.0" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/username_link_tooltip"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:clickable="true"
android:visibility="gone"
android:background="@color/transparent"
android:clipChildren="false"
android:clipToPadding="false"
tools:visibility="visible"
app:layout_constraintTop_toBottomOf="@id/username_link_container"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<FrameLayout
android:id="@+id/tooltip_arrow_top"
android:layout_width="19dp"
android:layout_height="14dp"
android:importantForAccessibility="no"
android:scaleType="fitXY"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="@drawable/ic_tooltip_arrow_up"
android:backgroundTint="@color/signal_colorPrimaryContainer" />
<FrameLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="9dp"
android:background="@drawable/tooltip_background"
android:backgroundTint="@color/signal_colorPrimaryContainer"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="@id/tooltip_description"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<ImageView
android:id="@+id/tooltip_share_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="25dp"
android:src="@drawable/symbol_share_android_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/tooltip_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="34dp"
android:text="@string/ManageProfileFragment__link_tooltip_title"
android:textAppearance="@style/Signal.Text.Body"
android:fontFamily="sans-serif-medium"
android:textColor="@color/signal_colorOnPrimaryContainer"
app:layout_constraintTop_toTopOf="@id/tooltip_share_icon"
app:layout_constraintStart_toEndOf="@id/tooltip_share_icon"
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
android:id="@+id/tooltip_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingBottom="15dp"
android:text="@string/ManageProfileFragment__link_tooltip_body"
android:textColor="@color/signal_colorOnSurfaceVariant"
app:layout_constraintTop_toBottomOf="@id/tooltip_title"
app:layout_constraintStart_toStartOf="@id/tooltip_title"
app:layout_constraintEnd_toEndOf="@id/tooltip_title"/>
<ImageView
android:id="@+id/link_tooltip_close_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="21dp"
android:layout_marginEnd="12dp"
android:src="@drawable/symbol_x_24"
android:foreground="?selectableItemBackgroundBorderless"
app:tint="@color/signal_colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/create_profile"
app:startDestination="@id/createProfileFragment">
<fragment
android:id="@+id/createProfileFragment"
android:name="org.thoughtcrime.securesms.profiles.edit.CreateProfileFragment"
android:label="fragment_create_profile"
tools:layout="@layout/create_profile_fragment">
<action
android:id="@+id/action_createProfileFragment_to_avatar_picker"
app:destination="@id/avatar_picker"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim">
<argument
android:name="group_id"
app:argType="org.thoughtcrime.securesms.groups.ParcelableGroupId"
app:nullable="true" />
<argument
android:name="group_avatar_media"
app:argType="org.thoughtcrime.securesms.mediasend.Media"
app:nullable="true" />
</action>
<action
android:id="@+id/action_createProfileFragment_to_phoneNumberPrivacy"
app:destination="@id/phoneNumberPrivacy"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
</fragment>
<include app:graph="@navigation/avatar_picker" />
<fragment
android:id="@+id/phoneNumberPrivacy"
android:name="org.thoughtcrime.securesms.profiles.edit.pnp.WhoCanSeeMyPhoneNumberFragment"
android:label="fragment_phone_number_privacy"
tools:layout="@layout/dsl_settings_fragment" />
</navigation>

View File

@@ -2,22 +2,47 @@
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/create_profile"
app:startDestination="@id/createProfileFragment">
android:id="@+id/manage_profile"
app:startDestination="@id/manageProfileFragment">
<fragment
android:id="@+id/createProfileFragment"
android:name="org.thoughtcrime.securesms.profiles.edit.CreateProfileFragment"
android:label="fragment_create_profile"
tools:layout="@layout/create_profile_fragment">
android:id="@+id/manageProfileFragment"
android:name="org.thoughtcrime.securesms.profiles.manage.EditProfileFragment"
android:label="fragment_manage_profile"
tools:layout="@layout/edit_profile_fragment">
<action
android:id="@+id/action_createProfileFragment_to_avatar_picker"
android:id="@+id/action_manageUsername"
app:destination="@id/usernameManageFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit" />
<action
android:id="@+id/action_manageProfileName"
app:destination="@id/profileNameManageFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit" />
<action
android:id="@+id/action_manageAbout"
app:destination="@id/aboutManageFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit" />
<action
android:id="@+id/action_manageProfileFragment_to_avatar_picker"
app:destination="@id/avatar_picker"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim">
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit">
<argument
android:name="group_id"
app:argType="org.thoughtcrime.securesms.groups.ParcelableGroupId"
@@ -27,24 +52,80 @@
android:name="group_avatar_media"
app:argType="org.thoughtcrime.securesms.mediasend.Media"
app:nullable="true" />
</action>
<action
android:id="@+id/action_createProfileFragment_to_phoneNumberPrivacy"
app:destination="@id/phoneNumberPrivacy"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
android:id="@+id/action_manageProfileFragment_to_badgeManageFragment"
app:destination="@id/manage_badges"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit" />
<action
android:id="@+id/action_manageProfileFragment_to_shareUsernameDialog"
app:destination="@id/shareUsernameDialog" />
<action
android:id="@+id/action_manageProfileFragment_to_usernameEducationFragment"
app:destination="@id/usernameEducationFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit" />
<action
android:id="@+id/action_manageProfileFragment_to_usernameLinkFragment"
app:destination="@id/usernameLinkFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit" />
</fragment>
<include app:graph="@navigation/avatar_picker" />
<fragment
android:id="@+id/usernameManageFragment"
android:name="org.thoughtcrime.securesms.profiles.manage.UsernameEditFragment"
android:label="fragment_manage_username"
tools:layout="@layout/username_edit_fragment" />
<fragment
android:id="@+id/phoneNumberPrivacy"
android:name="org.thoughtcrime.securesms.profiles.edit.pnp.WhoCanSeeMyPhoneNumberFragment"
android:label="fragment_phone_number_privacy"
tools:layout="@layout/dsl_settings_fragment" />
android:id="@+id/usernameEducationFragment"
android:name="org.thoughtcrime.securesms.profiles.manage.UsernameEducationFragment"
android:label="fragment_username_education"
tools:layout="@layout/username_education_fragment">
<action
android:id="@+id/action_usernameEducationFragment_to_usernameManageFragment"
app:destination="@id/usernameManageFragment"
app:popUpTo="@id/manageProfileFragment" />
</fragment>
<fragment
android:id="@+id/profileNameManageFragment"
android:name="org.thoughtcrime.securesms.profiles.manage.EditProfileNameFragment"
android:label="fragment_manage_profile_name"
tools:layout="@layout/edit_profile_name_fragment" />
<fragment
android:id="@+id/aboutManageFragment"
android:name="org.thoughtcrime.securesms.profiles.manage.EditAboutFragment"
android:label="fragment_manage_about"
tools:layout="@layout/edit_about_fragment" />
<fragment
android:id="@+id/usernameLinkFragment"
android:name="org.thoughtcrime.securesms.components.settings.app.usernamelinks.main.UsernameLinkSettingsFragment"
android:label="fragment_username_link" />
<include app:graph="@navigation/manage_badges" />
<include app:graph="@navigation/avatar_picker" />
<dialog
android:id="@+id/shareUsernameDialog"
android:name="org.thoughtcrime.securesms.profiles.manage.UsernameShareBottomSheet"
android:label="fragment_username_share" />
</navigation>

View File

@@ -1,112 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/manage_profile"
app:startDestination="@id/manageProfileFragment">
<fragment
android:id="@+id/manageProfileFragment"
android:name="org.thoughtcrime.securesms.profiles.manage.EditProfileFragment"
android:label="fragment_manage_profile"
tools:layout="@layout/edit_profile_fragment">
<action
android:id="@+id/action_manageUsername"
app:destination="@id/usernameManageFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit" />
<action
android:id="@+id/action_manageProfileName"
app:destination="@id/profileNameManageFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit" />
<action
android:id="@+id/action_manageAbout"
app:destination="@id/aboutManageFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit" />
<action
android:id="@+id/action_manageProfileFragment_to_avatar_picker"
app:destination="@id/avatar_picker"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit">
<argument
android:name="group_id"
app:argType="org.thoughtcrime.securesms.groups.ParcelableGroupId"
app:nullable="true" />
<argument
android:name="group_avatar_media"
app:argType="org.thoughtcrime.securesms.mediasend.Media"
app:nullable="true" />
</action>
<action
android:id="@+id/action_manageProfileFragment_to_badgeManageFragment"
app:destination="@id/manage_badges"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"
app:popExitAnim="@anim/fragment_close_exit" />
<action
android:id="@+id/action_manageProfileFragment_to_shareUsernameDialog"
app:destination="@id/shareUsernameDialog" />
<action
android:id="@+id/action_manageProfileFragment_to_usernameEducationFragment"
app:destination="@id/usernameEducationFragment" />
</fragment>
<fragment
android:id="@+id/usernameManageFragment"
android:name="org.thoughtcrime.securesms.profiles.manage.UsernameEditFragment"
android:label="fragment_manage_username"
tools:layout="@layout/username_edit_fragment" />
<fragment
android:id="@+id/usernameEducationFragment"
android:name="org.thoughtcrime.securesms.profiles.manage.UsernameEducationFragment"
android:label="fragment_username_education"
tools:layout="@layout/username_education_fragment">
<action
android:id="@+id/action_usernameEducationFragment_to_usernameManageFragment"
app:destination="@id/usernameManageFragment"
app:popUpTo="@id/manageProfileFragment" />
</fragment>
<fragment
android:id="@+id/profileNameManageFragment"
android:name="org.thoughtcrime.securesms.profiles.manage.EditProfileNameFragment"
android:label="fragment_manage_profile_name"
tools:layout="@layout/edit_profile_name_fragment" />
<fragment
android:id="@+id/aboutManageFragment"
android:name="org.thoughtcrime.securesms.profiles.manage.EditAboutFragment"
android:label="fragment_manage_about"
tools:layout="@layout/edit_about_fragment" />
<include app:graph="@navigation/manage_badges" />
<include app:graph="@navigation/avatar_picker" />
<dialog
android:id="@+id/shareUsernameDialog"
android:name="org.thoughtcrime.securesms.profiles.manage.UsernameShareBottomSheet"
android:label="fragment_username_share" />
</navigation>

View File

@@ -996,6 +996,10 @@
<!-- Text for a button that will take the user to the screen to manage their username link and QR code -->
<string name="ManageProfileFragment_link_setting_text">QR code or link</string>
<string name="ManageProfileFragment__edit_photo">Edit photo</string>
<!-- Title of a tooltip educating the user about a button on the screen that will take them to the username share screen -->
<string name="ManageProfileFragment__link_tooltip_title">Share your username</string>
<!-- Body of a tooltip educating the user about a button on the screen that will take them to the username share screen -->
<string name="ManageProfileFragment__link_tooltip_body">Let others start a chat with you by sharing your unique QR code or link.</string>
<!-- Snackbar message after creating username -->
<string name="ManageProfileFragment__username_created">Username created</string>
<!-- Snackbar message after copying username -->