Fix broadcast send when user sends to both story and non-story.

fork-5.53.8
Alex Hart 2022-03-24 14:09:39 -03:00 zatwierdzone przez Greyson Parrelli
rodzic 6e9a6283fc
commit 6c3baf229c
7 zmienionych plików z 88 dodań i 16 usunięć

Wyświetl plik

@ -38,6 +38,7 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.scribbles.ImageEditorFragment
import org.thoughtcrime.securesms.sms.MessageSender
import org.thoughtcrime.securesms.sms.MessageSender.PreUploadResult
import org.thoughtcrime.securesms.sms.OutgoingStoryMessage
import org.thoughtcrime.securesms.util.MessageUtil
import java.util.Collections
import java.util.concurrent.TimeUnit
@ -254,12 +255,19 @@ class MediaSelectionRepository(context: Context) {
}
}
storyMessages.forEach { (preUploadResult, messages) ->
MessageSender.sendMediaBroadcast(context, messages, Collections.singleton(preUploadResult))
}
if (broadcastMessages.isNotEmpty()) {
MessageSender.sendMediaBroadcast(context, broadcastMessages, preUploadResults)
MessageSender.sendMediaBroadcast(
context,
broadcastMessages,
preUploadResults,
storyMessages.flatMap { (preUploadResult, messages) ->
messages.map { OutgoingStoryMessage(it, preUploadResult) }
}
)
} else {
storyMessages.forEach { (preUploadResult, messages) ->
MessageSender.sendMediaBroadcast(context, messages, Collections.singleton(preUploadResult), Collections.emptyList())
}
}
}
}

Wyświetl plik

