From 7edef20f4ff1951925c36a0c99a1a250bcc7e073 Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Thu, 17 Mar 2022 15:26:47 -0300 Subject: [PATCH] Guard first time on add to my story. --- .../forward/MultiselectForwardFragment.kt | 22 +++++++++++- .../securesms/keyvalue/StoryValues.kt | 2 +- .../v2/text/send/TextStoryPostSendFragment.kt | 30 ++++++++-------- .../text/send/TextStoryPostSendRepository.kt | 14 +------- .../text/send/TextStoryPostSendViewModel.kt | 4 +-- .../securesms/sharing/ShareActivity.java | 35 +++++++++++++++++-- .../securesms/stories/dialogs/StoryDialogs.kt | 35 ++++++++++++++----- 7 files changed, 97 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragment.kt index 0d9436f49..e6e3e40bf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragment.kt @@ -35,8 +35,10 @@ import org.thoughtcrime.securesms.sharing.ShareSelectionAdapter import org.thoughtcrime.securesms.sharing.ShareSelectionMappingModel import org.thoughtcrime.securesms.stories.Stories import org.thoughtcrime.securesms.stories.Stories.getHeaderAction +import org.thoughtcrime.securesms.stories.dialogs.StoryDialogs import org.thoughtcrime.securesms.stories.settings.create.CreateStoryFlowDialogFragment import org.thoughtcrime.securesms.stories.settings.create.CreateStoryWithViewersFragment +import org.thoughtcrime.securesms.stories.settings.hide.HideStoryFromDialogFragment import org.thoughtcrime.securesms.util.BottomSheetUtil import org.thoughtcrime.securesms.util.FeatureFlags import org.thoughtcrime.securesms.util.LifecycleDisposable @@ -105,7 +107,21 @@ class MultiselectForwardFragment : sendButton.setOnClickListener { sendButton.isEnabled = false - viewModel.send(addMessage.text.toString(), contactSearchMediator.getSelectedContacts()) + + StoryDialogs.guardWithAddToYourStoryDialog( + requireContext(), + contactSearchMediator.getSelectedContacts(), + onAddToStory = { + performSend() + }, + onEditViewers = { + sendButton.isEnabled = true + HideStoryFromDialogFragment().show(childFragmentManager, null) + }, + onCancel = { + sendButton.isEnabled = true + } + ) } shareSelectionRecycler.adapter = shareSelectionAdapter @@ -211,6 +227,10 @@ class MultiselectForwardFragment : .show() } + private fun performSend() { + viewModel.send(addMessage.text.toString(), contactSearchMediator.getSelectedContacts()) + } + private fun displaySafetyNumberConfirmation(identityRecords: List) { SafetyNumberChangeDialog.show(childFragmentManager, identityRecords) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/StoryValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/StoryValues.kt index f5ebb110e..fbbb15acf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/StoryValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/StoryValues.kt @@ -24,5 +24,5 @@ internal class StoryValues(store: KeyValueStore) : SignalStoreValues(store) { var lastFontVersionCheck: Long by longValue(LAST_FONT_VERSION_CHECK, 0) - var userHasAddedToAStory: Boolean by booleanValue(USER_HAS_ADDED_TO_A_STORY, false) + var userHasBeenNotifiedAboutStories: Boolean by booleanValue(USER_HAS_ADDED_TO_A_STORY, false) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/send/TextStoryPostSendFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/send/TextStoryPostSendFragment.kt index d3e627557..8d74ba476 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/send/TextStoryPostSendFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/send/TextStoryPostSendFragment.kt @@ -46,7 +46,7 @@ class TextStoryPostSendFragment : Fragment(R.layout.stories_send_text_post_fragm private val viewModel: TextStoryPostSendViewModel by viewModels( factoryProducer = { - TextStoryPostSendViewModel.Factory(TextStoryPostSendRepository(requireContext())) + TextStoryPostSendViewModel.Factory(TextStoryPostSendRepository()) } ) @@ -83,21 +83,19 @@ class TextStoryPostSendFragment : Fragment(R.layout.stories_send_text_post_fragm } shareConfirmButton.setOnClickListener { - if (viewModel.isFirstSendToAStory(contactSearchMediator.getSelectedContacts())) { - StoryDialogs.guardWithAddToYourStoryDialog( - context = requireContext(), - onAddToStory = { send() }, - onEditViewers = { - viewModel.onSendCancelled() - HideStoryFromDialogFragment().show(childFragmentManager, null) - }, - onCancel = { - viewModel.onSendCancelled() - } - ) - } else { - send() - } + viewModel.onSending() + StoryDialogs.guardWithAddToYourStoryDialog( + contacts = contactSearchMediator.getSelectedContacts(), + context = requireContext(), + onAddToStory = { send() }, + onEditViewers = { + viewModel.onSendCancelled() + HideStoryFromDialogFragment().show(childFragmentManager, null) + }, + onCancel = { + viewModel.onSendCancelled() + } + ) } disposables += viewModel.untrustedIdentities.subscribe { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/send/TextStoryPostSendRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/send/TextStoryPostSendRepository.kt index 051ed3c0a..f2f1ecdf3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/send/TextStoryPostSendRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/send/TextStoryPostSendRepository.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.mediasend.v2.text.send -import android.content.Context import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.core.Single import org.signal.core.util.ThreadUtil @@ -11,7 +10,6 @@ import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.database.model.StoryType import org.thoughtcrime.securesms.database.model.databaseprotos.StoryTextPost import org.thoughtcrime.securesms.fonts.TextFont -import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.linkpreview.LinkPreview import org.thoughtcrime.securesms.mediasend.v2.UntrustedRecords import org.thoughtcrime.securesms.mediasend.v2.text.TextStoryPostCreationState @@ -21,17 +19,7 @@ import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.stories.Stories import org.thoughtcrime.securesms.util.Base64 -class TextStoryPostSendRepository(context: Context) { - - private val context = context.applicationContext - - fun isFirstSendToStory(shareContacts: Set): Boolean { - if (SignalStore.storyValues().userHasAddedToAStory) { - return false - } - - return shareContacts.any { it is ContactSearchKey.Story } - } +class TextStoryPostSendRepository { fun send(contactSearchKey: Set, textStoryPostCreationState: TextStoryPostCreationState, linkPreview: LinkPreview?): Single { return UntrustedRecords diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/send/TextStoryPostSendViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/send/TextStoryPostSendViewModel.kt index b7e55fe78..bacd0b004 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/send/TextStoryPostSendViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/send/TextStoryPostSendViewModel.kt @@ -27,12 +27,10 @@ class TextStoryPostSendViewModel(private val repository: TextStoryPostSendReposi disposables.clear() } - fun isFirstSendToAStory(contactSearchKeys: Set): Boolean { + fun onSending() { store.update { TextStoryPostSendState.SENDING } - - return repository.isFirstSendToStory(contactSearchKeys) } fun onSendCancelled() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java index bdc548b5e..7b1918e11 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java @@ -47,6 +47,7 @@ import org.thoughtcrime.securesms.PassphraseRequiredActivity; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.components.SearchToolbar; import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode; +import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey; import org.thoughtcrime.securesms.conversation.ConversationIntents; import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; @@ -56,6 +57,8 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.sharing.interstitial.ShareInterstitialActivity; import org.thoughtcrime.securesms.stories.Stories; +import org.thoughtcrime.securesms.stories.dialogs.StoryDialogs; +import org.thoughtcrime.securesms.stories.settings.hide.HideStoryFromDialogFragment; import org.thoughtcrime.securesms.util.ConversationUtil; import org.thoughtcrime.securesms.util.DynamicLanguage; import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme; @@ -78,6 +81,7 @@ import java.util.concurrent.atomic.AtomicReference; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.schedulers.Schedulers; +import kotlin.Unit; /** * Entry point for sharing content into the app. @@ -380,11 +384,30 @@ public class ShareActivity extends PassphraseRequiredActivity .commit(); shareConfirm.setOnClickListener(unused -> { + shareConfirm.setEnabled(false); + Set shareContacts = viewModel.getShareContacts(); - if (shareContacts.isEmpty()) throw new AssertionError(); - else if (shareContacts.size() == 1) onConfirmSingleDestination(shareContacts.iterator().next()); - else onConfirmMultipleDestinations(shareContacts); + StoryDialogs.INSTANCE.guardWithAddToYourStoryDialog(this, + shareContacts.stream() + .filter(contact -> contact.getRecipientId().isPresent()) + .map(contact -> Recipient.resolved(contact.getRecipientId().get())) + .filter(Recipient::isMyStory) + .map(myStory -> new ContactSearchKey.Story(myStory.getId())) + .collect(java.util.stream.Collectors.toList()), + () -> { + performSend(shareContacts); + return Unit.INSTANCE; + }, + () -> { + shareConfirm.setEnabled(true); + new HideStoryFromDialogFragment().show(getSupportFragmentManager(), null); + return Unit.INSTANCE; + }, + () -> { + shareConfirm.setEnabled(true); + return Unit.INSTANCE; + }); }); viewModel.getSelectedContactModels().observe(this, models -> { @@ -438,6 +461,12 @@ public class ShareActivity extends PassphraseRequiredActivity }); } + private void performSend(Set shareContacts) { + if (shareContacts.isEmpty()) throw new AssertionError(); + else if (shareContacts.size() == 1) onConfirmSingleDestination(shareContacts.iterator().next()); + else onConfirmMultipleDestinations(shareContacts); + } + private void initializeArgs() { this.args = ShareIntents.Args.from(getIntent()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/dialogs/StoryDialogs.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/dialogs/StoryDialogs.kt index cf810e25d..51fb173fc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/dialogs/StoryDialogs.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/dialogs/StoryDialogs.kt @@ -3,6 +3,9 @@ package org.thoughtcrime.securesms.stories.dialogs import android.content.Context import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey +import org.thoughtcrime.securesms.keyvalue.SignalStore +import org.thoughtcrime.securesms.recipients.Recipient object StoryDialogs { @@ -11,17 +14,33 @@ object StoryDialogs { */ fun guardWithAddToYourStoryDialog( context: Context, + contacts: Collection, onAddToStory: () -> Unit, onEditViewers: () -> Unit, onCancel: () -> Unit = {} ) { - MaterialAlertDialogBuilder(context, R.style.Signal_ThemeOverlay_Dialog_Rounded) - .setTitle(R.string.StoryDialogs__add_to_story_q) - .setMessage(R.string.StoryDialogs__adding_content) - .setPositiveButton(R.string.StoryDialogs__add_to_story) { _, _ -> onAddToStory.invoke() } - .setNeutralButton(R.string.StoryDialogs__edit_viewers) { _, _ -> onEditViewers.invoke() } - .setNegativeButton(android.R.string.cancel) { _, _ -> onCancel.invoke() } - .setCancelable(false) - .show() + if (!isFirstSendToMyStory(contacts)) { + onAddToStory() + } else { + SignalStore.storyValues().userHasBeenNotifiedAboutStories = true + MaterialAlertDialogBuilder(context, R.style.Signal_ThemeOverlay_Dialog_Rounded) + .setTitle(R.string.StoryDialogs__add_to_story_q) + .setMessage(R.string.StoryDialogs__adding_content) + .setPositiveButton(R.string.StoryDialogs__add_to_story) { _, _ -> + onAddToStory.invoke() + } + .setNeutralButton(R.string.StoryDialogs__edit_viewers) { _, _ -> onEditViewers.invoke() } + .setNegativeButton(android.R.string.cancel) { _, _ -> onCancel.invoke() } + .setCancelable(false) + .show() + } + } + + private fun isFirstSendToMyStory(shareContacts: Collection): Boolean { + if (SignalStore.storyValues().userHasBeenNotifiedAboutStories) { + return false + } + + return shareContacts.any { it is ContactSearchKey.Story && Recipient.resolved(it.recipientId).isMyStory } } }