Add group stories education sheet.

main
Alex Hart 2022-11-17 12:35:17 -04:00 zatwierdzone przez GitHub
rodzic 0df3096241
commit 04e8235cfc
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
11 zmienionych plików z 311 dodań i 35 usunięć

Wyświetl plik

@ -46,6 +46,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
import org.thoughtcrime.securesms.sharing.ShareSelectionAdapter
import org.thoughtcrime.securesms.sharing.ShareSelectionMappingModel
import org.thoughtcrime.securesms.stories.GroupStoryEducationSheet
import org.thoughtcrime.securesms.stories.Stories
import org.thoughtcrime.securesms.stories.Stories.getHeaderAction
import org.thoughtcrime.securesms.stories.settings.create.CreateStoryFlowDialogFragment
@ -80,6 +81,7 @@ class MultiselectForwardFragment :
Fragment(R.layout.multiselect_forward_fragment),
SafetyNumberBottomSheet.Callbacks,
ChooseStoryTypeBottomSheet.Callback,
GroupStoryEducationSheet.Callback,
WrapperDialogFragment.WrapperDialogFragmentCallback,
ChooseInitialMyStoryMembershipBottomSheetDialogFragment.Callback {
@ -466,13 +468,21 @@ class MultiselectForwardFragment :
}
override fun onGroupStoryClicked() {
ChooseGroupStoryBottomSheet().show(parentFragmentManager, ChooseGroupStoryBottomSheet.GROUP_STORY)
if (SignalStore.storyValues().userHasSeenGroupStoryEducationSheet) {
onGroupStoryEducationSheetNext()
} else {
GroupStoryEducationSheet().show(childFragmentManager, GroupStoryEducationSheet.KEY)
}
}
override fun onNewStoryClicked() {
CreateStoryFlowDialogFragment().show(parentFragmentManager, CreateStoryWithViewersFragment.REQUEST_KEY)
}
override fun onGroupStoryEducationSheetNext() {
ChooseGroupStoryBottomSheet().show(parentFragmentManager, ChooseGroupStoryBottomSheet.GROUP_STORY)
}
override fun onWrapperDialogFragmentDismissed() {
contactSearchMediator.refresh()
}

Wyświetl plik

@ -49,6 +49,11 @@ internal class StoryValues(store: KeyValueStore) : SignalStoreValues(store) {
* Whether or not the user will send and receive viewed receipts for stories
*/
private const val STORY_VIEWED_RECEIPTS = "stories.viewed.receipts"
/**
* Whether or not the user has seen the group story education sheet
*/
private const val USER_HAS_SEEN_GROUP_STORY_EDUCATION_SHEET = "stories.user.has.seen.group.story.education.sheet"
}
override fun onFirstEverAppLaunch() {
@ -62,7 +67,8 @@ internal class StoryValues(store: KeyValueStore) : SignalStoreValues(store) {
HAS_DOWNLOADED_ONBOARDING_STORY,
USER_HAS_VIEWED_ONBOARDING_STORY,
USER_HAS_READ_ONBOARDING_STORY,
STORY_VIEWED_RECEIPTS
STORY_VIEWED_RECEIPTS,
USER_HAS_SEEN_GROUP_STORY_EDUCATION_SHEET
)
var isFeatureDisabled: Boolean by booleanValue(MANUAL_FEATURE_DISABLE, false)
@ -81,6 +87,8 @@ internal class StoryValues(store: KeyValueStore) : SignalStoreValues(store) {
var viewedReceiptsEnabled: Boolean by booleanValue(STORY_VIEWED_RECEIPTS, false)
var userHasSeenGroupStoryEducationSheet: Boolean by booleanValue(USER_HAS_SEEN_GROUP_STORY_EDUCATION_SHEET, false)
fun isViewedReceiptsStateSet(): Boolean {
return store.containsKey(STORY_VIEWED_RECEIPTS)
}

Wyświetl plik

@ -124,6 +124,7 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
boolean hasViewedOnboardingStory = remote.hasViewedOnboardingStory();
boolean storiesDisabled = remote.isStoriesDisabled();
boolean hasReadOnboardingStory = remote.hasReadOnboardingStory() || remote.hasViewedOnboardingStory() || local.hasReadOnboardingStory() || local.hasViewedOnboardingStory() ;
boolean hasSeenGroupStoryEducation = remote.hasSeenGroupStoryEducationSheet() || local.hasSeenGroupStoryEducationSheet();
boolean matchesRemote = doParamsMatch(remote, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164, defaultReactions, subscriber, displayBadgesOnProfile, subscriptionManuallyCancelled, keepMutedChatsArchived, hasSetMyStoriesPrivacy, hasViewedOnboardingStory, storiesDisabled, storyViewReceiptsState, hasReadOnboardingStory);
boolean matchesLocal = doParamsMatch(local, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164, defaultReactions, subscriber, displayBadgesOnProfile, subscriptionManuallyCancelled, keepMutedChatsArchived, hasSetMyStoriesPrivacy, hasViewedOnboardingStory, storiesDisabled, storyViewReceiptsState, hasReadOnboardingStory);
@ -161,6 +162,7 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
.setHasViewedOnboardingStory(hasViewedOnboardingStory)
.setStoriesDisabled(storiesDisabled)
.setHasReadOnboardingStory(hasReadOnboardingStory)
.setHasSeenGroupStoryEducationSheet(hasSeenGroupStoryEducation)
.build();
}
}

