mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 01:40:07 +01:00
Add support for replying to gift badges.
This commit is contained in:
@@ -179,9 +179,10 @@ public class InputPanel extends LinearLayout
|
||||
long id,
|
||||
@NonNull Recipient author,
|
||||
@NonNull CharSequence body,
|
||||
@NonNull SlideDeck attachments)
|
||||
@NonNull SlideDeck attachments,
|
||||
@NonNull QuoteModel.Type quoteType)
|
||||
{
|
||||
this.quoteView.setQuote(glideRequests, id, author, body, false, attachments, null, null);
|
||||
this.quoteView.setQuote(glideRequests, id, author, body, false, attachments, null, null, quoteType);
|
||||
|
||||
int originalHeight = this.quoteView.getVisibility() == VISIBLE ? this.quoteView.getMeasuredHeight()
|
||||
: 0;
|
||||
@@ -256,7 +257,7 @@ public class InputPanel extends LinearLayout
|
||||
|
||||
public Optional<QuoteModel> getQuote() {
|
||||
if (quoteView.getQuoteId() > 0 && quoteView.getVisibility() == View.VISIBLE) {
|
||||
return Optional.of(new QuoteModel(quoteView.getQuoteId(), quoteView.getAuthor().getId(), quoteView.getBody().toString(), false, quoteView.getAttachments(), quoteView.getMentions()));
|
||||
return Optional.of(new QuoteModel(quoteView.getQuoteId(), quoteView.getAuthor().getId(), quoteView.getBody().toString(), false, quoteView.getAttachments(), quoteView.getMentions(), quoteView.getQuoteType()));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
@@ -30,6 +31,7 @@ import org.thoughtcrime.securesms.conversation.colors.ChatColors;
|
||||
import org.thoughtcrime.securesms.database.model.Mention;
|
||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.mms.QuoteModel;
|
||||
import org.thoughtcrime.securesms.mms.Slide;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
||||
@@ -87,16 +89,17 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||
private EmojiImageView missingStoryReaction;
|
||||
private EmojiImageView storyReactionEmoji;
|
||||
|
||||
private long id;
|
||||
private LiveRecipient author;
|
||||
private CharSequence body;
|
||||
private TextView mediaDescriptionText;
|
||||
private TextView missingLinkText;
|
||||
private SlideDeck attachments;
|
||||
private MessageType messageType;
|
||||
private int largeCornerRadius;
|
||||
private int smallCornerRadius;
|
||||
private CornerMask cornerMask;
|
||||
private long id;
|
||||
private LiveRecipient author;
|
||||
private CharSequence body;
|
||||
private TextView mediaDescriptionText;
|
||||
private TextView missingLinkText;
|
||||
private SlideDeck attachments;
|
||||
private MessageType messageType;
|
||||
private int largeCornerRadius;
|
||||
private int smallCornerRadius;
|
||||
private CornerMask cornerMask;
|
||||
private QuoteModel.Type quoteType;
|
||||
|
||||
private int thumbHeight;
|
||||
private int thumbWidth;
|
||||
@@ -206,7 +209,8 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||
boolean originalMissing,
|
||||
@NonNull SlideDeck attachments,
|
||||
@Nullable ChatColors chatColors,
|
||||
@Nullable String storyReaction)
|
||||
@Nullable String storyReaction,
|
||||
@NonNull QuoteModel.Type quoteType)
|
||||
{
|
||||
if (this.author != null) this.author.removeForeverObserver(this);
|
||||
|
||||
@@ -214,10 +218,11 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||
this.author = author.live();
|
||||
this.body = body;
|
||||
this.attachments = attachments;
|
||||
this.quoteType = quoteType;
|
||||
|
||||
this.author.observeForever(this);
|
||||
setQuoteAuthor(author);
|
||||
setQuoteText(body, attachments, originalMissing, storyReaction);
|
||||
setQuoteText(resolveBody(body, quoteType), attachments, originalMissing, storyReaction);
|
||||
setQuoteAttachment(glideRequests, body, attachments, originalMissing);
|
||||
setQuoteMissingFooter(originalMissing);
|
||||
|
||||
@@ -228,6 +233,10 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable CharSequence resolveBody(@Nullable CharSequence body, @NonNull QuoteModel.Type quoteType) {
|
||||
return quoteType == QuoteModel.Type.GIFT_BADGE ? getContext().getString(R.string.QuoteView__gift) : body;
|
||||
}
|
||||
|
||||
public void setTopCornerSizes(boolean topLeftLarge, boolean topRightLarge) {
|
||||
cornerMask.setTopLeftRadius(topLeftLarge ? largeCornerRadius : smallCornerRadius);
|
||||
cornerMask.setTopRightRadius(topRightLarge ? largeCornerRadius : smallCornerRadius);
|
||||
@@ -386,6 +395,18 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||
return;
|
||||
}
|
||||
|
||||
if (quoteType == QuoteModel.Type.GIFT_BADGE) {
|
||||
attachmentVideoOverlayView.setVisibility(GONE);
|
||||
attachmentContainerView.setVisibility(GONE);
|
||||
thumbnailView.setVisibility(VISIBLE);
|
||||
glideRequests.load(R.drawable.ic_gift_thumbnail)
|
||||
.centerCrop()
|
||||
.override(thumbWidth, thumbHeight)
|
||||
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
|
||||
.into(thumbnailView);
|
||||
return;
|
||||
}
|
||||
|
||||
Slide imageVideoSlide = slideDeck.getSlides().stream().filter(s -> s.hasImage() || s.hasVideo() || s.hasSticker()).findFirst().orElse(null);
|
||||
Slide documentSlide = slideDeck.getSlides().stream().filter(Slide::hasDocument).findFirst().orElse(null);
|
||||
Slide viewOnceSlide = slideDeck.getSlides().stream().filter(Slide::hasViewOnce).findFirst().orElse(null);
|
||||
@@ -459,6 +480,10 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||
return attachments.asAttachments();
|
||||
}
|
||||
|
||||
public @NonNull QuoteModel.Type getQuoteType() {
|
||||
return quoteType;
|
||||
}
|
||||
|
||||
public @NonNull List<Mention> getMentions() {
|
||||
return MentionAnnotation.getMentionsFromAnnotations(body);
|
||||
}
|
||||
|
||||
@@ -1471,7 +1471,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
quote.isOriginalMissing(),
|
||||
quote.getAttachment(),
|
||||
chatColors,
|
||||
isStoryReaction(current) ? current.getBody() : null);
|
||||
isStoryReaction(current) ? current.getBody() : null,
|
||||
quote.getQuoteType());
|
||||
|
||||
quoteView.setVisibility(View.VISIBLE);
|
||||
quoteView.setTextSize(TypedValue.COMPLEX_UNIT_SP, SignalStore.settings().getMessageFontSize());
|
||||
|
||||
@@ -281,6 +281,7 @@ import org.thoughtcrime.securesms.util.FullscreenHelper;
|
||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
import org.thoughtcrime.securesms.util.LifecycleDisposable;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.MessageRecordUtil;
|
||||
import org.thoughtcrime.securesms.util.MessageUtil;
|
||||
import org.thoughtcrime.securesms.util.PlayStoreUtil;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
@@ -3876,7 +3877,8 @@ public class ConversationParentFragment extends Fragment
|
||||
messageRecord.getDateSent(),
|
||||
author,
|
||||
body,
|
||||
slideDeck);
|
||||
slideDeck,
|
||||
MessageRecordUtil.getRecordQuoteType(messageRecord));
|
||||
|
||||
} else if (messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getLinkPreviews().isEmpty()) {
|
||||
LinkPreview linkPreview = ((MmsMessageRecord) messageRecord).getLinkPreviews().get(0);
|
||||
@@ -3890,7 +3892,8 @@ public class ConversationParentFragment extends Fragment
|
||||
messageRecord.getDateSent(),
|
||||
author,
|
||||
conversationMessage.getDisplayBody(requireContext()),
|
||||
slideDeck);
|
||||
slideDeck,
|
||||
MessageRecordUtil.getRecordQuoteType(messageRecord));
|
||||
} else {
|
||||
SlideDeck slideDeck = messageRecord.isMms() ? ((MmsMessageRecord) messageRecord).getSlideDeck() : new SlideDeck();
|
||||
|
||||
@@ -3904,7 +3907,8 @@ public class ConversationParentFragment extends Fragment
|
||||
messageRecord.getDateSent(),
|
||||
author,
|
||||
conversationMessage.getDisplayBody(requireContext()),
|
||||
slideDeck);
|
||||
slideDeck,
|
||||
MessageRecordUtil.getRecordQuoteType(messageRecord));
|
||||
}
|
||||
|
||||
inputPanel.clickOnComposeInput();
|
||||
|
||||
@@ -188,7 +188,6 @@ final class MenuState {
|
||||
messageRecord.isSecure() &&
|
||||
(!conversationRecipient.isGroup() || conversationRecipient.isActiveGroup()) &&
|
||||
!messageRecord.getRecipient().isBlocked() &&
|
||||
!MessageRecordUtil.hasGiftBadge(messageRecord) &&
|
||||
!conversationRecipient.isReleaseNotes();
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
static final String QUOTE_ATTACHMENT = "quote_attachment";
|
||||
static final String QUOTE_MISSING = "quote_missing";
|
||||
static final String QUOTE_MENTIONS = "quote_mentions";
|
||||
static final String QUOTE_TYPE = "quote_type";
|
||||
|
||||
static final String SHARED_CONTACTS = "shared_contacts";
|
||||
static final String LINK_PREVIEWS = "previews";
|
||||
@@ -171,6 +172,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
QUOTE_ATTACHMENT + " INTEGER DEFAULT -1, " +
|
||||
QUOTE_MISSING + " INTEGER DEFAULT 0, " +
|
||||
QUOTE_MENTIONS + " BLOB DEFAULT NULL," +
|
||||
QUOTE_TYPE + " INTEGER DEFAULT 0," +
|
||||
SHARED_CONTACTS + " TEXT, " +
|
||||
UNIDENTIFIED + " INTEGER DEFAULT 0, " +
|
||||
LINK_PREVIEWS + " TEXT, " +
|
||||
@@ -209,7 +211,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
MESSAGE_SIZE, STATUS, TRANSACTION_ID,
|
||||
BODY, PART_COUNT, RECIPIENT_ID, ADDRESS_DEVICE_ID,
|
||||
DELIVERY_RECEIPT_COUNT, READ_RECEIPT_COUNT, MISMATCHED_IDENTITIES, NETWORK_FAILURE, SUBSCRIPTION_ID,
|
||||
EXPIRES_IN, EXPIRE_STARTED, NOTIFIED, QUOTE_ID, QUOTE_AUTHOR, QUOTE_BODY, QUOTE_ATTACHMENT, QUOTE_MISSING, QUOTE_MENTIONS,
|
||||
EXPIRES_IN, EXPIRE_STARTED, NOTIFIED, QUOTE_ID, QUOTE_AUTHOR, QUOTE_BODY, QUOTE_ATTACHMENT, QUOTE_TYPE, QUOTE_MISSING, QUOTE_MENTIONS,
|
||||
SHARED_CONTACTS, LINK_PREVIEWS, UNIDENTIFIED, VIEW_ONCE, REACTIONS_UNREAD, REACTIONS_LAST_SEEN,
|
||||
REMOTE_DELETED, MENTIONS_SELF, NOTIFIED_TIMESTAMP, VIEWED_RECEIPT_COUNT, RECEIPT_TIMESTAMP, MESSAGE_RANGES,
|
||||
STORY_TYPE, PARENT_STORY_ID,
|
||||
@@ -1216,6 +1218,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
values.putNull(QUOTE_BODY);
|
||||
values.putNull(QUOTE_AUTHOR);
|
||||
values.putNull(QUOTE_ATTACHMENT);
|
||||
values.putNull(QUOTE_TYPE);
|
||||
values.putNull(QUOTE_ID);
|
||||
values.putNull(LINK_PREVIEWS);
|
||||
values.putNull(SHARED_CONTACTS);
|
||||
@@ -1536,6 +1539,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
long quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_ID));
|
||||
long quoteAuthor = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_AUTHOR));
|
||||
String quoteText = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_BODY));
|
||||
int quoteType = cursor.getInt(cursor.getColumnIndexOrThrow(QUOTE_TYPE));
|
||||
boolean quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(QUOTE_MISSING)) == 1;
|
||||
List<Attachment> quoteAttachments = Stream.of(associatedAttachments).filter(Attachment::isQuote).map(a -> (Attachment)a).toList();
|
||||
List<Mention> quoteMentions = parseQuoteMentions(context, cursor);
|
||||
@@ -1555,7 +1559,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
QuoteModel quote = null;
|
||||
|
||||
if (quoteId > 0 && quoteAuthor > 0 && (!TextUtils.isEmpty(quoteText) || !quoteAttachments.isEmpty())) {
|
||||
quote = new QuoteModel(quoteId, RecipientId.from(quoteAuthor), quoteText, quoteMissing, quoteAttachments, quoteMentions);
|
||||
quote = new QuoteModel(quoteId, RecipientId.from(quoteAuthor), quoteText, quoteMissing, quoteAttachments, quoteMentions, QuoteModel.Type.fromCode(quoteType));
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(mismatchDocument)) {
|
||||
@@ -1739,6 +1743,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
contentValues.put(QUOTE_ID, retrieved.getQuote().getId());
|
||||
contentValues.put(QUOTE_BODY, retrieved.getQuote().getText().toString());
|
||||
contentValues.put(QUOTE_AUTHOR, retrieved.getQuote().getAuthor().serialize());
|
||||
contentValues.put(QUOTE_TYPE, retrieved.getQuote().getType().getCode());
|
||||
contentValues.put(QUOTE_MISSING, retrieved.getQuote().isOriginalMissing() ? 1 : 0);
|
||||
|
||||
BodyRangeList mentionsList = MentionUtil.mentionsToBodyRangeList(retrieved.getQuote().getMentions());
|
||||
@@ -2011,6 +2016,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
contentValues.put(QUOTE_ID, message.getOutgoingQuote().getId());
|
||||
contentValues.put(QUOTE_AUTHOR, message.getOutgoingQuote().getAuthor().serialize());
|
||||
contentValues.put(QUOTE_BODY, updated.getBodyAsString());
|
||||
contentValues.put(QUOTE_TYPE, message.getOutgoingQuote().getType().getCode());
|
||||
contentValues.put(QUOTE_MISSING, message.getOutgoingQuote().isOriginalMissing() ? 1 : 0);
|
||||
|
||||
BodyRangeList mentionsList = MentionUtil.mentionsToBodyRangeList(updated.getMentions());
|
||||
@@ -2485,7 +2491,8 @@ public class MmsDatabase extends MessageDatabase {
|
||||
quoteText,
|
||||
message.getOutgoingQuote().isOriginalMissing(),
|
||||
new SlideDeck(context, message.getOutgoingQuote().getAttachments()),
|
||||
quoteMentions) :
|
||||
quoteMentions,
|
||||
message.getOutgoingQuote().getType()) :
|
||||
null,
|
||||
message.getSharedContacts(),
|
||||
message.getLinkPreviews(),
|
||||
@@ -2699,6 +2706,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
long quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_ID));
|
||||
long quoteAuthor = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_AUTHOR));
|
||||
CharSequence quoteText = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_BODY));
|
||||
int quoteType = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_TYPE));
|
||||
boolean quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_MISSING)) == 1;
|
||||
List<Mention> quoteMentions = parseQuoteMentions(context, cursor);
|
||||
List<DatabaseAttachment> attachments = SignalDatabase.attachments().getAttachments(cursor);
|
||||
@@ -2713,7 +2721,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
quoteMentions = updated.getMentions();
|
||||
}
|
||||
|
||||
return new Quote(quoteId, RecipientId.from(quoteAuthor), quoteText, quoteMissing, quoteDeck, quoteMentions);
|
||||
return new Quote(quoteId, RecipientId.from(quoteAuthor), quoteText, quoteMissing, quoteDeck, quoteMentions, QuoteModel.Type.fromCode(quoteType));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsDatabase.QUOTE_BODY,
|
||||
MmsDatabase.QUOTE_MISSING,
|
||||
MmsDatabase.QUOTE_ATTACHMENT,
|
||||
MmsDatabase.QUOTE_TYPE,
|
||||
MmsDatabase.QUOTE_MENTIONS,
|
||||
MmsDatabase.SHARED_CONTACTS,
|
||||
MmsDatabase.LINK_PREVIEWS,
|
||||
@@ -777,6 +778,7 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsDatabase.QUOTE_BODY,
|
||||
MmsDatabase.QUOTE_MISSING,
|
||||
MmsDatabase.QUOTE_ATTACHMENT,
|
||||
MmsDatabase.QUOTE_TYPE,
|
||||
MmsDatabase.QUOTE_MENTIONS,
|
||||
MmsDatabase.SHARED_CONTACTS,
|
||||
MmsDatabase.LINK_PREVIEWS,
|
||||
@@ -813,6 +815,7 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsDatabase.QUOTE_BODY,
|
||||
MmsDatabase.QUOTE_MISSING,
|
||||
MmsDatabase.QUOTE_ATTACHMENT,
|
||||
MmsDatabase.QUOTE_TYPE,
|
||||
MmsDatabase.QUOTE_MENTIONS,
|
||||
MmsDatabase.SHARED_CONTACTS,
|
||||
MmsDatabase.LINK_PREVIEWS,
|
||||
@@ -878,6 +881,7 @@ public class MmsSmsDatabase extends Database {
|
||||
mmsColumnsPresent.add(MmsDatabase.QUOTE_BODY);
|
||||
mmsColumnsPresent.add(MmsDatabase.QUOTE_MISSING);
|
||||
mmsColumnsPresent.add(MmsDatabase.QUOTE_ATTACHMENT);
|
||||
mmsColumnsPresent.add(MmsDatabase.QUOTE_TYPE);
|
||||
mmsColumnsPresent.add(MmsDatabase.QUOTE_MENTIONS);
|
||||
mmsColumnsPresent.add(MmsDatabase.SHARED_CONTACTS);
|
||||
mmsColumnsPresent.add(MmsDatabase.LINK_PREVIEWS);
|
||||
|
||||
@@ -195,8 +195,9 @@ object SignalDatabaseMigrations {
|
||||
private const val REMOVE_KNOWN_UNKNOWNS = 139
|
||||
private const val CDS_V2 = 140
|
||||
private const val GROUP_SERVICE_ID = 141
|
||||
private const val QUOTE_TYPE = 142
|
||||
|
||||
const val DATABASE_VERSION = 141
|
||||
const val DATABASE_VERSION = 142
|
||||
|
||||
@JvmStatic
|
||||
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
@@ -2528,6 +2529,10 @@ object SignalDatabaseMigrations {
|
||||
if (oldVersion < GROUP_SERVICE_ID) {
|
||||
db.execSQL("ALTER TABLE groups ADD COLUMN auth_service_id TEXT DEFAULT NULL")
|
||||
}
|
||||
|
||||
if (oldVersion < QUOTE_TYPE) {
|
||||
db.execSQL("ALTER TABLE mms ADD COLUMN quote_type INTEGER DEFAULT 0")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.components.mention.MentionAnnotation;
|
||||
import org.thoughtcrime.securesms.mms.QuoteModel;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
|
||||
@@ -13,25 +14,28 @@ import java.util.List;
|
||||
|
||||
public class Quote {
|
||||
|
||||
private final long id;
|
||||
private final RecipientId author;
|
||||
private final CharSequence text;
|
||||
private final boolean missing;
|
||||
private final SlideDeck attachment;
|
||||
private final List<Mention> mentions;
|
||||
private final long id;
|
||||
private final RecipientId author;
|
||||
private final CharSequence text;
|
||||
private final boolean missing;
|
||||
private final SlideDeck attachment;
|
||||
private final List<Mention> mentions;
|
||||
private final QuoteModel.Type quoteType;
|
||||
|
||||
public Quote(long id,
|
||||
@NonNull RecipientId author,
|
||||
@Nullable CharSequence text,
|
||||
boolean missing,
|
||||
@NonNull SlideDeck attachment,
|
||||
@NonNull List<Mention> mentions)
|
||||
@NonNull List<Mention> mentions,
|
||||
@NonNull QuoteModel.Type quoteType)
|
||||
{
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.missing = missing;
|
||||
this.attachment = attachment;
|
||||
this.mentions = mentions;
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.missing = missing;
|
||||
this.attachment = attachment;
|
||||
this.mentions = mentions;
|
||||
this.quoteType = quoteType;
|
||||
|
||||
SpannableString spannable = new SpannableString(text);
|
||||
MentionAnnotation.setMentionAnnotations(spannable, mentions);
|
||||
@@ -40,7 +44,7 @@ public class Quote {
|
||||
}
|
||||
|
||||
public @NonNull Quote withAttachment(@NonNull SlideDeck updatedAttachment) {
|
||||
return new Quote(id, author, text, missing, updatedAttachment, mentions);
|
||||
return new Quote(id, author, text, missing, updatedAttachment, mentions, quoteType);
|
||||
}
|
||||
|
||||
|
||||
@@ -63,4 +67,8 @@ public class Quote {
|
||||
public @NonNull SlideDeck getAttachment() {
|
||||
return attachment;
|
||||
}
|
||||
|
||||
public @NonNull QuoteModel.Type getQuoteType() {
|
||||
return quoteType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
import org.thoughtcrime.securesms.mms.QuoteModel;
|
||||
import org.thoughtcrime.securesms.net.NotPushRegisteredException;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
@@ -303,6 +304,7 @@ public abstract class PushSendJob extends SendJob {
|
||||
String quoteBody = message.getOutgoingQuote().getText();
|
||||
RecipientId quoteAuthor = message.getOutgoingQuote().getAuthor();
|
||||
List<SignalServiceDataMessage.Mention> quoteMentions = getMentionsFor(message.getOutgoingQuote().getMentions());
|
||||
QuoteModel.Type quoteType = message.getOutgoingQuote().getType();
|
||||
List<SignalServiceDataMessage.Quote.QuotedAttachment> quoteAttachments = new LinkedList<>();
|
||||
List<Attachment> filteredAttachments = Stream.of(message.getOutgoingQuote().getAttachments())
|
||||
.filterNot(a -> MediaUtil.isViewOnceType(a.getContentType()))
|
||||
@@ -351,7 +353,7 @@ public abstract class PushSendJob extends SendJob {
|
||||
|
||||
if (quoteAuthorRecipient.isMaybeRegistered()) {
|
||||
SignalServiceAddress quoteAddress = RecipientUtil.toSignalServiceAddress(context, quoteAuthorRecipient);
|
||||
return Optional.of(new SignalServiceDataMessage.Quote(quoteId, quoteAddress, quoteBody, quoteAttachments, quoteMentions));
|
||||
return Optional.of(new SignalServiceDataMessage.Quote(quoteId, quoteAddress, quoteBody, quoteAttachments, quoteMentions, quoteType.getDataMessageType()));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -1565,7 +1565,7 @@ public final class MessageContentProcessor {
|
||||
}
|
||||
|
||||
parentStoryId = new ParentStoryId.DirectReply(storyMessageId.getId());
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, displayText, false, story.getSlideDeck().asAttachments(), Collections.emptyList());
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, displayText, false, story.getSlideDeck().asAttachments(), Collections.emptyList(), QuoteModel.Type.NORMAL);
|
||||
expiresInMillis = TimeUnit.SECONDS.toMillis(message.getExpiresInSeconds());
|
||||
} else {
|
||||
warn(content.getTimestamp(), "Story has reactions disabled. Dropping reaction.");
|
||||
@@ -1656,7 +1656,7 @@ public final class MessageContentProcessor {
|
||||
displayText = story.getBody();
|
||||
}
|
||||
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, displayText, false, story.getSlideDeck().asAttachments(), Collections.emptyList());
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, displayText, false, story.getSlideDeck().asAttachments(), Collections.emptyList(), QuoteModel.Type.NORMAL);
|
||||
expiresInMillis = TimeUnit.SECONDS.toMillis(message.getExpiresInSeconds());
|
||||
} else {
|
||||
warn(content.getTimestamp(), "Story has replies disabled. Dropping reply.");
|
||||
@@ -1929,7 +1929,7 @@ public final class MessageContentProcessor {
|
||||
quoteBody = story.getBody();
|
||||
}
|
||||
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, quoteBody, false, story.getSlideDeck().asAttachments(), Collections.emptyList());
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, quoteBody, false, story.getSlideDeck().asAttachments(), Collections.emptyList(), QuoteModel.Type.NORMAL);
|
||||
expiresInMillis = TimeUnit.SECONDS.toMillis(message.getExpirationStartTimestamp());
|
||||
} else {
|
||||
warn(envelopeTimestamp, "Story has replies disabled. Dropping reply.");
|
||||
@@ -2722,7 +2722,7 @@ public final class MessageContentProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.of(new QuoteModel(quote.get().getId(), author, message.getBody(), false, attachments, mentions));
|
||||
return Optional.of(new QuoteModel(quote.get().getId(), author, message.getBody(), false, attachments, mentions, QuoteModel.Type.fromDataMessageType(quote.get().getType())));
|
||||
} else if (message != null) {
|
||||
warn("Found the target for the quote, but it's flagged as remotely deleted.");
|
||||
}
|
||||
@@ -2730,11 +2730,12 @@ public final class MessageContentProcessor {
|
||||
warn("Didn't find matching message record...");
|
||||
|
||||
return Optional.of(new QuoteModel(quote.get().getId(),
|
||||
author,
|
||||
quote.get().getText(),
|
||||
true,
|
||||
PointerAttachment.forPointers(quote.get().getAttachments()),
|
||||
getMentions(quote.get().getMentions())));
|
||||
author,
|
||||
quote.get().getText(),
|
||||
true,
|
||||
PointerAttachment.forPointers(quote.get().getAttachments()),
|
||||
getMentions(quote.get().getMentions()),
|
||||
QuoteModel.Type.fromDataMessageType(quote.get().getType())));
|
||||
}
|
||||
|
||||
private Optional<Attachment> getStickerAttachment(Optional<SignalServiceDataMessage.Sticker> sticker) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import androidx.annotation.Nullable;
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.database.model.Mention;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -19,14 +20,23 @@ public class QuoteModel {
|
||||
private final boolean missing;
|
||||
private final List<Attachment> attachments;
|
||||
private final List<Mention> mentions;
|
||||
private final Type type;
|
||||
|
||||
public QuoteModel(long id, @NonNull RecipientId author, String text, boolean missing, @Nullable List<Attachment> attachments, @Nullable List<Mention> mentions) {
|
||||
public QuoteModel(long id,
|
||||
@NonNull RecipientId author,
|
||||
String text,
|
||||
boolean missing,
|
||||
@Nullable List<Attachment> attachments,
|
||||
@Nullable List<Mention> mentions,
|
||||
@NonNull Type type)
|
||||
{
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.text = text;
|
||||
this.missing = missing;
|
||||
this.attachments = attachments;
|
||||
this.mentions = mentions != null ? mentions : Collections.emptyList();
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
@@ -52,4 +62,49 @@ public class QuoteModel {
|
||||
public @NonNull List<Mention> getMentions() {
|
||||
return mentions;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
NORMAL(0, SignalServiceDataMessage.Quote.Type.NORMAL),
|
||||
GIFT_BADGE(1, SignalServiceDataMessage.Quote.Type.GIFT_BADGE);
|
||||
|
||||
private final int code;
|
||||
private final SignalServiceDataMessage.Quote.Type dataMessageType;
|
||||
|
||||
Type(int code, @NonNull SignalServiceDataMessage.Quote.Type dataMessageType) {
|
||||
this.code = code;
|
||||
this.dataMessageType = dataMessageType;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public @NonNull SignalServiceDataMessage.Quote.Type getDataMessageType() {
|
||||
return dataMessageType;
|
||||
}
|
||||
|
||||
public static Type fromCode(int code) {
|
||||
for (final Type value : values()) {
|
||||
if (value.code == code) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid code: " + code);
|
||||
}
|
||||
|
||||
public static Type fromDataMessageType(@NonNull SignalServiceDataMessage.Quote.Type dataMessageType) {
|
||||
for (final Type value : values()) {
|
||||
if (value.dataMessageType == dataMessageType) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.components.emoji.MediaKeyboard
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.Mention
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
import org.thoughtcrime.securesms.mms.QuoteModel
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.util.visible
|
||||
|
||||
@@ -106,7 +107,8 @@ class StoryReplyComposer @JvmOverloads constructor(
|
||||
false,
|
||||
messageRecord.slideDeck,
|
||||
null,
|
||||
null
|
||||
null,
|
||||
QuoteModel.Type.NORMAL
|
||||
)
|
||||
|
||||
quoteView.visible = true
|
||||
|
||||
@@ -55,7 +55,7 @@ class StoryDirectReplyRepository(context: Context) {
|
||||
StoryType.NONE,
|
||||
ParentStoryId.DirectReply(storyId),
|
||||
isReaction,
|
||||
QuoteModel(message.dateSent, quoteAuthor.id, message.body, false, message.slideDeck.asAttachments(), null),
|
||||
QuoteModel(message.dateSent, quoteAuthor.id, message.body, false, message.slideDeck.asAttachments(), null, QuoteModel.Type.NORMAL),
|
||||
emptyList(),
|
||||
emptyList(),
|
||||
emptyList(),
|
||||
|
||||
@@ -9,6 +9,7 @@ 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.GiftBadge
|
||||
import org.thoughtcrime.securesms.mms.QuoteModel
|
||||
import org.thoughtcrime.securesms.mms.TextSlide
|
||||
import org.thoughtcrime.securesms.stickers.StickerUrl
|
||||
|
||||
@@ -127,3 +128,10 @@ fun MessageRecord.isTextOnly(context: Context): Boolean {
|
||||
!hasGiftBadge()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the QuoteType for this record, as if it was being quoted.
|
||||
*/
|
||||
fun MessageRecord.getRecordQuoteType(): QuoteModel.Type {
|
||||
return if (hasGiftBadge()) QuoteModel.Type.GIFT_BADGE else QuoteModel.Type.NORMAL
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user