Merge MediaMmsMessageRecord into MmsMessageRecord.

This commit is contained in:
Greyson Parrelli 2023-11-12 12:47:26 -05:00
parent 5f6fa73be9
commit 2f52664820
41 changed files with 407 additions and 473 deletions

View file

@ -10,7 +10,7 @@ import org.thoughtcrime.securesms.conversation.v2.data.ConversationElementKey
import org.thoughtcrime.securesms.conversation.v2.data.IncomingTextOnly
import org.thoughtcrime.securesms.conversation.v2.data.OutgoingTextOnly
import org.thoughtcrime.securesms.database.MessageTypes
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.StoryType
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.mms.SlideDeck
@ -78,7 +78,7 @@ class ConversationElementGenerator {
val isIncoming = random.nextBoolean()
val record = MediaMmsMessageRecord(
val record = MmsMessageRecord(
messageId,
if (isIncoming) Recipient.UNKNOWN else Recipient.self(),
0,

View file

@ -30,9 +30,8 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.animation.AnimationCompleteListener;
import org.thoughtcrime.securesms.conversation.ConversationItemDisplayMode;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.recipients.Recipient;
@ -318,7 +317,7 @@ public class ConversationItemFooter extends ConstraintLayout {
} else if (messageRecord.isRateLimited()) {
dateView.setText(R.string.ConversationItem_send_paused);
} else if (MessageRecordUtil.isScheduled(messageRecord)) {
dateView.setText(DateUtils.getOnlyTimeString(getContext(), locale, ((MediaMmsMessageRecord) messageRecord).getScheduledDate()));
dateView.setText(DateUtils.getOnlyTimeString(getContext(), locale, ((MmsMessageRecord) messageRecord).getScheduledDate()));
} else {
long timestamp = messageRecord.getTimestamp();
if (messageRecord.isEditMessage()) {

View file

@ -49,7 +49,7 @@ import org.thoughtcrime.securesms.conversation.ConversationStickerSuggestionAdap
import org.thoughtcrime.securesms.conversation.MessageStyler;
import org.thoughtcrime.securesms.conversation.VoiceNoteDraftView;
import org.thoughtcrime.securesms.database.DraftTable;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageId;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.Quote;
@ -423,10 +423,10 @@ public class InputPanel extends ConstraintLayout
}
private void updateEditModeThumbnail(@NonNull GlideRequests glideRequests) {
if (messageToEdit instanceof MediaMmsMessageRecord) {
MediaMmsMessageRecord mediaEditMessage = (MediaMmsMessageRecord) messageToEdit;
SlideDeck slideDeck = mediaEditMessage.getSlideDeck();
Slide imageVideoSlide = slideDeck.getSlides().stream().filter(s -> s.hasImage() || s.hasVideo() || s.hasSticker()).findFirst().orElse(null);
if (messageToEdit instanceof MmsMessageRecord) {
MmsMessageRecord mediaEditMessage = (MmsMessageRecord) messageToEdit;
SlideDeck slideDeck = mediaEditMessage.getSlideDeck();
Slide imageVideoSlide = slideDeck.getSlides().stream().filter(s -> s.hasImage() || s.hasVideo() || s.hasSticker()).findFirst().orElse(null);
if (imageVideoSlide != null && imageVideoSlide.getUri() != null) {
editMessageThumbnail.setVisibility(VISIBLE);

View file

@ -46,7 +46,7 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.conversation.colors.Colorizable;
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4Playable;
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicyEnforcer;
@ -326,7 +326,7 @@ public class ConversationAdapter
if (conversationMessage == null) return -1;
if (displayMode.getScheduleMessageMode()) {
calendar.setTimeInMillis(((MediaMmsMessageRecord) conversationMessage.getMessageRecord()).getScheduledDate());
calendar.setTimeInMillis(((MmsMessageRecord) conversationMessage.getMessageRecord()).getScheduledDate());
} else if (displayMode == ConversationItemDisplayMode.EditHistory.INSTANCE) {
calendar.setTimeInMillis(conversationMessage.getMessageRecord().getDateSent());
} else {
@ -346,7 +346,7 @@ public class ConversationAdapter
ConversationMessage conversationMessage = Objects.requireNonNull(getItem(position));
if (displayMode.getScheduleMessageMode()) {
viewHolder.setText(DateUtils.getScheduledMessagesDateHeaderString(viewHolder.itemView.getContext(), locale, ((MediaMmsMessageRecord) conversationMessage.getMessageRecord()).getScheduledDate()));
viewHolder.setText(DateUtils.getScheduledMessagesDateHeaderString(viewHolder.itemView.getContext(), locale, ((MmsMessageRecord) conversationMessage.getMessageRecord()).getScheduledDate()));
} else if (displayMode == ConversationItemDisplayMode.EditHistory.INSTANCE) {
viewHolder.setText(DateUtils.getConversationDateHeaderString(viewHolder.itemView.getContext(), locale, conversationMessage.getMessageRecord().getDateSent()));
} else {

View file

@ -105,9 +105,8 @@ import org.thoughtcrime.securesms.database.AttachmentTable;
import org.thoughtcrime.securesms.database.MediaTable;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.Quote;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.events.PartProgressEvent;
@ -1132,7 +1131,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
if (joinCallLinkStub.resolved()) joinCallLinkStub.get().setVisibility(View.GONE);
paymentViewStub.setVisibility(View.GONE);
sharedContactStub.get().setContact(((MediaMmsMessageRecord) messageRecord).getSharedContacts().get(0), glideRequests, locale);
sharedContactStub.get().setContact(((MmsMessageRecord) messageRecord).getSharedContacts().get(0), glideRequests, locale);
sharedContactStub.get().setEventListener(sharedContactEventListener);
sharedContactStub.get().setOnClickListener(sharedContactClickListener);
sharedContactStub.get().setOnLongClickListener(passthroughClickListener);
@ -1219,7 +1218,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
if (joinCallLinkStub.resolved()) joinCallLinkStub.get().setVisibility(View.GONE);
paymentViewStub.setVisibility(View.GONE);
audioViewStub.get().setAudio(Objects.requireNonNull(((MediaMmsMessageRecord) messageRecord).getSlideDeck().getAudioSlide()), new AudioViewCallbacks(), showControls, true);
audioViewStub.get().setAudio(Objects.requireNonNull(((MmsMessageRecord) messageRecord).getSlideDeck().getAudioSlide()), new AudioViewCallbacks(), showControls, true);
audioViewStub.get().setDownloadClickListener(singleDownloadClickListener);
audioViewStub.get().setOnLongClickListener(passthroughClickListener);
@ -1249,7 +1248,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
//noinspection ConstantConditions
documentViewStub.get().setDocument(
((MediaMmsMessageRecord) messageRecord).getSlideDeck().getDocumentSlide(),
((MmsMessageRecord) messageRecord).getSlideDeck().getDocumentSlide(),
showControls,
displayMode != ConversationItemDisplayMode.Detailed.INSTANCE
);
@ -1381,7 +1380,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
if (giftViewStub.resolved()) giftViewStub.get().setVisibility(View.GONE);
if (joinCallLinkStub.resolved()) joinCallLinkStub.get().setVisibility(View.GONE);
MediaMmsMessageRecord mediaMmsMessageRecord = (MediaMmsMessageRecord) messageRecord;
MmsMessageRecord mediaMmsMessageRecord = (MmsMessageRecord) messageRecord;
paymentViewStub.setVisibility(View.VISIBLE);
paymentViewStub.get().bindPayment(conversationRecipient.get(), Objects.requireNonNull(mediaMmsMessageRecord.getPayment()), colorizer);
@ -1592,9 +1591,9 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
if (quoteView == null) {
throw new AssertionError();
}
Quote quote = ((MediaMmsMessageRecord) current).getQuote();
Quote quote = ((MmsMessageRecord) current).getQuote();
if (((MediaMmsMessageRecord) current).getParentStoryId() != null) {
if (((MmsMessageRecord) current).getParentStoryId() != null) {
quoteView.setMessageType(current.isOutgoing() ? QuoteView.MessageType.STORY_REPLY_OUTGOING : QuoteView.MessageType.STORY_REPLY_INCOMING);
} else {
quoteView.setMessageType(current.isOutgoing() ? QuoteView.MessageType.OUTGOING : QuoteView.MessageType.INCOMING);

View file

@ -17,7 +17,7 @@ import org.thoughtcrime.securesms.database.BodyRangeUtil;
import org.thoughtcrime.securesms.database.MentionUtil;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.Mention;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList;
@ -161,7 +161,7 @@ public class ConversationMessage {
}
public static @NonNull FormattedDate getFormattedDate(@NonNull Context context, @NonNull MessageRecord messageRecord) {
return MessageRecordUtil.isScheduled(messageRecord) ? new FormattedDate(false, DateUtils.getOnlyTimeString(context, Locale.getDefault(), ((MediaMmsMessageRecord) messageRecord).getScheduledDate()))
return MessageRecordUtil.isScheduled(messageRecord) ? new FormattedDate(false, DateUtils.getOnlyTimeString(context, Locale.getDefault(), ((MmsMessageRecord) messageRecord).getScheduledDate()))
: DateUtils.getDatelessRelativeTimeSpanFormattedDate(context, Locale.getDefault(), messageRecord.getTimestamp());
}

View file

@ -3,9 +3,8 @@ package org.thoughtcrime.securesms.conversation;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.MessageRecordUtil;
import org.thoughtcrime.securesms.util.MessageConstraintsUtil;
@ -167,15 +166,15 @@ public final class MenuState {
MessageRecord messageRecord = multiSelectRecord.getMessageRecord();
builder.shouldShowResendAction(messageRecord.isFailed())
.shouldShowSaveAttachmentAction(mediaIsSelected &&
!actionMessage &&
!viewOnce &&
messageRecord.isMms() &&
!hasPendingMedia &&
!hasGift &&
!messageRecord.isMmsNotification() &&
((MediaMmsMessageRecord)messageRecord).containsMediaSlide() &&
((MediaMmsMessageRecord)messageRecord).getSlideDeck().getStickerSlide() == null)
.shouldShowSaveAttachmentAction(mediaIsSelected &&
!actionMessage &&
!viewOnce &&
messageRecord.isMms() &&
!hasPendingMedia &&
!hasGift &&
!messageRecord.isMmsNotification() &&
((MmsMessageRecord)messageRecord).containsMediaSlide() &&
((MmsMessageRecord)messageRecord).getSlideDeck().getStickerSlide() == null)
.shouldShowForwardAction(shouldShowForwardAction)
.shouldShowDetailsAction(!actionMessage && !conversationRecipient.isReleaseNotes())
.shouldShowReplyAction(canReplyToMessage(conversationRecipient, actionMessage, messageRecord, shouldShowMessageRequest, isNonAdminInAnnouncementGroup));

View file

@ -29,7 +29,6 @@ import org.thoughtcrime.securesms.conversation.colors.RecyclerViewColorizer
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart.Attachments
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4ItemDecoration
@ -167,7 +166,7 @@ class ScheduledMessagesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment
}
private fun handleRescheduleMessage(messageRecord: MessageRecord) {
ScheduleMessageTimePickerBottomSheet.showReschedule(childFragmentManager, messageRecord.id, (messageRecord as MediaMmsMessageRecord).scheduledDate)
ScheduleMessageTimePickerBottomSheet.showReschedule(childFragmentManager, messageRecord.id, (messageRecord as MmsMessageRecord).scheduledDate)
}
private fun handleSendMessageNow(messageRecord: MessageRecord) {

View file

@ -24,10 +24,10 @@ import org.thoughtcrime.securesms.database.MessageTypes
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.ThreadTable
import org.thoughtcrime.securesms.database.adjustBodyRanges
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.Mention
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.BodyRangeList
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.keyboard.KeyboardUtil
@ -207,7 +207,7 @@ class DraftRepository(
private fun loadDraftQuoteInternal(serialized: String): ConversationMessage? {
val quoteId: QuoteId = QuoteId.deserialize(context, serialized) ?: return null
val messageRecord: MessageRecord = SignalDatabase.messages.getMessageFor(quoteId.id, quoteId.author)?.let {
if (it is MediaMmsMessageRecord) {
if (it is MmsMessageRecord) {
it.withAttachments(SignalDatabase.attachments.getAttachmentsForMessage(it.id))
} else {
it

View file

@ -10,9 +10,9 @@ import org.thoughtcrime.securesms.conversation.v2.data.AttachmentHelper
import org.thoughtcrime.securesms.conversation.v2.data.ReactionHelper
import org.thoughtcrime.securesms.database.DatabaseObserver
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
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.Quote
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.util.getQuote
@ -74,7 +74,7 @@ class MessageQuotesRepository {
.map { replyRecord ->
val replyQuote: Quote? = replyRecord.getQuote()
if (replyQuote != null && replyQuote.id == originalRecord!!.dateSent) {
(replyRecord as MediaMmsMessageRecord).withoutQuote()
(replyRecord as MmsMessageRecord).withoutQuote()
} else {
replyRecord
}

View file

@ -194,7 +194,6 @@ import org.thoughtcrime.securesms.conversation.v2.keyboard.AttachmentKeyboardFra
import org.thoughtcrime.securesms.database.DraftTable
import org.thoughtcrime.securesms.database.model.IdentityRecord
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.Mention
import org.thoughtcrime.securesms.database.model.MessageId
import org.thoughtcrime.securesms.database.model.MessageRecord
@ -1990,7 +1989,7 @@ class ConversationFragment :
if (menuState.shouldShowSaveAttachmentAction()) {
items.add(
ActionItem(R.drawable.symbol_save_android_24, getResources().getString(R.string.conversation_selection__menu_save)) {
handleSaveAttachment(getSelectedConversationMessage().messageRecord as MediaMmsMessageRecord)
handleSaveAttachment(getSelectedConversationMessage().messageRecord as MmsMessageRecord)
actionMode?.finish()
}
)
@ -2166,7 +2165,7 @@ class ConversationFragment :
}
}
private fun handleSaveAttachment(record: MediaMmsMessageRecord) {
private fun handleSaveAttachment(record: MmsMessageRecord) {
if (record.isViewOnce) {
error("Cannot save a view-once message")
}
@ -2219,7 +2218,7 @@ class ConversationFragment :
}
private fun handleViewPaymentDetails(conversationMessage: ConversationMessage) {
val record: MediaMmsMessageRecord = conversationMessage.messageRecord as? MediaMmsMessageRecord ?: return
val record: MmsMessageRecord = conversationMessage.messageRecord as? MmsMessageRecord ?: return
val payment = record.payment ?: return
if (record.isPaymentNotification) {
startActivity(PaymentsActivity.navigateToPaymentDetails(requireContext(), payment.uuid))
@ -3295,7 +3294,7 @@ class ConversationFragment :
ConversationReactionOverlay.Action.EDIT -> handleEditMessage(conversationMessage)
ConversationReactionOverlay.Action.FORWARD -> handleForwardMessageParts(conversationMessage.multiselectCollection.toSet())
ConversationReactionOverlay.Action.RESEND -> handleResend(conversationMessage)
ConversationReactionOverlay.Action.DOWNLOAD -> handleSaveAttachment(conversationMessage.messageRecord as MediaMmsMessageRecord)
ConversationReactionOverlay.Action.DOWNLOAD -> handleSaveAttachment(conversationMessage.messageRecord as MmsMessageRecord)
ConversationReactionOverlay.Action.COPY -> handleCopyMessage(conversationMessage.multiselectCollection.toSet())
ConversationReactionOverlay.Action.MULTISELECT -> handleEnterMultiselect(conversationMessage)
ConversationReactionOverlay.Action.PAYMENT_DETAILS -> handleViewPaymentDetails(conversationMessage)

View file

@ -14,7 +14,7 @@ import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.conversation.v2.data.ConversationMessageElement
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.util.DateUtils
import org.thoughtcrime.securesms.util.adapter.mapping.MappingModel
import org.thoughtcrime.securesms.util.drawAsTopItemDecoration
@ -210,7 +210,7 @@ class ConversationItemDecorations(hasWallpaper: Boolean = false, private val sch
private fun ConversationMessageElement.timestamp(): Long {
return if (scheduleMessageMode) {
(conversationMessage.messageRecord as MediaMmsMessageRecord).scheduledDate
(conversationMessage.messageRecord as MmsMessageRecord).scheduledDate
} else {
conversationMessage.conversationTimestamp
}

View file

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.util.Util;
@ -41,11 +41,11 @@ public class AttachmentHelper {
public @NonNull List<MessageRecord> buildUpdatedModels(@NonNull Context context, @NonNull List<MessageRecord> records) {
return records.stream()
.map(record -> {
if (record instanceof MediaMmsMessageRecord) {
if (record instanceof MmsMessageRecord) {
List<DatabaseAttachment> attachments = messageIdToAttachments.get(record.getId());
if (Util.hasItems(attachments)) {
return ((MediaMmsMessageRecord) record).withAttachments(attachments);
return ((MmsMessageRecord) record).withAttachments(attachments);
}
}

View file

@ -18,8 +18,8 @@ import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord.NoGroupsInCommon
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord.RemovedContactHidden
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord.UniversalExpireTimerUpdate
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.messagerequests.MessageRequestRepository
import org.thoughtcrime.securesms.recipients.Recipient
@ -169,11 +169,11 @@ class ConversationDataSource(
val stopwatch = Stopwatch(title = "load($key), thread $threadId", decimalPlaces = 2)
var record = SignalDatabase.messages.getMessageRecordOrNull(key.id)
if ((record as? MediaMmsMessageRecord)?.parentStoryId?.isGroupReply() == true) {
if ((record as? MmsMessageRecord)?.parentStoryId?.isGroupReply() == true) {
return null
}
val scheduleDate = (record as? MediaMmsMessageRecord)?.scheduledDate
val scheduleDate = (record as? MmsMessageRecord)?.scheduledDate
if (scheduleDate != null && scheduleDate != -1L) {
return null
}

View file

@ -3,8 +3,7 @@ package org.thoughtcrime.securesms.conversation.v2.data;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageId;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.ReactionRecord;
import org.thoughtcrime.securesms.util.Util;
@ -47,8 +46,8 @@ public class ReactionHelper {
public static @NonNull MessageRecord recordWithReactions(@NonNull MessageRecord record, List<ReactionRecord> reactions) {
if (Util.hasItems(reactions)) {
if (record instanceof MediaMmsMessageRecord) {
return ((MediaMmsMessageRecord) record).withReactions(reactions);
if (record instanceof MmsMessageRecord) {
return ((MmsMessageRecord) record).withReactions(reactions);
} else {
throw new IllegalStateException("We have reactions for an unsupported record type: " + record.getClass().getName());
}

View file

@ -9,7 +9,7 @@ import android.util.TypedValue
import android.view.View
import org.thoughtcrime.securesms.components.QuoteView
import org.thoughtcrime.securesms.conversation.v2.data.ConversationMessageElement
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.adapter.mapping.MappingModel
@ -140,7 +140,7 @@ class V2ConversationItemMediaViewHolder<Model : MappingModel<Model>>(
return hasThumbnail() || hasQuote()
}
private fun requireMediaMessage(): MediaMmsMessageRecord {
return conversationMessage.messageRecord as MediaMmsMessageRecord
private fun requireMediaMessage(): MmsMessageRecord {
return conversationMessage.messageRecord as MmsMessageRecord
}
}

View file

@ -36,8 +36,8 @@ import org.thoughtcrime.securesms.conversation.mutiselect.Multiselect
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart
import org.thoughtcrime.securesms.conversation.mutiselect.Multiselectable
import org.thoughtcrime.securesms.conversation.v2.data.ConversationMessageElement
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.recipients.RecipientId
@ -642,7 +642,7 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
binding.footerDate.text = conversationMessage.computedProperties.formattedDate.value
} else {
var date = dateString
if (conversationContext.displayMode != ConversationItemDisplayMode.Detailed && record is MediaMmsMessageRecord && record.isEditMessage()) {
if (conversationContext.displayMode != ConversationItemDisplayMode.Detailed && record is MmsMessageRecord && record.isEditMessage()) {
date = getContext().getString(R.string.ConversationItem_edited_timestamp_footer, date)
binding.footerDate.setOnClickListener {

View file

@ -24,7 +24,7 @@ import com.bumptech.glide.request.transition.Transition
import org.signal.core.util.dp
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.conversation.v2.items.V2ConversationItemUtils.isThumbnailAtBottomOfBubble
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader
import org.thoughtcrime.securesms.mms.Slide
@ -92,7 +92,7 @@ class V2ConversationItemThumbnail @JvmOverloads constructor(
}
fun presentThumbnail(
mediaMessage: MediaMmsMessageRecord,
mediaMessage: MmsMessageRecord,
conversationContext: V2ConversationContext
) {
val slideDeck = mediaMessage.slideDeck

View file

@ -89,7 +89,6 @@ import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchSet
import org.thoughtcrime.securesms.database.documents.NetworkFailure
import org.thoughtcrime.securesms.database.documents.NetworkFailureSet
import org.thoughtcrime.securesms.database.model.GroupCallUpdateDetailsUtil
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.Mention
import org.thoughtcrime.securesms.database.model.MessageExportStatus
import org.thoughtcrime.securesms.database.model.MessageId
@ -964,7 +963,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
}
}
fun insertEditMessageInbox(mediaMessage: IncomingMessage, targetMessage: MediaMmsMessageRecord): Optional<InsertResult> {
fun insertEditMessageInbox(mediaMessage: IncomingMessage, targetMessage: MmsMessageRecord): Optional<InsertResult> {
val insertResult = insertMessageInbox(retrieved = mediaMessage, editedMessage = targetMessage, notifyObservers = false)
if (insertResult.isPresent) {
@ -1924,7 +1923,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
fun markAsRemoteDelete(targetMessage: MessageRecord) {
writableDatabase.withinTransaction { db ->
if (targetMessage.isEditMessage) {
val latestRevisionId = (targetMessage as? MediaMmsMessageRecord)?.latestRevisionId?.id ?: targetMessage.id
val latestRevisionId = (targetMessage as? MmsMessageRecord)?.latestRevisionId?.id ?: targetMessage.id
markAsRemoteDeleteInternal(latestRevisionId)
getPreviousEditIds(latestRevisionId).map { id ->
db.update(TABLE_NAME)
@ -2445,7 +2444,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
fun insertMessageInbox(
retrieved: IncomingMessage,
candidateThreadId: Long = -1,
editedMessage: MediaMmsMessageRecord? = null,
editedMessage: MmsMessageRecord? = null,
notifyObservers: Boolean = true
): Optional<InsertResult> {
val type = retrieved.toMessageType()
@ -2924,8 +2923,8 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
.where("$ID_WHERE OR $LATEST_REVISION_ID = ?", message.messageToEdit, message.messageToEdit)
.run()
val textAttachments = (editedMessage as? MediaMmsMessageRecord)?.slideDeck?.asAttachments()?.filter { it.contentType == MediaUtil.LONG_TEXT }?.mapNotNull { (it as? DatabaseAttachment)?.attachmentId?.rowId } ?: emptyList()
val linkPreviewAttachments = (editedMessage as? MediaMmsMessageRecord)?.linkPreviews?.mapNotNull { it.attachmentId?.rowId } ?: emptyList()
val textAttachments = (editedMessage as? MmsMessageRecord)?.slideDeck?.asAttachments()?.filter { it.contentType == MediaUtil.LONG_TEXT }?.mapNotNull { (it as? DatabaseAttachment)?.attachmentId?.rowId } ?: emptyList()
val linkPreviewAttachments = (editedMessage as? MmsMessageRecord)?.linkPreviews?.mapNotNull { it.attachmentId?.rowId } ?: emptyList()
val excludeIds = HashSet<Long>()
excludeIds += textAttachments
excludeIds += linkPreviewAttachments
@ -4933,7 +4932,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
return MessageId(cursor.requireLong(ID))
}
private fun getMediaMmsMessageRecord(cursor: Cursor): MediaMmsMessageRecord {
private fun getMediaMmsMessageRecord(cursor: Cursor): MmsMessageRecord {
val id = cursor.requireLong(ID)
val dateSent = cursor.requireLong(DATE_SENT)
val dateReceived = cursor.requireLong(DATE_RECEIVED)
@ -5012,7 +5011,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
null
}
return MediaMmsMessageRecord(
return MmsMessageRecord(
id,
fromRecipient,
fromDeviceId,

View file

@ -18,7 +18,7 @@ import org.signal.core.util.CursorUtil;
import org.signal.core.util.SQLiteDatabaseExtensionsKt;
import org.signal.core.util.SqlUtil;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageId;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.databaseprotos.CryptoValue;
@ -436,8 +436,8 @@ public final class PaymentTable extends DatabaseTable implements RecipientIdData
public @NonNull MessageRecord updateMessageWithPayment(@NonNull MessageRecord record) {
if (record.isPaymentNotification()) {
Payment payment = getPayment(UuidUtil.parseOrThrow(record.getBody()));
if (payment != null && record instanceof MediaMmsMessageRecord) {
return ((MediaMmsMessageRecord) record).withPayment(payment);
if (payment != null && record instanceof MmsMessageRecord) {
return ((MmsMessageRecord) record).withPayment(payment);
} else {
throw new AssertionError("Payment not found for message");
}

View file

@ -38,7 +38,6 @@ import org.thoughtcrime.securesms.database.SignalDatabase.Companion.messageLog
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.messages
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.recipients
import org.thoughtcrime.securesms.database.ThreadBodyUtil.ThreadBody
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.ThreadRecord
@ -1699,7 +1698,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
return null
}
val slideDeck: SlideDeck = (record as MediaMmsMessageRecord).slideDeck
val slideDeck: SlideDeck = (record as MmsMessageRecord).slideDeck
val thumbnail = Optional.ofNullable(slideDeck.thumbnailSlide)
.or(Optional.ofNullable(slideDeck.stickerSlide))
.orElse(null)

View file

@ -1,314 +0,0 @@
/**
* Copyright (C) 2012 Moxie Marlinspike
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms.database.model;
import android.content.Context;
import android.text.SpannableString;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import androidx.core.content.ContextCompat;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.AttachmentId;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.contactshare.Contact;
import org.thoughtcrime.securesms.database.CallTable;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.MessageTable.Status;
import org.thoughtcrime.securesms.database.MessageTypes;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList;
import org.thoughtcrime.securesms.database.model.databaseprotos.GiftBadge;
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.payments.Payment;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.whispersystems.signalservice.api.payments.FormatterOptions;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
* Represents the message record model for MMS messages that contain
* media (ie: they've been downloaded).
*
* @author Moxie Marlinspike
*
*/
public class MediaMmsMessageRecord extends MmsMessageRecord {
private final static String TAG = Log.tag(MediaMmsMessageRecord.class);
private final boolean mentionsSelf;
private final BodyRangeList messageRanges;
private final Payment payment;
private final CallTable.Call call;
private final long scheduledDate;
private final MessageId latestRevisionId;
public MediaMmsMessageRecord(long id,
Recipient fromRecipient,
int fromDeviceId,
Recipient toRecipient,
long dateSent,
long dateReceived,
long dateServer,
int deliveryReceiptCount,
long threadId,
String body,
@NonNull SlideDeck slideDeck,
long mailbox,
Set<IdentityKeyMismatch> mismatches,
Set<NetworkFailure> failures,
int subscriptionId,
long expiresIn,
long expireStarted,
boolean viewOnce,
int readReceiptCount,
@Nullable Quote quote,
@NonNull List<Contact> contacts,
@NonNull List<LinkPreview> linkPreviews,
boolean unidentified,
@NonNull List<ReactionRecord> reactions,
boolean remoteDelete,
boolean mentionsSelf,
long notifiedTimestamp,
int viewedReceiptCount,
long receiptTimestamp,
@Nullable BodyRangeList messageRanges,
@NonNull StoryType storyType,
@Nullable ParentStoryId parentStoryId,
@Nullable GiftBadge giftBadge,
@Nullable Payment payment,
@Nullable CallTable.Call call,
long scheduledDate,
@Nullable MessageId latestRevisionId,
@Nullable MessageId originalMessageId,
int revisionNumber)
{
super(id, body, fromRecipient, fromDeviceId, toRecipient, dateSent,
dateReceived, dateServer, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox, mismatches, failures,
subscriptionId, expiresIn, expireStarted, viewOnce, slideDeck,
readReceiptCount, quote, contacts, linkPreviews, unidentified, reactions, remoteDelete, notifiedTimestamp, viewedReceiptCount, receiptTimestamp,
storyType, parentStoryId, giftBadge, originalMessageId, revisionNumber);
this.mentionsSelf = mentionsSelf;
this.messageRanges = messageRanges;
this.payment = payment;
this.call = call;
this.scheduledDate = scheduledDate;
this.latestRevisionId = latestRevisionId;
}
@Override
public boolean hasSelfMention() {
return mentionsSelf;
}
@Override
public boolean isMmsNotification() {
return false;
}
@Override
@WorkerThread
public SpannableString getDisplayBody(@NonNull Context context) {
if (MessageTypes.isChatSessionRefresh(type)) {
return emphasisAdded(context.getString(R.string.MmsMessageRecord_bad_encrypted_mms_message));
} else if (MessageTypes.isDuplicateMessageType(type)) {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_duplicate_message));
} else if (MessageTypes.isNoRemoteSessionType(type)) {
return emphasisAdded(context.getString(R.string.MmsMessageRecord_mms_message_encrypted_for_non_existing_session));
} else if (isLegacyMessage()) {
return emphasisAdded(context.getString(R.string.MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported));
} else if (isPaymentNotification() && payment != null) {
return new SpannableString(context.getString(R.string.MessageRecord__payment_s, payment.getAmount().toString(FormatterOptions.defaults())));
}
return super.getDisplayBody(context);
}
@Override
public @Nullable UpdateDescription getUpdateDisplayBody(@NonNull Context context, @Nullable Consumer<RecipientId> recipientClickHandler) {
if (isCallLog() && call != null && !(call.getType() == CallTable.Type.GROUP_CALL)) {
boolean accepted = call.getEvent() == CallTable.Event.ACCEPTED;
String callDateString = getCallDateString(context);
if (call.getDirection() == CallTable.Direction.OUTGOING) {
if (call.getType() == CallTable.Type.AUDIO_CALL) {
int updateString = accepted ? R.string.MessageRecord_outgoing_voice_call : R.string.MessageRecord_unanswered_voice_call;
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(updateString), callDateString), R.drawable.ic_update_audio_call_outgoing_16);
} else {
int updateString = accepted ? R.string.MessageRecord_outgoing_video_call : R.string.MessageRecord_unanswered_video_call;
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(updateString), callDateString), R.drawable.ic_update_video_call_outgoing_16);
}
} else {
boolean isVideoCall = call.getType() == CallTable.Type.VIDEO_CALL;
boolean isMissed = call.getEvent() == CallTable.Event.MISSED;
if (accepted) {
int updateString = isVideoCall ? R.string.MessageRecord_incoming_video_call : R.string.MessageRecord_incoming_voice_call;
int icon = isVideoCall ? R.drawable.ic_update_video_call_incoming_16 : R.drawable.ic_update_audio_call_incoming_16;
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(updateString), callDateString), icon);
} else if (isMissed) {
return isVideoCall ? staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_missed_video_call), callDateString), R.drawable.ic_update_video_call_missed_16, ContextCompat.getColor(context, R.color.core_red_shade), ContextCompat.getColor(context, R.color.core_red))
: staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_missed_voice_call), callDateString), R.drawable.ic_update_audio_call_missed_16, ContextCompat.getColor(context, R.color.core_red_shade), ContextCompat.getColor(context, R.color.core_red));
} else {
return isVideoCall ? staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_you_declined_a_video_call), callDateString), R.drawable.ic_update_video_call_incoming_16)
: staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_you_declined_a_voice_call), callDateString), R.drawable.ic_update_audio_call_incoming_16);
}
}
}
return super.getUpdateDisplayBody(context, recipientClickHandler);
}
@Override
public @Nullable BodyRangeList getMessageRanges() {
return messageRanges;
}
@Override
public @NonNull BodyRangeList requireMessageRanges() {
return Objects.requireNonNull(messageRanges);
}
public @Nullable Payment getPayment() {
return payment;
}
public @Nullable CallTable.Call getCall() {
return call;
}
public long getScheduledDate() {
return scheduledDate;
}
public @Nullable MessageId getLatestRevisionId() {
return latestRevisionId;
}
public @NonNull MediaMmsMessageRecord withReactions(@NonNull List<ReactionRecord> reactions) {
return new MediaMmsMessageRecord(getId(), getFromRecipient(), getFromDeviceId(), getToRecipient(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), getSlideDeck(),
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), getQuote(), getSharedContacts(), getLinkPreviews(), isUnidentified(), reactions, isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment(), getCall(), getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
}
public @NonNull MediaMmsMessageRecord withoutQuote() {
return new MediaMmsMessageRecord(getId(), getFromRecipient(), getFromDeviceId(), getToRecipient(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), getSlideDeck(),
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), null, getSharedContacts(), getLinkPreviews(), isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment(), getCall(), getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
}
public @NonNull MediaMmsMessageRecord withAttachments(@NonNull List<DatabaseAttachment> attachments) {
Map<AttachmentId, DatabaseAttachment> attachmentIdMap = new HashMap<>();
for (DatabaseAttachment attachment : attachments) {
attachmentIdMap.put(attachment.getAttachmentId(), attachment);
}
List<Contact> contacts = updateContacts(getSharedContacts(), attachmentIdMap);
Set<Attachment> contactAttachments = contacts.stream().map(Contact::getAvatarAttachment).filter(Objects::nonNull).collect(Collectors.toSet());
List<LinkPreview> linkPreviews = updateLinkPreviews(getLinkPreviews(), attachmentIdMap);
Set<Attachment> linkPreviewAttachments = linkPreviews.stream().map(LinkPreview::getThumbnail).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toSet());
Quote quote = updateQuote(getQuote(), attachments);
List<DatabaseAttachment> slideAttachments = attachments.stream().filter(a -> !contactAttachments.contains(a)).filter(a -> !linkPreviewAttachments.contains(a)).collect(Collectors.toList());
SlideDeck slideDeck = MessageTable.MmsReader.buildSlideDeck(slideAttachments);
return new MediaMmsMessageRecord(getId(), getFromRecipient(), getFromDeviceId(), getToRecipient(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), slideDeck,
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), quote, contacts, linkPreviews, isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment(), getCall(), getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
}
public @NonNull MediaMmsMessageRecord withPayment(@NonNull Payment payment) {
return new MediaMmsMessageRecord(getId(), getFromRecipient(), getFromDeviceId(), getToRecipient(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), getSlideDeck(),
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), getQuote(), getSharedContacts(), getLinkPreviews(), isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), payment, getCall(), getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
}
public @NonNull MediaMmsMessageRecord withCall(@Nullable CallTable.Call call) {
return new MediaMmsMessageRecord(getId(), getFromRecipient(), getFromDeviceId(), getToRecipient(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), getSlideDeck(),
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), getQuote(), getSharedContacts(), getLinkPreviews(), isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment(), call, getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
}
private static @NonNull List<Contact> updateContacts(@NonNull List<Contact> contacts, @NonNull Map<AttachmentId, DatabaseAttachment> attachmentIdMap) {
return contacts.stream()
.map(contact -> {
if (contact.getAvatar() != null) {
DatabaseAttachment attachment = attachmentIdMap.get(contact.getAvatar().getAttachmentId());
Contact.Avatar updatedAvatar = new Contact.Avatar(contact.getAvatar().getAttachmentId(),
attachment,
contact.getAvatar().isProfile());
return new Contact(contact, updatedAvatar);
} else {
return contact;
}
})
.collect(Collectors.toList());
}
private static @NonNull List<LinkPreview> updateLinkPreviews(@NonNull List<LinkPreview> linkPreviews, @NonNull Map<AttachmentId, DatabaseAttachment> attachmentIdMap) {
return linkPreviews.stream()
.map(preview -> {
if (preview.getAttachmentId() != null) {
DatabaseAttachment attachment = attachmentIdMap.get(preview.getAttachmentId());
if (attachment != null) {
return new LinkPreview(preview.getUrl(), preview.getTitle(), preview.getDescription(), preview.getDate(), attachment);
} else {
return preview;
}
} else {
return preview;
}
})
.collect(Collectors.toList());
}
private static @Nullable Quote updateQuote(@Nullable Quote quote, @NonNull List<DatabaseAttachment> attachments) {
if (quote == null) {
return null;
}
List<DatabaseAttachment> quoteAttachments = attachments.stream().filter(Attachment::isQuote).collect(Collectors.toList());
return quote.withAttachment(new SlideDeck(quoteAttachments));
}
}

View file

@ -735,8 +735,8 @@ public abstract class MessageRecord extends DisplayRecord {
}
public boolean isLatestRevision() {
if (this instanceof MediaMmsMessageRecord) {
return ((MediaMmsMessageRecord) this).getLatestRevisionId() == null;
if (this instanceof MmsMessageRecord) {
return ((MmsMessageRecord) this).getLatestRevisionId() == null;
}
return true;
}

View file

@ -10,7 +10,7 @@ import org.thoughtcrime.securesms.database.CallTable
import org.thoughtcrime.securesms.payments.Payment
fun MessageRecord.withReactions(reactions: List<ReactionRecord>): MessageRecord {
return if (this is MediaMmsMessageRecord) {
return if (this is MmsMessageRecord) {
this.withReactions(reactions)
} else {
this
@ -18,14 +18,14 @@ fun MessageRecord.withReactions(reactions: List<ReactionRecord>): MessageRecord
}
fun MessageRecord.withAttachments(attachments: List<DatabaseAttachment>): MessageRecord {
return if (this is MediaMmsMessageRecord) {
return if (this is MmsMessageRecord) {
this.withAttachments(attachments)
} else {
this
}
}
fun MessageRecord.withPayment(payment: Payment): MessageRecord {
return if (this is MediaMmsMessageRecord) {
return if (this is MmsMessageRecord) {
this.withPayment(payment)
} else {
this
@ -33,7 +33,7 @@ fun MessageRecord.withPayment(payment: Payment): MessageRecord {
}
fun MessageRecord.withCall(call: CallTable.Call): MessageRecord {
return if (this is MediaMmsMessageRecord) {
return if (this is MmsMessageRecord) {
this.withCall(call)
} else {
this

View file

@ -1,63 +1,138 @@
/*
* Copyright 2023 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.database.model;
import android.content.Context;
import android.text.SpannableString;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import androidx.core.content.ContextCompat;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.AttachmentId;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.contactshare.Contact;
import org.thoughtcrime.securesms.database.CallTable;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.MessageTable.Status;
import org.thoughtcrime.securesms.database.MessageTypes;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList;
import org.thoughtcrime.securesms.database.model.databaseprotos.GiftBadge;
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.payments.Payment;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.whispersystems.signalservice.api.payments.FormatterOptions;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
public abstract class MmsMessageRecord extends MessageRecord {
/**
* Represents the message record model for MMS messages that contain
* media (ie: they've been downloaded).
*
* @author Moxie Marlinspike
*
*/
private final @NonNull SlideDeck slideDeck;
private final @Nullable Quote quote;
private final @NonNull List<Contact> contacts = new LinkedList<>();
private final @NonNull List<LinkPreview> linkPreviews = new LinkedList<>();
private final @NonNull StoryType storyType;
private final @Nullable ParentStoryId parentStoryId;
private final @Nullable GiftBadge giftBadge;
public class MmsMessageRecord extends MessageRecord {
private final static String TAG = Log.tag(MmsMessageRecord.class);
private final boolean viewOnce;
private final SlideDeck slideDeck;
private final Quote quote;
private final List<Contact> contacts = new LinkedList<>();
private final List<LinkPreview> linkPreviews = new LinkedList<>();
private final StoryType storyType;
private final ParentStoryId parentStoryId;
private final GiftBadge giftBadge;
private final boolean viewOnce;
private final boolean mentionsSelf;
private final BodyRangeList messageRanges;
private final Payment payment;
private final CallTable.Call call;
private final long scheduledDate;
private final MessageId latestRevisionId;
MmsMessageRecord(long id, String body, Recipient fromRecipient, int fromDeviceId, Recipient toRecipient, long dateSent,
long dateReceived, long dateServer, long threadId, int deliveryStatus, int deliveryReceiptCount,
long type, Set<IdentityKeyMismatch> mismatches,
Set<NetworkFailure> networkFailures, int subscriptionId, long expiresIn,
long expireStarted, boolean viewOnce,
@NonNull SlideDeck slideDeck, int readReceiptCount,
@Nullable Quote quote, @NonNull List<Contact> contacts,
@NonNull List<LinkPreview> linkPreviews, boolean unidentified,
@NonNull List<ReactionRecord> reactions, boolean remoteDelete, long notifiedTimestamp,
int viewedReceiptCount, long receiptTimestamp, @NonNull StoryType storyType,
@Nullable ParentStoryId parentStoryId, @Nullable GiftBadge giftBadge, @Nullable MessageId originalMessageId,
int revisionNumber)
public MmsMessageRecord(long id,
Recipient fromRecipient,
int fromDeviceId,
Recipient toRecipient,
long dateSent,
long dateReceived,
long dateServer,
int deliveryReceiptCount,
long threadId,
String body,
@NonNull SlideDeck slideDeck,
long mailbox,
Set<IdentityKeyMismatch> mismatches,
Set<NetworkFailure> failures,
int subscriptionId,
long expiresIn,
long expireStarted,
boolean viewOnce,
int readReceiptCount,
@Nullable Quote quote,
@NonNull List<Contact> contacts,
@NonNull List<LinkPreview> linkPreviews,
boolean unidentified,
@NonNull List<ReactionRecord> reactions,
boolean remoteDelete,
boolean mentionsSelf,
long notifiedTimestamp,
int viewedReceiptCount,
long receiptTimestamp,
@Nullable BodyRangeList messageRanges,
@NonNull StoryType storyType,
@Nullable ParentStoryId parentStoryId,
@Nullable GiftBadge giftBadge,
@Nullable Payment payment,
@Nullable CallTable.Call call,
long scheduledDate,
@Nullable MessageId latestRevisionId,
@Nullable MessageId originalMessageId,
int revisionNumber)
{
super(id, body, fromRecipient, fromDeviceId, toRecipient,
dateSent, dateReceived, dateServer, threadId, deliveryStatus, deliveryReceiptCount,
type, mismatches, networkFailures, subscriptionId, expiresIn, expireStarted, readReceiptCount,
dateSent, dateReceived, dateServer, threadId, Status.STATUS_NONE, deliveryReceiptCount,
mailbox, mismatches, failures, subscriptionId, expiresIn, expireStarted, readReceiptCount,
unidentified, reactions, remoteDelete, notifiedTimestamp, viewedReceiptCount, receiptTimestamp, originalMessageId, revisionNumber);
this.slideDeck = slideDeck;
this.quote = quote;
this.viewOnce = viewOnce;
this.storyType = storyType;
this.parentStoryId = parentStoryId;
this.giftBadge = giftBadge;
this.slideDeck = slideDeck;
this.quote = quote;
this.viewOnce = viewOnce;
this.storyType = storyType;
this.parentStoryId = parentStoryId;
this.giftBadge = giftBadge;
this.mentionsSelf = mentionsSelf;
this.messageRanges = messageRanges;
this.payment = payment;
this.call = call;
this.scheduledDate = scheduledDate;
this.latestRevisionId = latestRevisionId;
this.contacts.addAll(contacts);
this.linkPreviews.addAll(linkPreviews);
}
@Override
public boolean isMms() {
return true;
@ -111,4 +186,191 @@ public abstract class MmsMessageRecord extends MessageRecord {
public @Nullable GiftBadge getGiftBadge() {
return giftBadge;
}
@Override
public boolean hasSelfMention() {
return mentionsSelf;
}
@Override
public boolean isMmsNotification() {
return false;
}
@Override
@WorkerThread
public SpannableString getDisplayBody(@NonNull Context context) {
if (MessageTypes.isChatSessionRefresh(type)) {
return emphasisAdded(context.getString(R.string.MmsMessageRecord_bad_encrypted_mms_message));
} else if (MessageTypes.isDuplicateMessageType(type)) {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_duplicate_message));
} else if (MessageTypes.isNoRemoteSessionType(type)) {
return emphasisAdded(context.getString(R.string.MmsMessageRecord_mms_message_encrypted_for_non_existing_session));
} else if (isLegacyMessage()) {
return emphasisAdded(context.getString(R.string.MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported));
} else if (isPaymentNotification() && payment != null) {
return new SpannableString(context.getString(R.string.MessageRecord__payment_s, payment.getAmount().toString(FormatterOptions.defaults())));
}
return super.getDisplayBody(context);
}
@Override
public @Nullable UpdateDescription getUpdateDisplayBody(@NonNull Context context, @Nullable Consumer<RecipientId> recipientClickHandler) {
if (isCallLog() && call != null && !(call.getType() == CallTable.Type.GROUP_CALL)) {
boolean accepted = call.getEvent() == CallTable.Event.ACCEPTED;
String callDateString = getCallDateString(context);
if (call.getDirection() == CallTable.Direction.OUTGOING) {
if (call.getType() == CallTable.Type.AUDIO_CALL) {
int updateString = accepted ? R.string.MessageRecord_outgoing_voice_call : R.string.MessageRecord_unanswered_voice_call;
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(updateString), callDateString), R.drawable.ic_update_audio_call_outgoing_16);
} else {
int updateString = accepted ? R.string.MessageRecord_outgoing_video_call : R.string.MessageRecord_unanswered_video_call;
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(updateString), callDateString), R.drawable.ic_update_video_call_outgoing_16);
}
} else {
boolean isVideoCall = call.getType() == CallTable.Type.VIDEO_CALL;
boolean isMissed = call.getEvent() == CallTable.Event.MISSED;
if (accepted) {
int updateString = isVideoCall ? R.string.MessageRecord_incoming_video_call : R.string.MessageRecord_incoming_voice_call;
int icon = isVideoCall ? R.drawable.ic_update_video_call_incoming_16 : R.drawable.ic_update_audio_call_incoming_16;
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(updateString), callDateString), icon);
} else if (isMissed) {
return isVideoCall ? staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_missed_video_call), callDateString), R.drawable.ic_update_video_call_missed_16, ContextCompat.getColor(context, R.color.core_red_shade), ContextCompat.getColor(context, R.color.core_red))
: staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_missed_voice_call), callDateString), R.drawable.ic_update_audio_call_missed_16, ContextCompat.getColor(context, R.color.core_red_shade), ContextCompat.getColor(context, R.color.core_red));
} else {
return isVideoCall ? staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_you_declined_a_video_call), callDateString), R.drawable.ic_update_video_call_incoming_16)
: staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_you_declined_a_voice_call), callDateString), R.drawable.ic_update_audio_call_incoming_16);
}
}
}
return super.getUpdateDisplayBody(context, recipientClickHandler);
}
@Override
public @Nullable BodyRangeList getMessageRanges() {
return messageRanges;
}
@Override
public @NonNull BodyRangeList requireMessageRanges() {
return Objects.requireNonNull(messageRanges);
}
public @Nullable Payment getPayment() {
return payment;
}
public @Nullable CallTable.Call getCall() {
return call;
}
public long getScheduledDate() {
return scheduledDate;
}
public @Nullable MessageId getLatestRevisionId() {
return latestRevisionId;
}
public @NonNull MmsMessageRecord withReactions(@NonNull List<ReactionRecord> reactions) {
return new MmsMessageRecord(getId(), getFromRecipient(), getFromDeviceId(), getToRecipient(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), getSlideDeck(),
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), getQuote(), getSharedContacts(), getLinkPreviews(), isUnidentified(), reactions, isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment(), getCall(), getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
}
public @NonNull MmsMessageRecord withoutQuote() {
return new MmsMessageRecord(getId(), getFromRecipient(), getFromDeviceId(), getToRecipient(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), getSlideDeck(),
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), null, getSharedContacts(), getLinkPreviews(), isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment(), getCall(), getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
}
public @NonNull MmsMessageRecord withAttachments(@NonNull List<DatabaseAttachment> attachments) {
Map<AttachmentId, DatabaseAttachment> attachmentIdMap = new HashMap<>();
for (DatabaseAttachment attachment : attachments) {
attachmentIdMap.put(attachment.getAttachmentId(), attachment);
}
List<Contact> contacts = updateContacts(getSharedContacts(), attachmentIdMap);
Set<Attachment> contactAttachments = contacts.stream().map(Contact::getAvatarAttachment).filter(Objects::nonNull).collect(Collectors.toSet());
List<LinkPreview> linkPreviews = updateLinkPreviews(getLinkPreviews(), attachmentIdMap);
Set<Attachment> linkPreviewAttachments = linkPreviews.stream().map(LinkPreview::getThumbnail).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toSet());
Quote quote = updateQuote(getQuote(), attachments);
List<DatabaseAttachment> slideAttachments = attachments.stream().filter(a -> !contactAttachments.contains(a)).filter(a -> !linkPreviewAttachments.contains(a)).collect(Collectors.toList());
SlideDeck slideDeck = MessageTable.MmsReader.buildSlideDeck(slideAttachments);
return new MmsMessageRecord(getId(), getFromRecipient(), getFromDeviceId(), getToRecipient(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), slideDeck,
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), quote, contacts, linkPreviews, isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment(), getCall(), getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
}
public @NonNull MmsMessageRecord withPayment(@NonNull Payment payment) {
return new MmsMessageRecord(getId(), getFromRecipient(), getFromDeviceId(), getToRecipient(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), getSlideDeck(),
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), getQuote(), getSharedContacts(), getLinkPreviews(), isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), payment, getCall(), getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
}
public @NonNull MmsMessageRecord withCall(@Nullable CallTable.Call call) {
return new MmsMessageRecord(getId(), getFromRecipient(), getFromDeviceId(), getToRecipient(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), getSlideDeck(),
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
getReadReceiptCount(), getQuote(), getSharedContacts(), getLinkPreviews(), isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), getViewedReceiptCount(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment(), call, getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
}
private static @NonNull List<Contact> updateContacts(@NonNull List<Contact> contacts, @NonNull Map<AttachmentId, DatabaseAttachment> attachmentIdMap) {
return contacts.stream()
.map(contact -> {
if (contact.getAvatar() != null) {
DatabaseAttachment attachment = attachmentIdMap.get(contact.getAvatar().getAttachmentId());
Contact.Avatar updatedAvatar = new Contact.Avatar(contact.getAvatar().getAttachmentId(),
attachment,
contact.getAvatar().isProfile());
return new Contact(contact, updatedAvatar);
} else {
return contact;
}
})
.collect(Collectors.toList());
}
private static @NonNull List<LinkPreview> updateLinkPreviews(@NonNull List<LinkPreview> linkPreviews, @NonNull Map<AttachmentId, DatabaseAttachment> attachmentIdMap) {
return linkPreviews.stream()
.map(preview -> {
if (preview.getAttachmentId() != null) {
DatabaseAttachment attachment = attachmentIdMap.get(preview.getAttachmentId());
if (attachment != null) {
return new LinkPreview(preview.getUrl(), preview.getTitle(), preview.getDescription(), preview.getDate(), attachment);
} else {
return preview;
}
} else {
return preview;
}
})
.collect(Collectors.toList());
}
private static @Nullable Quote updateQuote(@Nullable Quote quote, @NonNull List<DatabaseAttachment> attachments) {
if (quote == null) {
return null;
}
List<DatabaseAttachment> quoteAttachments = attachments.stream().filter(Attachment::isQuote).collect(Collectors.toList());
return quote.withAttachment(new SlideDeck(quoteAttachments));
}
}

View file

@ -30,7 +30,6 @@ import org.thoughtcrime.securesms.database.NoSuchMessageException
import org.thoughtcrime.securesms.database.PaymentTable.PublicKeyConflictException
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.GroupRecord
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.Mention
import org.thoughtcrime.securesms.database.model.MessageId
import org.thoughtcrime.securesms.database.model.MessageRecord
@ -515,7 +514,7 @@ object DataMessageProcessor {
return null
}
val targetMessageId = (targetMessage as? MediaMmsMessageRecord)?.latestRevisionId ?: MessageId(targetMessage.id)
val targetMessageId = (targetMessage as? MmsMessageRecord)?.latestRevisionId ?: MessageId(targetMessage.id)
if (isRemove) {
SignalDatabase.reactions.deleteReaction(targetMessageId, senderRecipientId)
@ -1050,7 +1049,7 @@ object DataMessageProcessor {
}
val authorId = Recipient.externalPush(ServiceId.parseOrThrow(quote.authorAci!!)).id
var quotedMessage = SignalDatabase.messages.getMessageFor(quote.id!!, authorId) as? MediaMmsMessageRecord
var quotedMessage = SignalDatabase.messages.getMessageFor(quote.id!!, authorId) as? MmsMessageRecord
if (quotedMessage != null && !quotedMessage.isRemoteDelete) {
log(timestamp, "Found matching message record...")
@ -1076,7 +1075,7 @@ object DataMessageProcessor {
}
if (quotedMessage.isPaymentNotification) {
quotedMessage = SignalDatabase.payments.updateMessageWithPayment(quotedMessage) as MediaMmsMessageRecord
quotedMessage = SignalDatabase.payments.updateMessageWithPayment(quotedMessage) as MmsMessageRecord
}
val body = if (quotedMessage.isPaymentNotification) quotedMessage.getDisplayBody(context).toString() else quotedMessage.body

View file

@ -6,8 +6,8 @@ import org.signal.core.util.orNull
import org.thoughtcrime.securesms.database.MessageTable.InsertResult
import org.thoughtcrime.securesms.database.MessageType
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MessageId
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
import org.thoughtcrime.securesms.database.model.toBodyRangeList
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
@ -49,7 +49,7 @@ object EditMessageProcessor {
log(envelope.timestamp!!, "[handleEditMessage] Edit message for " + editMessage.targetSentTimestamp)
var targetMessage: MediaMmsMessageRecord? = SignalDatabase.messages.getMessageFor(editMessage.targetSentTimestamp!!, senderRecipient.id) as? MediaMmsMessageRecord
var targetMessage: MmsMessageRecord? = SignalDatabase.messages.getMessageFor(editMessage.targetSentTimestamp!!, senderRecipient.id) as? MmsMessageRecord
val targetThreadRecipient: Recipient? = if (targetMessage != null) SignalDatabase.threads.getRecipientForThreadId(targetMessage.threadId) else null
if (targetMessage == null || targetThreadRecipient == null) {
@ -118,7 +118,7 @@ object EditMessageProcessor {
envelope: Envelope,
metadata: EnvelopeMetadata,
message: DataMessage,
targetMessage: MediaMmsMessageRecord
targetMessage: MmsMessageRecord
): InsertResult? {
val messageRanges: BodyRangeList? = message.bodyRanges.filter { it.mentionAci == null }.toList().toBodyRangeList()
val targetQuote = targetMessage.quote
@ -178,7 +178,7 @@ object EditMessageProcessor {
envelope: Envelope,
metadata: EnvelopeMetadata,
message: DataMessage,
targetMessage: MediaMmsMessageRecord
targetMessage: MmsMessageRecord
): InsertResult? {
val textMessage = IncomingMessage(
type = MessageType.NORMAL,

View file

@ -25,7 +25,6 @@ import org.thoughtcrime.securesms.database.PaymentMetaDataUtil
import org.thoughtcrime.securesms.database.SentStorySyncManifest
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.DistributionListId
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.Mention
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
@ -377,7 +376,7 @@ object SyncMessageProcessor {
val mediaMessage = OutgoingMessage(
recipient = toRecipient,
body = message.body ?: "",
attachments = syncAttachments.ifEmpty { (targetMessage as? MediaMmsMessageRecord)?.slideDeck?.asAttachments() ?: emptyList() },
attachments = syncAttachments.ifEmpty { (targetMessage as? MmsMessageRecord)?.slideDeck?.asAttachments() ?: emptyList() },
timestamp = sent.timestamp!!,
expiresIn = targetMessage.expiresIn,
viewOnce = viewOnce,
@ -962,7 +961,7 @@ object SyncMessageProcessor {
val toMarkViewed = records.map { it.id }
val toEnqueueDownload = records
.map { it as MediaMmsMessageRecord }
.map { it as MmsMessageRecord }
.filter { it.storyType.isStory && !it.storyType.isTextStory }
for (mediaMmsMessageRecord in toEnqueueDownload) {

View file

@ -7,9 +7,9 @@ import org.thoughtcrime.securesms.database.MessageTable
import org.thoughtcrime.securesms.database.NoSuchMessageException
import org.thoughtcrime.securesms.database.RecipientTable
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
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.ReactionRecord
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
import org.thoughtcrime.securesms.recipients.Recipient
@ -51,7 +51,7 @@ object NotificationStateProvider {
SignalDatabase.messages.hasGroupReplyOrReactionInStory(it)
}
if (record is MediaMmsMessageRecord) {
if (record is MmsMessageRecord) {
val attachments = SignalDatabase.attachments.getAttachmentsForMessage(record.id)
if (attachments.isNotEmpty()) {
record = record.withAttachments(attachments)

View file

@ -10,7 +10,7 @@ import org.signal.core.util.PendingIntentFlags
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.conversation.ConversationIntents
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.jobs.IndividualSendJob
import org.thoughtcrime.securesms.jobs.PushGroupSendJob
@ -37,7 +37,7 @@ class ScheduledMessageManager(
@Suppress("UsePropertyAccessSyntax")
@WorkerThread
override fun getNextClosestEvent(): Event? {
val oldestMessage: MediaMmsMessageRecord? = messagesTable.getOldestScheduledSendTimestamp() as? MediaMmsMessageRecord
val oldestMessage: MmsMessageRecord? = messagesTable.getOldestScheduledSendTimestamp() as? MmsMessageRecord
if (oldestMessage == null) {
cancelAlarm(application, ScheduledMessagesAlarm::class.java)

View file

@ -21,7 +21,6 @@ import org.signal.core.util.readParcelableCompat
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.conversation.colors.ChatColors
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
@ -120,7 +119,7 @@ data class StoryTextPostModel(
override fun decode(source: StoryTextPostModel, width: Int, height: Int, options: Options): Resource<Bitmap> {
val message = SignalDatabase.messages.getMessageFor(source.storySentAtMillis, source.storyAuthor).run {
if (this is MediaMmsMessageRecord) {
if (this is MmsMessageRecord) {
this.withAttachments(SignalDatabase.attachments.getAttachmentsForMessage(this.id))
} else {
this

View file

@ -20,8 +20,8 @@ import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.attachments.Attachment
import org.thoughtcrime.securesms.components.menu.ActionItem
import org.thoughtcrime.securesms.components.menu.SignalContextMenu
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
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.providers.BlobProvider
import org.thoughtcrime.securesms.stories.StoryTextPostModel
@ -49,7 +49,7 @@ object StoryContextMenu {
}
fun save(context: Context, messageRecord: MessageRecord) {
val mediaMessageRecord = messageRecord as? MediaMmsMessageRecord
val mediaMessageRecord = messageRecord as? MmsMessageRecord
val uri: Uri? = mediaMessageRecord?.slideDeck?.firstSlide?.uri
val contentType: String? = mediaMessageRecord?.slideDeck?.firstSlide?.contentType
@ -92,7 +92,7 @@ object StoryContextMenu {
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, saveAttachment)
}
fun share(fragment: Fragment, messageRecord: MediaMmsMessageRecord) {
fun share(fragment: Fragment, messageRecord: MmsMessageRecord) {
val intent = if (messageRecord.storyType.isTextStory) {
val textStoryBody = StoryTextPost.ADAPTER.decode(Base64.decode(messageRecord.body)).body
val linkUrl = messageRecord.linkPreviews.firstOrNull()?.url ?: ""

View file

@ -39,7 +39,6 @@ import org.thoughtcrime.securesms.components.settings.configure
import org.thoughtcrime.securesms.conversation.ConversationIntents
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.StoryViewState
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
@ -339,7 +338,7 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
}
},
onShareStory = {
StoryContextMenu.share(this@StoriesLandingFragment, it.data.primaryStory.messageRecord as MediaMmsMessageRecord)
StoryContextMenu.share(this@StoriesLandingFragment, it.data.primaryStory.messageRecord as MmsMessageRecord)
},
onSave = {
StoryContextMenu.save(requireContext(), it.data.primaryStory.messageRecord)

View file

@ -16,7 +16,7 @@ import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.avatar.view.AvatarView
import org.thoughtcrime.securesms.badges.BadgeImageView
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.recipients.Recipient
@ -92,8 +92,8 @@ object StoriesLandingItem {
}
private fun hasThumbChange(newItem: Model): Boolean {
val oldRecord = data.primaryStory.messageRecord as? MediaMmsMessageRecord ?: return false
val newRecord = newItem.data.primaryStory.messageRecord as? MediaMmsMessageRecord ?: return false
val oldRecord = data.primaryStory.messageRecord as? MmsMessageRecord ?: return false
val newRecord = newItem.data.primaryStory.messageRecord as? MmsMessageRecord ?: return false
val oldThumb = oldRecord.slideDeck.thumbnailSlide?.uri
val newThumb = newRecord.slideDeck.thumbnailSlide?.uri
@ -150,7 +150,7 @@ object StoriesLandingItem {
badgeView.setBadgeFromRecipient(model.data.storyRecipient)
}
val record = model.data.primaryStory.messageRecord as MediaMmsMessageRecord
val record = model.data.primaryStory.messageRecord as MmsMessageRecord
avatarView.setStoryRingFromState(model.data.storyViewState)
@ -188,7 +188,7 @@ object StoriesLandingItem {
}
if (model.data.secondaryStory != null) {
val secondaryRecord = model.data.secondaryStory.messageRecord as MediaMmsMessageRecord
val secondaryRecord = model.data.secondaryStory.messageRecord as MmsMessageRecord
val secondaryThumb = secondaryRecord.slideDeck.thumbnailSlide?.uri
storyOutline.setBackgroundColor(ContextCompat.getColor(context, R.color.signal_background_primary))

View file

@ -14,7 +14,6 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsText
import org.thoughtcrime.securesms.components.settings.configure
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
@ -91,7 +90,7 @@ class MyStoriesFragment : DSLSettingsFragment(
}
},
onShareClick = {
StoryContextMenu.share(this@MyStoriesFragment, it.distributionStory.messageRecord as MediaMmsMessageRecord)
StoryContextMenu.share(this@MyStoriesFragment, it.distributionStory.messageRecord as MmsMessageRecord)
},
onInfoClick = { model, preview ->
openStoryViewer(model, preview, true)

View file

@ -1,6 +1,6 @@
package org.thoughtcrime.securesms.stories.viewer.info
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.messagedetails.MessageDetails
/**
@ -9,7 +9,7 @@ import org.thoughtcrime.securesms.messagedetails.MessageDetails
data class StoryInfoState(
val messageDetails: MessageDetails? = null
) {
private val mediaMessage = messageDetails?.conversationMessage?.messageRecord as? MediaMmsMessageRecord
private val mediaMessage = messageDetails?.conversationMessage?.messageRecord as? MmsMessageRecord
val sentMillis: Long = mediaMessage?.dateSent ?: -1L
val receivedMillis: Long = mediaMessage?.dateReceived ?: -1L

View file

@ -57,7 +57,7 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
import org.thoughtcrime.securesms.database.AttachmentTable
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
import org.thoughtcrime.securesms.mediapreview.MediaPreviewFragment
import org.thoughtcrime.securesms.mediapreview.VideoControlsDelegate
@ -760,7 +760,7 @@ class StoryViewerPageFragment :
}
private fun presentSlate(post: StoryPost) {
storySlate.setBackground((post.conversationMessage.messageRecord as? MediaMmsMessageRecord)?.slideDeck?.thumbnailSlide?.placeholderBlur)
storySlate.setBackground((post.conversationMessage.messageRecord as? MmsMessageRecord)?.slideDeck?.thumbnailSlide?.placeholderBlur)
if (post.conversationMessage.messageRecord.isOutgoing) {
storySlate.moveToState(StorySlateView.State.HIDDEN, post.id)
@ -1084,7 +1084,7 @@ class StoryViewerPageFragment :
}
},
onShare = {
StoryContextMenu.share(this, it.conversationMessage.messageRecord as MediaMmsMessageRecord)
StoryContextMenu.share(this, it.conversationMessage.messageRecord as MmsMessageRecord)
},
onSave = {
StoryContextMenu.save(requireContext(), it.conversationMessage.messageRecord)

View file

@ -5,8 +5,8 @@ import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.ParentStoryId
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
import org.thoughtcrime.securesms.mms.OutgoingMessage
@ -28,7 +28,7 @@ class StoryDirectReplyRepository(context: Context) {
fun send(storyId: Long, groupDirectReplyRecipientId: RecipientId?, body: CharSequence, bodyRangeList: BodyRangeList?, isReaction: Boolean): Completable {
return Completable.create { emitter ->
val message = SignalDatabase.messages.getMessageRecord(storyId) as MediaMmsMessageRecord
val message = SignalDatabase.messages.getMessageRecord(storyId) as MmsMessageRecord
val (recipient, threadId) = if (groupDirectReplyRecipientId == null) {
message.fromRecipient to message.threadId
} else {

View file

@ -5,7 +5,6 @@ package org.thoughtcrime.securesms.util
import android.content.Context
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.database.MessageTypes
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.Quote
@ -19,7 +18,7 @@ const val MAX_BODY_DISPLAY_LENGTH = 1000
fun MessageRecord.isMediaMessage(): Boolean {
return isMms &&
!isMmsNotification &&
(this as MediaMmsMessageRecord).containsMediaSlide() &&
(this as MmsMessageRecord).containsMediaSlide() &&
slideDeck.stickerSlide == null
}
@ -145,7 +144,7 @@ fun MessageRecord.isTextOnly(context: Context): Boolean {
}
fun MessageRecord.isScheduled(): Boolean {
return (this as? MediaMmsMessageRecord)?.scheduledDate?.let { it != -1L } ?: false
return (this as? MmsMessageRecord)?.scheduledDate?.let { it != -1L } ?: false
}
/**
@ -156,7 +155,7 @@ fun MessageRecord.getRecordQuoteType(): QuoteModel.Type {
}
fun MessageRecord.isEditMessage(): Boolean {
return this is MediaMmsMessageRecord && isEditMessage
return this is MmsMessageRecord && isEditMessage
}
/**

View file

@ -26,7 +26,7 @@ import org.signal.core.util.StreamUtil
import org.signal.core.util.logging.Log
import org.signal.core.util.orNull
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.mms.PartAuthority
import java.io.File
@ -63,7 +63,7 @@ object SaveAttachmentUtil {
.show()
}
fun getAttachmentsForRecord(record: MediaMmsMessageRecord): Set<SaveAttachment> {
fun getAttachmentsForRecord(record: MmsMessageRecord): Set<SaveAttachment> {
return record.slideDeck.slides
.filter { it.uri != null && (it.hasImage() || it.hasVideo() || it.hasAudio() || it.hasDocument()) }
.map { SaveAttachment(it.uri!!, it.contentType, record.dateSent, it.fileName.orNull()) }

View file

@ -7,7 +7,7 @@ import org.thoughtcrime.securesms.blurhash.BlurHash
import org.thoughtcrime.securesms.contactshare.Contact
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch
import org.thoughtcrime.securesms.database.documents.NetworkFailure
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.database.model.ParentStoryId
import org.thoughtcrime.securesms.database.model.Quote
import org.thoughtcrime.securesms.database.model.ReactionRecord
@ -143,8 +143,8 @@ object FakeMessageRecords {
giftBadge: GiftBadge? = null,
payment: Payment? = null,
call: CallTable.Call? = null
): MediaMmsMessageRecord {
return MediaMmsMessageRecord(
): MmsMessageRecord {
return MmsMessageRecord(
id,
conversationRecipient,
recipientDeviceId,