Wyświetl plik

@ -152,6 +152,7 @@ public final class StorageSyncHelper {
.setStoriesDisabled(SignalStore.storyValues().isFeatureDisabled())
.setStoryViewReceiptsState(storyViewReceiptsState)
.setHasReadOnboardingStory(hasReadOnboardingStory)
.setHasSeenGroupStoryEducationSheet(SignalStore.storyValues().getUserHasSeenGroupStoryEducationSheet())
.build();
return SignalStorageRecord.forAccount(account);
@ -181,6 +182,7 @@ public final class StorageSyncHelper {
SignalStore.storyValues().setUserHasViewedOnboardingStory(update.getNew().hasViewedOnboardingStory());
SignalStore.storyValues().setFeatureDisabled(update.getNew().isStoriesDisabled());
SignalStore.storyValues().setUserHasReadOnboardingStory(update.getNew().hasReadOnboardingStory());
SignalStore.storyValues().setUserHasSeenGroupStoryEducationSheet(update.getNew().hasSeenGroupStoryEducationSheet());
if (update.getNew().getStoryViewReceiptsState() == OptionalBool.UNSET) {
SignalStore.storyValues().setViewedReceiptsEnabled(update.getNew().isReadReceiptsEnabled());

Wyświetl plik

@ -0,0 +1,43 @@
package org.thoughtcrime.securesms.stories
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.button.MaterialButton
import org.signal.core.util.concurrent.SignalExecutors
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.fragments.requireListener
/**
* Displays an education sheet to the user which explains what Group Stories are.
*/
class GroupStoryEducationSheet : FixedRoundedCornerBottomSheetDialogFragment() {
companion object {
const val KEY = "GROUP_STORY_EDU"
}
override val peekHeightPercentage: Float = 1f
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.group_story_education_sheet, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
SignalStore.storyValues().userHasSeenGroupStoryEducationSheet = true
SignalExecutors.BOUNDED_IO.execute { Stories.onStorySettingsChanged(Recipient.self().id) }
view.findViewById<MaterialButton>(R.id.next).setOnClickListener {
requireListener<Callback>().onGroupStoryEducationSheetNext()
dismissAllowingStateLoss()
}
}
interface Callback {
fun onGroupStoryEducationSheetNext()
}
}

Wyświetl plik

@ -16,8 +16,10 @@ import org.thoughtcrime.securesms.components.settings.configure
import org.thoughtcrime.securesms.contacts.paged.ContactSearchItems
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
import org.thoughtcrime.securesms.groups.ParcelableGroupId
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.mediasend.v2.stories.ChooseGroupStoryBottomSheet
import org.thoughtcrime.securesms.mediasend.v2.stories.ChooseStoryTypeBottomSheet
import org.thoughtcrime.securesms.stories.GroupStoryEducationSheet
import org.thoughtcrime.securesms.stories.dialogs.StoryDialogs
import org.thoughtcrime.securesms.stories.settings.create.CreateStoryFlowDialogFragment
import org.thoughtcrime.securesms.stories.settings.create.CreateStoryWithViewersFragment
@ -34,7 +36,8 @@ class StoriesPrivacySettingsFragment :
DSLSettingsFragment(
titleId = R.string.preferences__stories
),
ChooseStoryTypeBottomSheet.Callback {
ChooseStoryTypeBottomSheet.Callback,
GroupStoryEducationSheet.Callback {
private val viewModel: StoriesPrivacySettingsViewModel by viewModels()
private val lifecycleDisposable = LifecycleDisposable()
@ -181,10 +184,18 @@ class StoriesPrivacySettingsFragment :
}
override fun onGroupStoryClicked() {
ChooseGroupStoryBottomSheet().show(parentFragmentManager, ChooseGroupStoryBottomSheet.GROUP_STORY)
if (SignalStore.storyValues().userHasSeenGroupStoryEducationSheet) {
onGroupStoryEducationSheetNext()
} else {
GroupStoryEducationSheet().show(childFragmentManager, GroupStoryEducationSheet.KEY)
}
}
override fun onNewStoryClicked() {
CreateStoryFlowDialogFragment().show(parentFragmentManager, CreateStoryWithViewersFragment.REQUEST_KEY)
}
override fun onGroupStoryEducationSheetNext() {
ChooseGroupStoryBottomSheet().show(parentFragmentManager, ChooseGroupStoryBottomSheet.GROUP_STORY)
}
}

Wyświetl plik

@ -0,0 +1,45 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="140dp"
android:height="128dp"
android:viewportWidth="140"
android:viewportHeight="128">
<path
android:pathData="M53.92,13.83L97.42,13.83A14.5,14.5 0,0 1,111.92 28.33L111.92,105.67A14.5,14.5 0,0 1,97.42 120.17L53.92,120.17A14.5,14.5 0,0 1,39.42 105.67L39.42,28.33A14.5,14.5 0,0 1,53.92 13.83z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="75.67"
android:startY="13.83"
android:endX="75.67"
android:endY="120.17"
android:type="linear">
<item android:offset="0" android:color="#FF4437D8"/>
<item android:offset="0.33" android:color="#FF6B70DE"/>
<item android:offset="0.67" android:color="#FFB774E0"/>
<item android:offset="1" android:color="#FFFF8E8E"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M33.95,25.81L25.98,28.71C18.45,31.45 14.57,39.77 17.31,47.3L33.95,93.02V25.81Z"
android:fillType="evenOdd">
<aapt:attr name="android:fillColor">
<gradient
android:startX="25.19"
android:startY="25.81"
android:endX="25.19"
android:endY="93.02"
android:type="linear">
<item android:offset="0" android:color="#FF4437D8"/>
<item android:offset="0.33" android:color="#FF6B70DE"/>
<item android:offset="0.67" android:color="#FFB774E0"/>
<item android:offset="1" android:color="#FFFF8E8E"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M86.55,63.1C88.62,63.1 90.6,63.93 92.06,65.39C93.52,66.85 94.35,68.83 94.35,70.9V71.8H96.15V70.9C96.15,68.63 95.34,66.43 93.87,64.69C92.39,62.96 90.35,61.81 88.11,61.44C89.3,60.39 90.14,59.01 90.52,57.47C90.9,55.93 90.81,54.31 90.25,52.83C89.69,51.35 88.69,50.07 87.38,49.17C86.08,48.27 84.53,47.79 82.95,47.79C81.37,47.79 79.82,48.27 78.52,49.17C77.21,50.07 76.21,51.35 75.65,52.83C75.09,54.31 75,55.93 75.38,57.47C75.76,59.01 76.6,60.39 77.79,61.44C76.64,61.62 75.54,62.02 74.54,62.6C73.85,61.77 73,61.09 72.04,60.6C71.08,60.11 70.02,59.82 68.95,59.76C67.87,59.7 66.79,59.87 65.78,60.24C64.77,60.62 63.84,61.21 63.07,61.96C62.3,62.71 61.69,63.62 61.28,64.62C60.87,65.62 60.68,66.69 60.71,67.77C60.74,68.85 60.99,69.91 61.46,70.88C61.92,71.86 62.58,72.73 63.39,73.44C61.15,73.81 59.11,74.96 57.63,76.69C56.16,78.43 55.35,80.63 55.35,82.9V83.8H57.15V82.9C57.15,80.83 57.98,78.85 59.44,77.39C60.9,75.93 62.88,75.1 64.95,75.1H72.15C74.22,75.1 76.2,75.93 77.66,77.39C79.12,78.85 79.95,80.83 79.95,82.9V83.8H81.75V82.9C81.75,80.63 80.94,78.43 79.47,76.69C77.99,74.96 75.95,73.81 73.71,73.44C75,72.3 75.88,70.77 76.21,69.08C76.54,67.4 76.29,65.65 75.52,64.11C76.69,63.45 78.01,63.1 79.35,63.1H86.55ZM68.55,73.6C67.36,73.6 66.2,73.25 65.22,72.59C64.23,71.93 63.46,70.99 63.01,69.9C62.55,68.8 62.43,67.59 62.67,66.43C62.9,65.27 63.47,64.2 64.31,63.36C65.15,62.52 66.22,61.95 67.38,61.72C68.54,61.48 69.75,61.6 70.85,62.06C71.94,62.51 72.88,63.28 73.54,64.27C74.2,65.25 74.55,66.41 74.55,67.6C74.55,69.19 73.92,70.72 72.79,71.84C71.67,72.97 70.14,73.6 68.55,73.6V73.6ZM76.95,55.6C76.95,54.41 77.3,53.25 77.96,52.27C78.62,51.28 79.56,50.51 80.65,50.06C81.75,49.6 82.96,49.48 84.12,49.72C85.28,49.95 86.35,50.52 87.19,51.36C88.03,52.2 88.6,53.27 88.83,54.43C89.07,55.59 88.95,56.8 88.49,57.9C88.04,58.99 87.27,59.93 86.28,60.59C85.3,61.25 84.14,61.6 82.95,61.6C81.36,61.6 79.83,60.97 78.71,59.84C77.58,58.72 76.95,57.19 76.95,55.6Z"
android:strokeWidth="0.5"
android:fillColor="#ffffff"
android:strokeColor="#ffffff"/>
</vector>

Wyświetl plik

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="wrap_content"
tools:viewBindingIgnore="true">
<ImageView
android:id="@+id/handle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:importantForAccessibility="no"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/bottom_sheet_handle" />
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:importantForAccessibility="no"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/handle"
app:srcCompat="@drawable/group_story" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="24dp"
android:text="@string/GroupStoryEducationSheet__introducing_group_stories"
android:textAppearance="@style/Signal.Text.TitleLarge"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/image" />
<ImageView
android:id="@+id/share_story_updates_img"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_marginStart="32dp"
android:importantForAccessibility="no"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/share_story_updates_text"
app:srcCompat="@drawable/ic_group_24"
app:tint="@color/signal_colorOnSurface" />
<ImageView
android:id="@+id/anyone_in_group_img"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_marginStart="32dp"
android:importantForAccessibility="no"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/anyone_in_group_text"
app:srcCompat="@drawable/ic_plus_24"
app:tint="@color/signal_colorOnSurface" />
<ImageView
android:id="@+id/all_group_chat_members_img"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_marginStart="32dp"
android:importantForAccessibility="no"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/all_group_chat_members_text"
app:srcCompat="@drawable/ic_reply_24"
app:tint="@color/signal_colorOnSurface" />
<TextView
android:id="@+id/share_story_updates_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="32dp"
android:text="@string/GroupStoryEducationSheet__share_story_updates_to"
android:textAppearance="@style/Signal.Text.BodyLarge"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/share_story_updates_img"
app:layout_constraintTop_toBottomOf="@id/title" />
<TextView
android:id="@+id/anyone_in_group_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="32dp"
android:text="@string/GroupStoryEducationSheet__anyone_in_the_group"
android:textAppearance="@style/Signal.Text.BodyLarge"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/anyone_in_group_img"
app:layout_constraintTop_toBottomOf="@id/share_story_updates_text" />
<TextView
android:id="@+id/all_group_chat_members_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="32dp"
android:text="@string/GroupStoryEducationSheet__all_group_chat_members"
android:textAppearance="@style/Signal.Text.BodyLarge"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/all_group_chat_members_img"
app:layout_constraintTop_toBottomOf="@id/anyone_in_group_text" />
<com.google.android.material.button.MaterialButton
android:id="@+id/next"
style="@style/Signal.Widget.Button.Medium.Primary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="36dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="16dp"
android:text="@string/GroupStoryEducationSheet__next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/all_group_chat_members_text" />
</androidx.constraintlayout.widget.ConstraintLayout>

Wyświetl plik

@ -5604,6 +5604,18 @@
<string name="YourInformationIsPrivateBottomSheet__signal_does_not_and_cannot">Signal does not and cannot connect your donation to your Signal account.</string>
<string name="YourInformationIsPrivateBottomSheet__thank_you">Thank you for your support!</string>
<!-- GroupStoryEducationSheet -->
<!-- Displayed as the title of the education bottom sheet -->
<string name="GroupStoryEducationSheet__introducing_group_stories">Introducing: Group Stories</string>
<!-- Line item on the sheet explaining group stories -->
<string name="GroupStoryEducationSheet__share_story_updates_to">Share story updates to a group chat you\'re already in.</string>
<!-- Line item on the sheet explaining that anyone in the group can share to group stories -->
<string name="GroupStoryEducationSheet__anyone_in_the_group">Anyone in the group chat can add to the story.</string>
<!-- Line item on the sheet explaining that anyone in the group can view replies -->
<string name="GroupStoryEducationSheet__all_group_chat_members">All group chat members can view story replies.</string>
<!-- Button label to dismiss sheet -->
<string name="GroupStoryEducationSheet__next">Next</string>
<!-- EOF -->
</resources>

Wyświetl plik

@ -191,6 +191,10 @@ public final class SignalAccountRecord implements SignalRecord {
diff.add("HasReadOnboardingStory");
}
if (hasSeenGroupStoryEducationSheet() != that.hasSeenGroupStoryEducationSheet()) {
diff.add("HasSeenGroupStoryEducationSheet");
}
return diff.toString();
} else {
return "Different class. " + getClass().getSimpleName() + " | " + other.getClass().getSimpleName();
@ -317,6 +321,10 @@ public final class SignalAccountRecord implements SignalRecord {
return proto.getHasReadOnboardingStory();
}
public boolean hasSeenGroupStoryEducationSheet() {
return proto.getHasSeenGroupStoryEducationSheet();
}
public AccountRecord toProto() {
return proto;
}
@ -684,6 +692,11 @@ public final class SignalAccountRecord implements SignalRecord {
return this;
}
public Builder setHasSeenGroupStoryEducationSheet(boolean hasSeenGroupStoryEducationSheet) {
builder.setHasSeenGroupStoryEducationSheet(hasSeenGroupStoryEducationSheet);
return this;
}
private static AccountRecord.Builder parseUnknowns(byte[] serializedUnknowns) {
try {
return AccountRecord.parseFrom(serializedUnknowns).toBuilder();

Wyświetl plik

@ -153,37 +153,38 @@ message AccountRecord {
}
}
bytes profileKey = 1;
string givenName = 2;
string familyName = 3;
string avatarUrlPath = 4;
bool noteToSelfArchived = 5;
bool readReceipts = 6;
bool sealedSenderIndicators = 7;
bool typingIndicators = 8;
bool proxiedLinkPreviews = 9;
bool noteToSelfMarkedUnread = 10;
bool linkPreviews = 11;
PhoneNumberSharingMode phoneNumberSharingMode = 12;
bool unlistedPhoneNumber = 13;
repeated PinnedConversation pinnedConversations = 14;
bool preferContactAvatars = 15;
Payments payments = 16;
uint32 universalExpireTimer = 17;
bool primarySendsSms = 18;
string e164 = 19;
repeated string preferredReactionEmoji = 20;
bytes subscriberId = 21;
string subscriberCurrencyCode = 22;
bool displayBadgesOnProfile = 23;
bool subscriptionManuallyCancelled = 24;
bool keepMutedChatsArchived = 25;
bool hasSetMyStoriesPrivacy = 26;
bool hasViewedOnboardingStory = 27;
reserved /* storiesDisabled */ 28;
bool storiesDisabled = 29;
OptionalBool storyViewReceiptsEnabled = 30;
bool hasReadOnboardingStory = 31;
bytes profileKey = 1;
string givenName = 2;
string familyName = 3;
string avatarUrlPath = 4;
bool noteToSelfArchived = 5;
bool readReceipts = 6;
bool sealedSenderIndicators = 7;
bool typingIndicators = 8;
bool proxiedLinkPreviews = 9;
bool noteToSelfMarkedUnread = 10;
bool linkPreviews = 11;
PhoneNumberSharingMode phoneNumberSharingMode = 12;
bool unlistedPhoneNumber = 13;
repeated PinnedConversation pinnedConversations = 14;
bool preferContactAvatars = 15;
Payments payments = 16;
uint32 universalExpireTimer = 17;
bool primarySendsSms = 18;
string e164 = 19;
repeated string preferredReactionEmoji = 20;
bytes subscriberId = 21;
string subscriberCurrencyCode = 22;
bool displayBadgesOnProfile = 23;
bool subscriptionManuallyCancelled = 24;
bool keepMutedChatsArchived = 25;
bool hasSetMyStoriesPrivacy = 26;
bool hasViewedOnboardingStory = 27;
reserved /* storiesDisabled */ 28;
bool storiesDisabled = 29;
OptionalBool storyViewReceiptsEnabled = 30;
bool hasReadOnboardingStory = 31;
bool hasSeenGroupStoryEducationSheet = 32;
}
message StoryDistributionListRecord {