Safety number check and profile refresh for group sends.

fork-5.53.8
Alex Hart 2022-03-30 09:25:36 -03:00 zatwierdzone przez Cody Henthorne
rodzic 14849d6e45
commit 76a9342afa
2 zmienionych plików z 98 dodań i 31 usunięć

Wyświetl plik

@ -11,17 +11,25 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.kotlin.subscribeBy
import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.emoji.MediaKeyboard
import org.thoughtcrime.securesms.components.mention.MentionAnnotation
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
import org.thoughtcrime.securesms.components.settings.configure
import org.thoughtcrime.securesms.conversation.colors.Colorizer
import org.thoughtcrime.securesms.conversation.ui.error.SafetyNumberChangeDialog
import org.thoughtcrime.securesms.conversation.ui.mentions.MentionsPickerFragment
import org.thoughtcrime.securesms.conversation.ui.mentions.MentionsPickerViewModel
import org.thoughtcrime.securesms.database.model.Mention
import org.thoughtcrime.securesms.jobs.RetrieveProfileJob
import org.thoughtcrime.securesms.keyboard.KeyboardPage
import org.thoughtcrime.securesms.keyboard.KeyboardPagerViewModel
import org.thoughtcrime.securesms.keyboard.emoji.EmojiKeyboardCallback
import org.thoughtcrime.securesms.mediasend.v2.UntrustedRecords
import org.thoughtcrime.securesms.reactions.any.ReactWithAnyEmojiBottomSheetDialogFragment
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
@ -51,7 +59,8 @@ class StoryGroupReplyFragment :
BottomSheetBehaviorDelegate,
StoryReplyComposer.Callback,
EmojiKeyboardCallback,
ReactWithAnyEmojiBottomSheetDialogFragment.Callback {
ReactWithAnyEmojiBottomSheetDialogFragment.Callback,
SafetyNumberChangeDialog.Callback {
private val viewModel: StoryGroupReplyViewModel by viewModels(
factoryProducer = {
@ -81,6 +90,10 @@ class StoryGroupReplyFragment :
private lateinit var composer: StoryReplyComposer
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
SignalExecutors.BOUNDED.execute {
RetrieveProfileJob.enqueue(groupRecipientId)
}
recyclerView = view.findViewById(R.id.recycler)
composer = view.findViewById(R.id.composer)
@ -194,9 +207,12 @@ class StoryGroupReplyFragment :
recyclerView.isNestedScrollingEnabled = child == StoryViewsAndRepliesPagerParent.Child.REPLIES
}
private var resendBody: CharSequence? = null
private var resendMentions: List<Mention> = emptyList()
override fun onSendActionClicked() {
val (body, mentions) = composer.consumeInput()
lifecycleDisposable += StoryGroupReplySender.sendReply(requireContext(), storyId, body, mentions).subscribe()
performSend(body, mentions)
}
override fun onPickReactionClicked() {
@ -299,6 +315,8 @@ class StoryGroupReplyFragment :
}
companion object {
private val TAG = Log.tag(StoryGroupReplyFragment::class.java)
private const val ARG_STORY_ID = "arg.story.id"
private const val ARG_GROUP_RECIPIENT_ID = "arg.group.recipient.id"
@ -312,6 +330,43 @@ class StoryGroupReplyFragment :
}
}
private fun performSend(body: CharSequence, mentions: List<Mention>) {
lifecycleDisposable += StoryGroupReplySender.sendReply(requireContext(), storyId, body, mentions)
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy(
onError = {
if (it is UntrustedRecords.UntrustedRecordsException) {
resendBody = body
resendMentions = mentions
SafetyNumberChangeDialog.show(childFragmentManager, it.untrustedRecords)
} else {
Log.w(TAG, "Failed to send reply", it)
val context = context
if (context != null) {
Toast.makeText(context, R.string.message_details_recipient__failed_to_send, Toast.LENGTH_SHORT).show()
}
}
}
)
}
override fun onSendAnywayAfterSafetyNumberChange(changedRecipients: MutableList<RecipientId>) {
val resendBody = resendBody
if (resendBody != null) {
performSend(resendBody, resendMentions)
}
}
override fun onMessageResentAfterSafetyNumberChange() {
error("Should never get here.")
}
override fun onCanceled() {
resendBody = null
resendMentions = emptyList()
}
interface Callback {
fun onStartDirectReply(recipientId: RecipientId)
}

Wyświetl plik

@ -2,11 +2,14 @@ package org.thoughtcrime.securesms.stories.viewer.reply.group
import android.content.Context
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.Mention
import org.thoughtcrime.securesms.database.model.ParentStoryId
import org.thoughtcrime.securesms.database.model.StoryType
import org.thoughtcrime.securesms.mediasend.v2.UntrustedRecords
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage
import org.thoughtcrime.securesms.sms.MessageSender
@ -24,38 +27,47 @@ object StoryGroupReplySender {
}
private fun sendInternal(context: Context, storyId: Long, body: CharSequence, mentions: List<Mention>, isReaction: Boolean): Completable {
return Completable.create {
val messageAndRecipient = Single.fromCallable {
val message = SignalDatabase.mms.getMessageRecord(storyId)
val recipient = SignalDatabase.threads.getRecipientForThreadId(message.threadId)!!
MessageSender.send(
context,
OutgoingMediaMessage(
recipient,
body.toString(),
emptyList(),
System.currentTimeMillis(),
0,
0L,
false,
0,
StoryType.NONE,
ParentStoryId.GroupReply(message.id),
isReaction,
null,
emptyList(),
emptyList(),
mentions,
emptySet(),
emptySet()
),
message.threadId,
false,
null
) {
it.onComplete()
}
message to recipient
}
return messageAndRecipient.flatMapCompletable { (message, recipient) ->
UntrustedRecords.checkForBadIdentityRecords(setOf(ContactSearchKey.KnownRecipient(recipient.id)))
.andThen(
Completable.create {
MessageSender.send(
context,
OutgoingMediaMessage(
recipient,
body.toString(),
emptyList(),
System.currentTimeMillis(),
0,
0L,
false,
0,
StoryType.NONE,
ParentStoryId.GroupReply(message.id),
isReaction,
null,
emptyList(),
emptyList(),
mentions,
emptySet(),
emptySet()
),
message.threadId,
false,
null
) {
it.onComplete()
}
}
)
}.subscribeOn(Schedulers.io())
}
}