From be01f2b51153e3d2009a1c394dec342f4abb429d Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Tue, 30 May 2023 13:15:50 -0300 Subject: [PATCH] CFV2 -- Add to Contacts / Mute Conversation. --- .../conversation/v2/AddToContactsContract.kt | 28 ++++++++++++++++++- .../conversation/v2/ConversationFragment.kt | 13 +++++++-- .../conversation/v2/ConversationRepository.kt | 5 ++++ .../conversation/v2/ConversationViewModel.kt | 9 ++++++ .../securesms/recipients/Recipient.java | 7 +++++ 5 files changed, 58 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/AddToContactsContract.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/AddToContactsContract.kt index 24cb2551dd..df69e0972b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/AddToContactsContract.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/AddToContactsContract.kt @@ -18,6 +18,8 @@ import org.thoughtcrime.securesms.contactshare.Contact import org.thoughtcrime.securesms.contactshare.ContactUtil import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob +import org.thoughtcrime.securesms.recipients.Recipient +import org.thoughtcrime.securesms.recipients.RecipientExporter /** * Wraps up the "Add shared contact to contact list" into a contract. The flow here is a little @@ -44,7 +46,31 @@ class AddToContactsContract : ActivityResultContract() { launcher: ActivityResultLauncher, contact: Contact ): Disposable { - return Single.fromCallable { ContactUtil.buildAddToContactsIntent(fragment.requireContext(), contact) } + return launchIntent( + fragment = fragment, + launcher = launcher, + intentProducer = Single.fromCallable { ContactUtil.buildAddToContactsIntent(fragment.requireContext(), contact) } + ) + } + + fun createIntentAndLaunch( + fragment: Fragment, + launcher: ActivityResultLauncher, + recipient: Recipient + ): Disposable { + return launchIntent( + fragment = fragment, + launcher = launcher, + intentProducer = Single.just(RecipientExporter.export(recipient).asAddContactIntent()) + ) + } + + private fun launchIntent( + fragment: Fragment, + launcher: ActivityResultLauncher, + intentProducer: Single + ): Disposable { + return intentProducer .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeBy { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt index 57aeb8e5e7..f48c895c0d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt @@ -74,6 +74,7 @@ import org.signal.libsignal.protocol.InvalidMessageException import org.thoughtcrime.securesms.BlockUnblockDialog import org.thoughtcrime.securesms.LoggingFragment import org.thoughtcrime.securesms.MainActivity +import org.thoughtcrime.securesms.MuteDialog import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.badges.gifts.OpenableGift import org.thoughtcrime.securesms.badges.gifts.OpenableGiftItemDecoration @@ -1790,7 +1791,13 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment) } override fun handleAddToContacts() { - // TODO [cfv2] - ("Not yet implemented") + val recipient = viewModel.recipientSnapshot?.takeIf { it.isIndividual } ?: return + + AddToContactsContract.createIntentAndLaunch( + fragment = this@ConversationFragment, + launcher = addToContactsLauncher, + recipient = recipient + ) } override fun handleDisplayGroupRecipients() { @@ -1842,11 +1849,11 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment) } override fun handleMuteNotifications() { - // TODO [cfv2] - ("Not yet implemented") + MuteDialog.show(requireContext(), viewModel::muteConversation) } override fun handleUnmuteNotifications() { - // TODO [cfv2] - ("Not yet implemented") + viewModel.muteConversation(0L) } override fun handleConversationSettings() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRepository.kt index afb72dd135..12aea834f2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRepository.kt @@ -44,6 +44,7 @@ import org.thoughtcrime.securesms.database.RecipientTable import org.thoughtcrime.securesms.database.RxDatabaseObserver import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.SignalDatabase.Companion.attachments +import org.thoughtcrime.securesms.database.SignalDatabase.Companion.recipients import org.thoughtcrime.securesms.database.model.GroupRecord import org.thoughtcrime.securesms.database.model.IdentityRecord import org.thoughtcrime.securesms.database.model.Mention @@ -345,6 +346,10 @@ class ConversationRepository( }.subscribeOn(Schedulers.io()) } + fun setConversationMuted(recipientId: RecipientId, until: Long) { + SignalExecutors.BOUNDED_IO.execute { recipients.setMuted(recipientId, until) } + } + /** * Copies the selected content to the clipboard. Maybe will emit either the copied contents or * a complete which means there were no contents to be copied. diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt index 4ff511e927..821f5b4a1a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt @@ -15,6 +15,7 @@ import io.reactivex.rxjava3.core.Maybe import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.disposables.CompositeDisposable +import io.reactivex.rxjava3.kotlin.addTo import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.kotlin.subscribeBy import io.reactivex.rxjava3.processors.PublishProcessor @@ -221,6 +222,14 @@ class ConversationViewModel( } } + fun muteConversation(until: Long) { + recipient.firstOrError() + .subscribeBy { + repository.setConversationMuted(it.id, until) + } + .addTo(disposables) + } + fun requestMarkRead(timestamp: Long) { } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java index beb87dd1bf..2f63505ffc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java @@ -840,6 +840,13 @@ public class Recipient { return lastProfileFetch; } + /** + * Denotes that this Recipient represents another person. + */ + public boolean isIndividual() { + return !isGroup() && !isCallLink() && !isDistributionList() && !isReleaseNotes(); + } + public boolean isGroup() { return resolve().groupId != null; }