Add group stories education sheet.

This commit is contained in:
Alex Hart
2022-11-17 12:35:17 -04:00
committed by GitHub
parent 0df3096241
commit 04e8235cfc
11 changed files with 311 additions and 35 deletions

View File

@@ -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()
}

View File

@@ -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)
}

View File

@@ -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();
}
}

View File

@@ -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());

View File

@@ -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()
}
}

View File

@@ -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)
}
}