@ -204,7 +204,11 @@ public class MessageSender {
}
}
public static void sendMediaBroadcast(@NonNull Context context, @NonNull List<OutgoingSecureMediaMessage> messages, @NonNull Collection<PreUploadResult> preUploadResults) {
public static void sendMediaBroadcast(@NonNull Context context,
@NonNull List<OutgoingSecureMediaMessage> messages,
@NonNull Collection<PreUploadResult> preUploadResults,
@NonNull List<OutgoingStoryMessage> storyMessages)
{
Log.i(TAG, "Sending media broadcast to " + Stream.of(messages).map(m -> m.getRecipient().getId()).toList());
Preconditions.checkArgument(messages.size() > 0, "No messages!");
Preconditions.checkArgument(Stream.of(messages).allMatch(m -> m.getAttachments().isEmpty()), "Messages can't have attachments! They should be pre-uploaded.");
@ -230,12 +234,13 @@ public class MessageSender {
attachmentDatabase.updateMessageId(preUploadAttachmentIds, primaryMessageId, primaryMessage.getStoryType().isStory());
messageIds.add(primaryMessageId);
List<DatabaseAttachment> preUploadAttachments = Stream.of(preUploadAttachmentIds)
.map(attachmentDatabase::getAttachment)
.toList();
if (messages.size() > 0) {
List<OutgoingSecureMediaMessage> secondaryMessages = messages.subList(1, messages.size());
List<List<AttachmentId>> attachmentCopies = new ArrayList<>();
List<DatabaseAttachment> preUploadAttachments = Stream.of(preUploadAttachmentIds)
.map(attachmentDatabase::getAttachment)
.toList();
for (int i = 0; i < preUploadAttachmentIds.size(); i++) {
attachmentCopies.add(new ArrayList<>(messages.size()));
@ -266,6 +271,34 @@ public class MessageSender {
}
}
for (final OutgoingStoryMessage storyMessage : storyMessages) {
OutgoingSecureMediaMessage message = storyMessage.getOutgoingSecureMediaMessage();
if (!message.getStoryType().isStory()) {
throw new AssertionError("Only story messages can be sent via this method.");
}
long allocatedThreadId = threadDatabase.getOrCreateThreadIdFor(message.getRecipient(), message.getDistributionType());
long messageId = mmsDatabase.insertMessageOutbox(storyMessage.getOutgoingSecureMediaMessage(), allocatedThreadId, false, null);
Optional<DatabaseAttachment> preUploadAttachment = preUploadAttachments.stream()
.filter(a -> a.getAttachmentId().equals(storyMessage.getPreUploadResult().getAttachmentId()))
.findFirst();
if (!preUploadAttachment.isPresent()) {
Log.w(TAG, "Dropping story message without pre-upload attachment.");
mmsDatabase.markAsSentFailed(messageId);
} else {
AttachmentId attachmentCopyId = attachmentDatabase.insertAttachmentForPreUpload(preUploadAttachment.get()).getAttachmentId();
attachmentDatabase.updateMessageId(Collections.singletonList(attachmentCopyId), messageId, true);
messageIds.add(messageId);
messages.add(storyMessage.getOutgoingSecureMediaMessage());
Job copyJob = new AttachmentCopyJob(storyMessage.getPreUploadResult().getAttachmentId(), Collections.singletonList(attachmentCopyId));
jobManager.add(copyJob, preUploadJobIds);
messageDependsOnIds.add(copyJob.getId());
}
}
for (int i = 0; i < messageIds.size(); i++) {
long messageId = messageIds.get(i);
OutgoingSecureMediaMessage message = messages.get(i);

Wyświetl plik

@ -0,0 +1,8 @@
package org.thoughtcrime.securesms.sms
import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage
class OutgoingStoryMessage(
val outgoingSecureMediaMessage: OutgoingSecureMediaMessage,
val preUploadResult: MessageSender.PreUploadResult
)

Wyświetl plik

@ -28,8 +28,8 @@ class StoryPost(
override fun isVideo(): Boolean = MediaUtil.isVideo(attachment)
}
class TextContent(uri: Uri, val recordId: Long) : Content(uri) {
override val transferState: Int = AttachmentDatabase.TRANSFER_PROGRESS_DONE
class TextContent(uri: Uri, val recordId: Long, hasBody: Boolean) : Content(uri) {
override val transferState: Int = if (hasBody) AttachmentDatabase.TRANSFER_PROGRESS_DONE else AttachmentDatabase.TRANSFER_PROGRESS_FAILED
override fun isVideo(): Boolean = false
}

Wyświetl plik

@ -14,12 +14,14 @@ import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.MessageId
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.databaseprotos.StoryTextPost
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob
import org.thoughtcrime.securesms.jobs.MultiDeviceViewedUpdateJob
import org.thoughtcrime.securesms.jobs.SendViewedReceiptJob
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.Base64
class StoryViewerPageRepository(context: Context) {
@ -175,7 +177,8 @@ class StoryViewerPageRepository(context: Context) {
return if (record.storyType.isTextStory || record.slideDeck.asAttachments().isEmpty()) {
StoryPost.Content.TextContent(
uri = Uri.parse("story_text_post://${record.id}"),
recordId = record.id
recordId = record.id,
hasBody = canParseToTextStory(record.body)
)
} else {
StoryPost.Content.AttachmentContent(
@ -183,4 +186,17 @@ class StoryViewerPageRepository(context: Context) {
)
}
}
private fun canParseToTextStory(body: String): Boolean {
return if (body.isNotEmpty()) {
try {
StoryTextPost.parseFrom(Base64.decode(body))
return true
} catch (e: Exception) {
false
}
} else {
false
}
}
}

Wyświetl plik

@ -66,10 +66,10 @@ class StoryTextPostPreviewFragment : Fragment(R.layout.stories_text_post_preview
} else {
storyTextPostView.setLinkPreviewClickListener(null)
}
requireActivity().supportStartPostponedEnterTransition()
loadPreview(storyTextThumb, storyTextPostView)
}
StoryTextPostState.LoadState.FAILED -> {
requireActivity().supportStartPostponedEnterTransition()
requireListener<MediaPreviewFragment.Events>().mediaNotAvailable()
}
}

Wyświetl plik

@ -19,12 +19,19 @@ class StoryTextPostViewModel(recordId: Long, repository: StoryTextPostRepository
init {
disposables += repository.getRecord(recordId)
.map {
if (it.body.isNotEmpty()) {
StoryTextPost.parseFrom(Base64.decode(it.body)) to it.linkPreviews.firstOrNull()
} else {
throw Exception("Text post message body is empty.")
}
}
.subscribeBy(
onSuccess = { record ->
onSuccess = { (post, previews) ->
store.update { state ->
state.copy(
storyTextPost = StoryTextPost.parseFrom(Base64.decode(record.body)),
linkPreview = record.linkPreviews.firstOrNull(),
storyTextPost = post,
linkPreview = previews,
loadState = StoryTextPostState.LoadState.LOADED
)
}