mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 09:49:30 +01:00
Add text formatting send and receive support for conversations.
This commit is contained in:
committed by
Greyson Parrelli
parent
aa2075c78f
commit
cc490f4b73
@@ -48,6 +48,7 @@ import org.thoughtcrime.securesms.database.SentStorySyncManifest;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.database.StickerTable;
|
||||
import org.thoughtcrime.securesms.database.ThreadTable;
|
||||
import org.thoughtcrime.securesms.database.model.DatabaseProtosUtil;
|
||||
import org.thoughtcrime.securesms.database.model.DistributionListId;
|
||||
import org.thoughtcrime.securesms.database.model.GroupRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||
@@ -62,6 +63,7 @@ import org.thoughtcrime.securesms.database.model.ReactionRecord;
|
||||
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
||||
import org.thoughtcrime.securesms.database.model.StoryType;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.ChatColor;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.GiftBadge;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.StoryTextPost;
|
||||
@@ -170,6 +172,7 @@ import org.whispersystems.signalservice.api.payments.Money;
|
||||
import org.whispersystems.signalservice.api.push.DistributionId;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.SyncMessage;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -274,7 +277,7 @@ public final class MessageContentProcessor {
|
||||
if (content.getDataMessage().isPresent()) {
|
||||
GroupTable groupDatabase = SignalDatabase.groups();
|
||||
SignalServiceDataMessage message = content.getDataMessage().get();
|
||||
boolean isMediaMessage = message.getAttachments().isPresent() || message.getQuote().isPresent() || message.getSharedContacts().isPresent() || message.getPreviews().isPresent() || message.getSticker().isPresent() || message.getMentions().isPresent();
|
||||
boolean isMediaMessage = message.getAttachments().isPresent() || message.getQuote().isPresent() || message.getSharedContacts().isPresent() || message.getPreviews().isPresent() || message.getSticker().isPresent() || message.getMentions().isPresent() || message.getBodyRanges().isPresent();
|
||||
Optional<GroupId> groupId = GroupUtil.idFromGroupContext(message.getGroupContext());
|
||||
boolean isGv2Message = groupId.isPresent() && groupId.get().isV2();
|
||||
|
||||
@@ -1550,7 +1553,8 @@ public final class MessageContentProcessor {
|
||||
content.getServerUuid(),
|
||||
null,
|
||||
false,
|
||||
false);
|
||||
false,
|
||||
getBodyRangeList(message.getBodyRanges()));
|
||||
|
||||
insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
|
||||
|
||||
@@ -1671,13 +1675,15 @@ public final class MessageContentProcessor {
|
||||
} else if (SignalDatabase.storySends().canReply(senderRecipient.getId(), storyContext.getSentTimestamp())) {
|
||||
MmsMessageRecord story = (MmsMessageRecord) database.getMessageRecord(storyMessageId.getId());
|
||||
|
||||
String displayText = "";
|
||||
String displayText = "";
|
||||
BodyRangeList bodyRanges = null;
|
||||
if (story.getStoryType().isTextStory()) {
|
||||
displayText = story.getBody();
|
||||
bodyRanges = story.getMessageRanges();
|
||||
}
|
||||
|
||||
parentStoryId = new ParentStoryId.DirectReply(storyMessageId.getId());
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, displayText, false, story.getSlideDeck().asAttachments(), Collections.emptyList(), QuoteModel.Type.NORMAL);
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, displayText, false, story.getSlideDeck().asAttachments(), Collections.emptyList(), QuoteModel.Type.NORMAL, bodyRanges);
|
||||
expiresInMillis = TimeUnit.SECONDS.toMillis(message.getExpiresInSeconds());
|
||||
} else {
|
||||
warn(content.getTimestamp(), "Story has reactions disabled. Dropping reaction.");
|
||||
@@ -1780,12 +1786,14 @@ public final class MessageContentProcessor {
|
||||
} else if (groupStory || SignalDatabase.storySends().canReply(senderRecipient.getId(), storyContext.getSentTimestamp())) {
|
||||
parentStoryId = new ParentStoryId.DirectReply(storyMessageId.getId());
|
||||
|
||||
String displayText = "";
|
||||
String displayText = "";
|
||||
BodyRangeList bodyRanges = null;
|
||||
if (story.getStoryType().isTextStory()) {
|
||||
displayText = story.getBody();
|
||||
bodyRanges = story.getMessageRanges();
|
||||
}
|
||||
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, displayText, false, story.getSlideDeck().asAttachments(), Collections.emptyList(), QuoteModel.Type.NORMAL);
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, displayText, false, story.getSlideDeck().asAttachments(), Collections.emptyList(), QuoteModel.Type.NORMAL, bodyRanges);
|
||||
expiresInMillis = TimeUnit.SECONDS.toMillis(message.getExpiresInSeconds());
|
||||
} else {
|
||||
warn(content.getTimestamp(), "Story has replies disabled. Dropping reply.");
|
||||
@@ -1796,6 +1804,8 @@ public final class MessageContentProcessor {
|
||||
return null;
|
||||
}
|
||||
|
||||
BodyRangeList bodyRanges = message.getBodyRanges().map(DatabaseProtosUtil::toBodyRangeList).orElse(null);
|
||||
|
||||
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(senderRecipient.getId(),
|
||||
content.getTimestamp(),
|
||||
content.getServerReceivedTimestamp(),
|
||||
@@ -1819,7 +1829,8 @@ public final class MessageContentProcessor {
|
||||
content.getServerUuid(),
|
||||
null,
|
||||
false,
|
||||
false);
|
||||
false,
|
||||
bodyRanges);
|
||||
|
||||
Optional<InsertResult> insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
|
||||
|
||||
@@ -1934,6 +1945,7 @@ public final class MessageContentProcessor {
|
||||
Optional<List<LinkPreview>> linkPreviews = getLinkPreviews(message.getPreviews(), message.getBody().orElse(""), false);
|
||||
Optional<List<Mention>> mentions = getMentions(message.getMentions());
|
||||
Optional<Attachment> sticker = getStickerAttachment(message.getSticker());
|
||||
BodyRangeList messageRanges = getBodyRangeList(message.getBodyRanges());
|
||||
|
||||
handlePossibleExpirationUpdate(content, message, Optional.empty(), senderRecipient, threadRecipient, receivedTime);
|
||||
|
||||
@@ -1960,7 +1972,8 @@ public final class MessageContentProcessor {
|
||||
content.getServerUuid(),
|
||||
null,
|
||||
false,
|
||||
false);
|
||||
false,
|
||||
messageRanges);
|
||||
|
||||
insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
|
||||
|
||||
@@ -2064,12 +2077,15 @@ public final class MessageContentProcessor {
|
||||
} else if (groupStory || story.getStoryType().isStoryWithReplies()) {
|
||||
parentStoryId = new ParentStoryId.DirectReply(storyMessageId.getId());
|
||||
|
||||
String quoteBody = "";
|
||||
String quoteBody = "";
|
||||
BodyRangeList bodyRanges = null;
|
||||
|
||||
if (story.getStoryType().isTextStory()) {
|
||||
quoteBody = story.getBody();
|
||||
quoteBody = story.getBody();
|
||||
bodyRanges = story.getMessageRanges();
|
||||
}
|
||||
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, quoteBody, false, story.getSlideDeck().asAttachments(), Collections.emptyList(), QuoteModel.Type.NORMAL);
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, quoteBody, false, story.getSlideDeck().asAttachments(), Collections.emptyList(), QuoteModel.Type.NORMAL, bodyRanges);
|
||||
expiresInMillis = TimeUnit.SECONDS.toMillis(message.getDataMessage().get().getExpiresInSeconds());
|
||||
} else {
|
||||
warn(envelopeTimestamp, "Story has replies disabled. Dropping reply.");
|
||||
@@ -2094,7 +2110,8 @@ public final class MessageContentProcessor {
|
||||
Collections.emptySet(),
|
||||
Collections.emptySet(),
|
||||
null,
|
||||
true);
|
||||
true,
|
||||
null);
|
||||
|
||||
if (recipient.getExpiresInSeconds() != message.getDataMessage().get().getExpiresInSeconds()) {
|
||||
handleSynchronizeSentExpirationUpdate(message);
|
||||
@@ -2213,7 +2230,8 @@ public final class MessageContentProcessor {
|
||||
Collections.emptySet(),
|
||||
Collections.emptySet(),
|
||||
null,
|
||||
true);
|
||||
true,
|
||||
null);
|
||||
|
||||
MessageTable messageTable = SignalDatabase.messages();
|
||||
long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient);
|
||||
@@ -2310,7 +2328,8 @@ public final class MessageContentProcessor {
|
||||
Collections.emptySet(),
|
||||
Collections.emptySet(),
|
||||
giftBadge.orElse(null),
|
||||
true);
|
||||
true,
|
||||
null);
|
||||
|
||||
if (recipients.getExpiresInSeconds() != message.getDataMessage().get().getExpiresInSeconds()) {
|
||||
handleSynchronizeSentExpirationUpdate(message);
|
||||
@@ -2488,9 +2507,10 @@ public final class MessageContentProcessor {
|
||||
{
|
||||
log(envelopeTimestamp, "Synchronize sent text message for " + message.getTimestamp());
|
||||
|
||||
Recipient recipient = getSyncMessageDestination(message);
|
||||
String body = message.getDataMessage().get().getBody().orElse("");
|
||||
long expiresInMillis = TimeUnit.SECONDS.toMillis(message.getDataMessage().get().getExpiresInSeconds());
|
||||
Recipient recipient = getSyncMessageDestination(message);
|
||||
String body = message.getDataMessage().get().getBody().orElse("");
|
||||
long expiresInMillis = TimeUnit.SECONDS.toMillis(message.getDataMessage().get().getExpiresInSeconds());
|
||||
BodyRangeList bodyRanges = message.getDataMessage().get().getBodyRanges().map(DatabaseProtosUtil::toBodyRangeList).orElse(null);
|
||||
|
||||
if (recipient.getExpiresInSeconds() != message.getDataMessage().get().getExpiresInSeconds()) {
|
||||
handleSynchronizeSentExpirationUpdate(message);
|
||||
@@ -2513,14 +2533,15 @@ public final class MessageContentProcessor {
|
||||
StoryType.NONE,
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
true);
|
||||
true,
|
||||
bodyRanges);
|
||||
|
||||
messageId = SignalDatabase.messages().insertMessageOutbox(outgoingMessage, threadId, false, GroupReceiptTable.STATUS_UNKNOWN, null);
|
||||
database = SignalDatabase.messages();
|
||||
|
||||
updateGroupReceiptStatus(message, messageId, recipient.requireGroupId());
|
||||
} else {
|
||||
OutgoingMessage outgoingTextMessage = OutgoingMessage.text(recipient, body, expiresInMillis, message.getTimestamp());
|
||||
OutgoingMessage outgoingTextMessage = OutgoingMessage.text(recipient, body, expiresInMillis, message.getTimestamp(), bodyRanges);
|
||||
|
||||
messageId = SignalDatabase.messages().insertMessageOutbox(outgoingTextMessage, threadId, false, null);
|
||||
database = SignalDatabase.messages();
|
||||
@@ -3023,7 +3044,7 @@ public final class MessageContentProcessor {
|
||||
|
||||
String body = message.isPaymentNotification() ? message.getDisplayBody(context).toString() : message.getBody();
|
||||
|
||||
return Optional.of(new QuoteModel(quote.get().getId(), author, body, false, attachments, mentions, QuoteModel.Type.fromDataMessageType(quote.get().getType())));
|
||||
return Optional.of(new QuoteModel(quote.get().getId(), author, body, false, attachments, mentions, QuoteModel.Type.fromDataMessageType(quote.get().getType()), message.getMessageRanges()));
|
||||
} else if (message != null) {
|
||||
warn("Found the target for the quote, but it's flagged as remotely deleted.");
|
||||
}
|
||||
@@ -3036,7 +3057,8 @@ public final class MessageContentProcessor {
|
||||
true,
|
||||
PointerAttachment.forPointers(quote.get().getAttachments()),
|
||||
getMentions(quote.get().getMentions()),
|
||||
QuoteModel.Type.fromDataMessageType(quote.get().getType())));
|
||||
QuoteModel.Type.fromDataMessageType(quote.get().getType()),
|
||||
DatabaseProtosUtil.toBodyRangeList(quote.get().getBodyRanges())));
|
||||
}
|
||||
|
||||
private Optional<Attachment> getStickerAttachment(Optional<SignalServiceDataMessage.Sticker> sticker) {
|
||||
@@ -3124,6 +3146,14 @@ public final class MessageContentProcessor {
|
||||
return Optional.of(getMentions(signalServiceMentions.get()));
|
||||
}
|
||||
|
||||
private @Nullable BodyRangeList getBodyRangeList(Optional<List<SignalServiceProtos.BodyRange>> bodyRanges) {
|
||||
if (!bodyRanges.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return DatabaseProtosUtil.toBodyRangeList(bodyRanges.get());
|
||||
}
|
||||
|
||||
private @NonNull List<Mention> getMentions(@Nullable List<SignalServiceDataMessage.Mention> signalServiceMentions) {
|
||||
if (signalServiceMentions == null || signalServiceMentions.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
|
||||
Reference in New Issue
Block a user