From 13c72779af28e833fc563a30fef596bf8da4df7d Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Sat, 11 Aug 2018 09:55:52 -0400 Subject: [PATCH] Visually note quotes for messages you don't have. We will now show a small footer under quotes for messages that you don't have locally. Also fixes #7850 --- res/drawable-hdpi/ic_broken_link.png | Bin 0 -> 327 bytes res/drawable-mdpi/ic_broken_link.png | Bin 0 -> 286 bytes res/drawable-xhdpi/ic_broken_link.png | Bin 0 -> 532 bytes res/drawable-xxhdpi/ic_broken_link.png | Bin 0 -> 628 bytes res/drawable-xxxhdpi/ic_broken_link.png | Bin 0 -> 970 bytes res/layout/quote_view.xml | 244 ++++++++++-------- res/values/attrs.xml | 2 + res/values/colors.xml | 2 + res/values/strings.xml | 4 +- res/values/themes.xml | 4 + .../securesms/ConversationFragment.java | 23 +- .../securesms/ConversationItem.java | 2 +- .../securesms/color/MaterialColor.java | 11 + .../securesms/components/InputPanel.java | 4 +- .../securesms/components/QuoteView.java | 26 +- .../securesms/database/MmsDatabase.java | 14 +- .../securesms/database/MmsSmsDatabase.java | 8 +- .../database/helpers/SQLCipherOpenHelper.java | 7 +- .../securesms/database/model/Quote.java | 8 +- .../securesms/jobs/PushDecryptJob.java | 3 +- .../securesms/mms/QuoteModel.java | 14 +- 21 files changed, 241 insertions(+), 135 deletions(-) create mode 100644 res/drawable-hdpi/ic_broken_link.png create mode 100644 res/drawable-mdpi/ic_broken_link.png create mode 100644 res/drawable-xhdpi/ic_broken_link.png create mode 100644 res/drawable-xxhdpi/ic_broken_link.png create mode 100644 res/drawable-xxxhdpi/ic_broken_link.png diff --git a/res/drawable-hdpi/ic_broken_link.png b/res/drawable-hdpi/ic_broken_link.png new file mode 100644 index 0000000000000000000000000000000000000000..f6e1c1550b84ceed2a09fc1b400d6e75eb342d7c GIT binary patch literal 327 zcmV-N0l5B&P)Px$0ZBwbR7ef<BuEFcd_^JGgV{OQF)m_Nc={;g2bBx;+iLn#M6XPx#*hxe|R5%gUl06QBKoEsNDJ(3wjFp9lptZNw(kqzgF-)vHhq3i0mL}`>0ZZ0k zLPEzTj~V98o1cX&o7@Q@EJhEFcn@BqinL-(*!LzNxCBRV1-As1$-LXyqn(2tDCuZi{V+nfsKt`Wkpvb;aaC>_;3aa}{tlGlE4VQVZ#>XK={#{E~8s z|8WAxbR5UpN@Bat`0}n3S948sUAt+HQvxsM-_8~BDAsz>UidPZq;Uy$oqOa^0PzC& klk~sykT~)diT-r#7m9Wnu+KAcAOHXW07*qoM6N<$g7SuWbpQYW literal 0 HcmV?d00001 diff --git a/res/drawable-xhdpi/ic_broken_link.png b/res/drawable-xhdpi/ic_broken_link.png new file mode 100644 index 0000000000000000000000000000000000000000..5d2c290ed7b1f6ea2180683b4af68f312fc81429 GIT binary patch literal 532 zcmV+v0_**WP)Px$&PhZ;R9Fe^ma$3$K@f)T1Z`Bbv52K9(@4NRm6#@_UAkc2B(+T%@dCE(17RnpF77H?sOCJ4&(;@o86t+`Df?mHVJ}CstWw~3Pe#)T)@%kI`9^i>#!H|FC`dc<6DWk0}v zEIYO(#%~(u3QkQh0zPt%)0zcioLhGJ0r_8omhJhXF|>i2#Yg5Lx45qiIz}G90v6U; z7=uk`I6hCWleZNql_(6ku%ObIW~QgyXHHkmzk%V@RoUl*bj*x z0XjgRh{HhG-{?02Eq-*YPo3FvxO66%3+1oGnkMwN5KinXdh5PSgA Wa>Mier`osx0000Px%E=fc|RA>e5m`hFqK@f%~B(h*>!onC9ti1+zAYRCYM%i!(FQJ|S_r@JtHj-%Y z`zQ3IrVuhOU?z4Yf2JSR-Cq|qGtDGPv>1UHff#`pff#`nMPRepOwgc3NX1bApQ3N{ z+PO^_c#5fYXA|It$Zy%xi++ho@!#)Eo(JHkXF@8zY=kc!t7bh<5_uN6K{K>KD^%9r z88Gx)r)}R2yOZu_Vetm11u`T#|&|rS+g(X#Sjbv?rSK8>9a~R%k2Ip&} zqio$%<&Zgav@UCUFX`o~6T;s)Z-I-JnXK^}w&>cm{UUtr5LTR^>yg*DN_}Lqruxo* z*oyHv?l3?HNT2zFbq79#2J*0p?!miFwEtUW0FKufff#`pff#{*5rJQSmuZ!J=~bEl O0000Px&gh@m}RCodHn!9ckF%*V(xhaGK3K}jAQ52y_p`rqUQX)dq@D3@FD5xk9Pk=b2p)N=don&jfUaBlgnPF* za1ahv-iHG=Ao5K46dVgoeFWW!fPOSoIV-O%pj@EfjHVd*e=Dq&PK&MlXzqDfvDC3_ zuU$~f%D0O|kID45xB{+&bKo>6G?soL`HAu^c-U^YRnLgXql{(yAGF{@0Z3dWwN z*rEM*sJ*ZbLlfX0cn9i~FBrQPbA-0iD=)i1_IJR2FcF(4SI@vX@CMW^gCOtw{F;ZU zT(ap#1}p$MTDJ_Eyz_sH%50iv@R^R&;FB9!V>vAHj=~2jGilP9L`J9Qbc+3b{-Nzv zf`cZQ$0VhVv;%r(&MFD-BqkmKl@}Alj`%NVpU005Wma%x3B=?H4X3iBs%fxUI^l(8 zmXAQb#$-7(ZcoRE)ySxo=%5M>%vCFS-xX}HM7XT`{knBJPlB(3LBV%zcVNj1^Yo3p zbBQ_D0(`!q%f1>>UJ7)UYRMU_tHfsC$;(&yE&>6$oZ&*J8-b2eoyl~rpupZh$je3f zE&>6$=_vTw(yzPrT1y-$o$YINq}9^fY)^dB@0~JLX17bKLy^ZJk&pSlo$(n5b?#S! zNK54;h{1tvd!HEdhLWHX{iNToTc=?igrxLq5M#q4AA1e1b_u5|IJ+ETpXd&J5E=$~ z=G^Zf)bm#BISMma&pHZUO$R4=_K(7!(cR@(sWKxXkFxCdypG~`GDh$;;;j$FESyfGMEM1Yep+UY9y^ zg-EA6G4MFhwUVxvnnqsNc)HHZp8GwbJxS2h_f#>W1ap=Ivf0y+JkVYx;T^@y18@PT zURLyt{}F6~XW%9Nc29gf_eVq?=!!ZdwOn2I$MYJj!q~`%mK~j~d<`4y|1>e~+g|^W zG*SuAzYi#~<#y@xE6_3bx4J<8=Bn5M`qfDPi{oUp6JBVkVD5r2e&k(1k{~R)XDclN s76FTZMZh9p5wHkY1S|p;fks8(FC$SP - - + android:orientation="vertical"> + android:orientation="horizontal"> - + + android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" + android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + android:orientation="vertical" + android:layout_weight="1"> - - - + tools:text="Peter Parker" /> + + + + + + + + + + + + - - - - - - - - - - - + android:layout_width="wrap_content" + android:layout_height="match_parent"> + android:id="@+id/quote_thumbnail" + android:layout_width="60dp" + android:layout_height="match_parent" + android:scaleType="centerCrop" + android:visibility="gone" + tools:visibility="gone" /> + + + + + + - + + + + + + + + + + diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 9bab467c4a..ca1ff5d318 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -127,6 +127,8 @@ + + diff --git a/res/values/colors.xml b/res/values/colors.xml index 64c95f7607..71a28a3ebe 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -29,6 +29,7 @@ #30000000 #40000000 #70000000 + #90000000 #05ffffff #10ffffff @@ -38,6 +39,7 @@ #60ffffff #70ffffff #aaffffff + #bbffffff #ddffffff #32000000 diff --git a/res/values/strings.xml b/res/values/strings.xml index 1eeed6991f..7c8f259e0b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -204,7 +204,8 @@ SMS Deleting Deleting messages... - Quoted message not found + Original message not found + Original message no longer available There is no browser installed on your device. @@ -793,6 +794,7 @@ Photo Document You + Original message not found Scroll to the bottom diff --git a/res/values/themes.xml b/res/values/themes.xml index d1115fec57..be3beacb76 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -243,6 +243,8 @@ @drawable/preference_divider_light + @color/core_light_60 + @drawable/ic_group_grey600_24dp @style/PreferenceThemeOverlay.Fix @@ -386,6 +388,8 @@ @drawable/preference_divider_dark + @color/core_dark_05 + @drawable/ic_group_white_24dp @style/PreferenceThemeOverlay.Fix @color/black diff --git a/src/org/thoughtcrime/securesms/ConversationFragment.java b/src/org/thoughtcrime/securesms/ConversationFragment.java index 9ec757fc3c..96a7b468f1 100644 --- a/src/org/thoughtcrime/securesms/ConversationFragment.java +++ b/src/org/thoughtcrime/securesms/ConversationFragment.java @@ -701,6 +701,12 @@ public class ConversationFragment extends Fragment return; } + if (messageRecord.getQuote().isOriginalMissing()) { + Log.i(TAG, "Clicked on a quote whose original message we never had."); + Toast.makeText(getContext(), R.string.ConversationFragment_quoted_message_not_found, Toast.LENGTH_SHORT).show(); + return; + } + new AsyncTask() { @Override protected Integer doInBackground(Void... voids) { @@ -711,8 +717,7 @@ public class ConversationFragment extends Fragment return DatabaseFactory.getMmsSmsDatabase(getContext()) .getQuotedMessagePosition(threadId, messageRecord.getQuote().getId(), - messageRecord.getQuote().getAuthor(), - getListAdapter().getItemCount()); + messageRecord.getQuote().getAuthor()); } @Override @@ -725,13 +730,15 @@ public class ConversationFragment extends Fragment if (position >= 0 && position < getListAdapter().getItemCount()) { list.scrollToPosition(position); getListAdapter().pulseHighlightItem(position); + } else if (position < 0) { + Log.w(TAG, "Tried to navigate to quoted message, but it was deleted."); + Toast.makeText(getContext(), R.string.ConversationFragment_quoted_message_no_longer_available, Toast.LENGTH_SHORT).show(); } else { - Toast.makeText(getContext(), getResources().getText(R.string.ConversationFragment_quoted_message_not_found), Toast.LENGTH_SHORT).show(); - if (position < 0) { - Log.w(TAG, "Tried to navigate to quoted message, but it was deleted."); - } else { - Log.w(TAG, "Tried to navigate to quoted message, but it was out of the bounds of the adapter."); - } + Log.i(TAG, "Quoted message was outside of the loaded range. Need to restart the loader."); + + firstLoad = true; + startingPosition = position; + getLoaderManager().restartLoader(0, Bundle.EMPTY, ConversationFragment.this); } } }.execute(); diff --git a/src/org/thoughtcrime/securesms/ConversationItem.java b/src/org/thoughtcrime/securesms/ConversationItem.java index f038c17809..2d6036110c 100644 --- a/src/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/org/thoughtcrime/securesms/ConversationItem.java @@ -598,7 +598,7 @@ public class ConversationItem extends LinearLayout if (current.isMms() && !current.isMmsNotification() && ((MediaMmsMessageRecord)current).getQuote() != null) { Quote quote = ((MediaMmsMessageRecord)current).getQuote(); assert quote != null; - quoteView.setQuote(glideRequests, quote.getId(), Recipient.from(context, quote.getAuthor(), true), quote.getText(), quote.getAttachment()); + quoteView.setQuote(glideRequests, quote.getId(), Recipient.from(context, quote.getAuthor(), true), quote.getText(), quote.isOriginalMissing(), quote.getAttachment()); quoteView.setVisibility(View.VISIBLE); quoteView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT; diff --git a/src/org/thoughtcrime/securesms/color/MaterialColor.java b/src/org/thoughtcrime/securesms/color/MaterialColor.java index dccab1e04f..d487abbc1f 100644 --- a/src/org/thoughtcrime/securesms/color/MaterialColor.java +++ b/src/org/thoughtcrime/securesms/color/MaterialColor.java @@ -107,6 +107,17 @@ public enum MaterialColor { : R.color.transparent_white_aa); } + public int toQuoteFooterColor(@NonNull Context context, boolean outgoing) { + if (outgoing) { + int color = toConversationColor(context); + int alpha = isDarkTheme(context) ? (int) (0.4 * 255) : (int) (0.6 * 255); + + return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color)); + } + return context.getResources().getColor(isDarkTheme(context) ? R.color.transparent_black_90 + : R.color.transparent_white_bb); + } + public boolean represents(Context context, int colorValue) { return context.getResources().getColor(conversationColorDark) == colorValue || context.getResources().getColor(conversationColorLight) == colorValue || diff --git a/src/org/thoughtcrime/securesms/components/InputPanel.java b/src/org/thoughtcrime/securesms/components/InputPanel.java index 8fc9aea9aa..031acc46b0 100644 --- a/src/org/thoughtcrime/securesms/components/InputPanel.java +++ b/src/org/thoughtcrime/securesms/components/InputPanel.java @@ -121,7 +121,7 @@ public class InputPanel extends LinearLayout } public void setQuote(@NonNull GlideRequests glideRequests, long id, @NonNull Recipient author, @NonNull String body, @NonNull SlideDeck attachments) { - this.quoteView.setQuote(glideRequests, id, author, body, attachments); + this.quoteView.setQuote(glideRequests, id, author, body, false, attachments); this.quoteView.setVisibility(View.VISIBLE); } @@ -131,7 +131,7 @@ public class InputPanel extends LinearLayout public Optional getQuote() { if (quoteView.getQuoteId() > 0 && quoteView.getVisibility() == View.VISIBLE) { - return Optional.of(new QuoteModel(quoteView.getQuoteId(), quoteView.getAuthor().getAddress(), quoteView.getBody(), quoteView.getAttachments())); + return Optional.of(new QuoteModel(quoteView.getQuoteId(), quoteView.getAuthor().getAddress(), quoteView.getBody(), false, quoteView.getAttachments())); } else { return Optional.absent(); } diff --git a/src/org/thoughtcrime/securesms/components/QuoteView.java b/src/org/thoughtcrime/securesms/components/QuoteView.java index 555c4d4400..dc6eba85fc 100644 --- a/src/org/thoughtcrime/securesms/components/QuoteView.java +++ b/src/org/thoughtcrime/securesms/components/QuoteView.java @@ -15,7 +15,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.TextView; import com.annimon.stream.Stream; @@ -42,7 +41,8 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener private static final int MESSAGE_TYPE_OUTGOING = 1; private static final int MESSAGE_TYPE_INCOMING = 2; - private ViewGroup rootView; + private ViewGroup mainView; + private ViewGroup footerView; private TextView authorView; private TextView bodyView; private ImageView quoteBarView; @@ -56,6 +56,7 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener private Recipient author; private String body; private TextView mediaDescriptionText; + private TextView missingLinkText; private SlideDeck attachments; private int messageType; private int largeCornerRadius; @@ -87,7 +88,8 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener private void initialize(@Nullable AttributeSet attrs) { inflate(getContext(), R.layout.quote_view, this); - this.rootView = findViewById(R.id.quote_root); + this.mainView = findViewById(R.id.quote_main); + this.footerView = findViewById(R.id.quote_missing_footer); this.authorView = findViewById(R.id.quote_author); this.bodyView = findViewById(R.id.quote_text); this.quoteBarView = findViewById(R.id.quote_bar); @@ -97,6 +99,7 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener this.attachmentNameView = findViewById(R.id.quote_attachment_name); this.dismissView = findViewById(R.id.quote_dismiss); this.mediaDescriptionText = findViewById(R.id.media_type); + this.missingLinkText = findViewById(R.id.quote_missing_text); this.largeCornerRadius = getResources().getDimensionPixelSize(R.dimen.quote_corner_radius_large); this.smallCornerRadius = getResources().getDimensionPixelSize(R.dimen.quote_corner_radius_bottom); @@ -116,6 +119,7 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener bodyView.setTextColor(primaryColor); attachmentNameView.setTextColor(primaryColor); mediaDescriptionText.setTextColor(secondaryColor); + missingLinkText.setTextColor(primaryColor); if (messageType == MESSAGE_TYPE_PREVIEW) { int radius = getResources().getDimensionPixelOffset(R.dimen.quote_corner_radius_preview); @@ -147,7 +151,13 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener } } - public void setQuote(GlideRequests glideRequests, long id, @NonNull Recipient author, @Nullable String body, @NonNull SlideDeck attachments) { + public void setQuote(GlideRequests glideRequests, + long id, + @NonNull Recipient author, + @Nullable String body, + boolean originalMissing, + @NonNull SlideDeck attachments) + { if (this.author != null) this.author.removeListener(this); this.id = id; @@ -159,6 +169,7 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener setQuoteAuthor(author); setQuoteText(body, attachments); setQuoteAttachment(glideRequests, attachments); + setQuoteMissingFooter(originalMissing); } public void setTopCornerSizes(boolean topLeftLarge, boolean topRightLarge) { @@ -194,7 +205,7 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener // We use the raw color resource because Android 4.x was struggling with tints here quoteBarView.setImageResource(author.getColor().toQuoteBarColorResource(getContext(), outgoing)); - rootView.setBackgroundColor(author.getColor().toQuoteBackgroundColor(getContext(), outgoing)); + mainView.setBackgroundColor(author.getColor().toQuoteBackgroundColor(getContext(), outgoing)); } private void setQuoteText(@Nullable String body, @NonNull SlideDeck attachments) { @@ -257,6 +268,11 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener } } + private void setQuoteMissingFooter(boolean missing) { + footerView.setVisibility(missing ? VISIBLE : GONE); + footerView.setBackgroundColor(author.getColor().toQuoteFooterColor(getContext(), messageType != MESSAGE_TYPE_INCOMING)); + } + public long getQuoteId() { return id; } diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java index 9b6357927a..031c934089 100644 --- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -103,6 +103,7 @@ public class MmsDatabase extends MessagingDatabase { static final String QUOTE_AUTHOR = "quote_author"; static final String QUOTE_BODY = "quote_body"; static final String QUOTE_ATTACHMENT = "quote_attachment"; + static final String QUOTE_MISSING = "quote_missing"; static final String SHARED_CONTACTS = "shared_contacts"; @@ -124,7 +125,7 @@ public class MmsDatabase extends MessagingDatabase { EXPIRE_STARTED + " INTEGER DEFAULT 0, " + NOTIFIED + " INTEGER DEFAULT 0, " + READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + QUOTE_ID + " INTEGER DEFAULT 0, " + QUOTE_AUTHOR + " TEXT, " + QUOTE_BODY + " TEXT, " + QUOTE_ATTACHMENT + " INTEGER DEFAULT -1, " + - SHARED_CONTACTS + " TEXT);"; + QUOTE_MISSING + " INTEGER DEFAULT 0, " + SHARED_CONTACTS + " TEXT);"; public static final String[] CREATE_INDEXS = { "CREATE INDEX IF NOT EXISTS mms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");", @@ -144,7 +145,7 @@ public class MmsDatabase extends MessagingDatabase { MESSAGE_SIZE, STATUS, TRANSACTION_ID, BODY, PART_COUNT, ADDRESS, 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, SHARED_CONTACTS, + EXPIRES_IN, EXPIRE_STARTED, NOTIFIED, QUOTE_ID, QUOTE_AUTHOR, QUOTE_BODY, QUOTE_ATTACHMENT, QUOTE_MISSING, SHARED_CONTACTS, "json_group_array(json_object(" + "'" + AttachmentDatabase.ROW_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + ", " + "'" + AttachmentDatabase.UNIQUE_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UNIQUE_ID + ", " + @@ -578,6 +579,7 @@ public class MmsDatabase extends MessagingDatabase { long quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_ID)); String quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_AUTHOR)); String quoteText = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_BODY)); + boolean quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(QUOTE_MISSING)) == 1; List quoteAttachments = Stream.of(associatedAttachments).filter(Attachment::isQuote).map(a -> (Attachment)a).toList(); List contacts = getSharedContacts(cursor, associatedAttachments); Set contactAttachments = new HashSet<>(Stream.of(contacts).map(Contact::getAvatarAttachment).filter(a -> a != null).toList()); @@ -587,7 +589,7 @@ public class MmsDatabase extends MessagingDatabase { QuoteModel quote = null; if (quoteId > 0 && (!TextUtils.isEmpty(quoteText) || !quoteAttachments.isEmpty())) { - quote = new QuoteModel(quoteId, Address.fromSerialized(quoteAuthor), quoteText, quoteAttachments); + quote = new QuoteModel(quoteId, Address.fromSerialized(quoteAuthor), quoteText, quoteMissing, quoteAttachments); } if (body != null && (Types.isGroupQuit(outboxType) || Types.isGroupUpdate(outboxType))) { @@ -739,6 +741,7 @@ public class MmsDatabase extends MessagingDatabase { contentValues.put(QUOTE_ID, retrieved.getQuote().getId()); contentValues.put(QUOTE_BODY, retrieved.getQuote().getText()); contentValues.put(QUOTE_AUTHOR, retrieved.getQuote().getAuthor().serialize()); + contentValues.put(QUOTE_MISSING, retrieved.getQuote().isOriginalMissing() ? 1 : 0); quoteAttachments = retrieved.getQuote().getAttachments(); } @@ -882,6 +885,7 @@ public class MmsDatabase extends MessagingDatabase { contentValues.put(QUOTE_ID, message.getOutgoingQuote().getId()); contentValues.put(QUOTE_AUTHOR, message.getOutgoingQuote().getAuthor().serialize()); contentValues.put(QUOTE_BODY, message.getOutgoingQuote().getText()); + contentValues.put(QUOTE_MISSING, message.getOutgoingQuote().isOriginalMissing() ? 1 : 0); quoteAttachments.addAll(message.getOutgoingQuote().getAttachments()); } @@ -1174,6 +1178,7 @@ public class MmsDatabase extends MessagingDatabase { new Quote(message.getOutgoingQuote().getId(), message.getOutgoingQuote().getAuthor(), message.getOutgoingQuote().getText(), + message.getOutgoingQuote().isOriginalMissing(), new SlideDeck(context, message.getOutgoingQuote().getAttachments())) : null, message.getSharedContacts()); @@ -1330,12 +1335,13 @@ public class MmsDatabase extends MessagingDatabase { long quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_ID)); String quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_AUTHOR)); String quoteText = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_BODY)); + boolean quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_MISSING)) == 1; List attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachment(cursor); List quoteAttachments = Stream.of(attachments).filter(Attachment::isQuote).toList(); SlideDeck quoteDeck = new SlideDeck(context, quoteAttachments); if (quoteId > 0 && !TextUtils.isEmpty(quoteAuthor)) { - return new Quote(quoteId, Address.fromExternal(context, quoteAuthor), quoteText, quoteDeck); + return new Quote(quoteId, Address.fromExternal(context, quoteAuthor), quoteText, quoteMissing, quoteDeck); } else { return null; } diff --git a/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java index be6cda38b3..803389f1e0 100644 --- a/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -66,6 +66,7 @@ public class MmsSmsDatabase extends Database { MmsDatabase.QUOTE_ID, MmsDatabase.QUOTE_AUTHOR, MmsDatabase.QUOTE_BODY, + MmsDatabase.QUOTE_MISSING, MmsDatabase.QUOTE_ATTACHMENT, MmsDatabase.SHARED_CONTACTS}; @@ -160,11 +161,11 @@ public class MmsSmsDatabase extends Database { DatabaseFactory.getMmsDatabase(context).incrementReceiptCount(syncMessageId, timestamp, false, true); } - public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull Address address, int limit) { + public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull Address address) { String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC"; String selection = MmsSmsColumns.THREAD_ID + " = " + threadId; - try (Cursor cursor = queryTables(new String[]{ MmsSmsColumns.NORMALIZED_DATE_SENT, MmsSmsColumns.ADDRESS }, selection, order, String.valueOf(limit))) { + try (Cursor cursor = queryTables(new String[]{ MmsSmsColumns.NORMALIZED_DATE_SENT, MmsSmsColumns.ADDRESS }, selection, order, null)) { String serializedAddress = address.serialize(); boolean isOwnNumber = Util.isOwnNumber(context, address); @@ -239,6 +240,7 @@ public class MmsSmsDatabase extends Database { MmsDatabase.QUOTE_ID, MmsDatabase.QUOTE_AUTHOR, MmsDatabase.QUOTE_BODY, + MmsDatabase.QUOTE_MISSING, MmsDatabase.QUOTE_ATTACHMENT, MmsDatabase.SHARED_CONTACTS}; @@ -262,6 +264,7 @@ public class MmsSmsDatabase extends Database { MmsDatabase.QUOTE_ID, MmsDatabase.QUOTE_AUTHOR, MmsDatabase.QUOTE_BODY, + MmsDatabase.QUOTE_MISSING, MmsDatabase.QUOTE_ATTACHMENT, MmsDatabase.SHARED_CONTACTS}; @@ -325,6 +328,7 @@ public class MmsSmsDatabase extends Database { mmsColumnsPresent.add(MmsDatabase.QUOTE_ID); mmsColumnsPresent.add(MmsDatabase.QUOTE_AUTHOR); mmsColumnsPresent.add(MmsDatabase.QUOTE_BODY); + mmsColumnsPresent.add(MmsDatabase.QUOTE_MISSING); mmsColumnsPresent.add(MmsDatabase.QUOTE_ATTACHMENT); mmsColumnsPresent.add(MmsDatabase.SHARED_CONTACTS); diff --git a/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 74dba2bdf0..2caa72319a 100644 --- a/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -50,8 +50,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { private static final int SHARED_CONTACTS = 8; private static final int FULL_TEXT_SEARCH = 9; private static final int BAD_IMPORT_CLEANUP = 10; + private static final int QUOTE_MISSING = 11; - private static final int DATABASE_VERSION = 10; + private static final int DATABASE_VERSION = 11; private static final String DATABASE_NAME = "signal.db"; private final Context context; @@ -235,6 +236,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { } } + if (oldVersion < QUOTE_MISSING) { + db.execSQL("ALTER TABLE mms ADD COLUMN quote_missing INTEGER DEFAULT 0"); + } + db.setTransactionSuccessful(); } finally { db.endTransaction(); diff --git a/src/org/thoughtcrime/securesms/database/model/Quote.java b/src/org/thoughtcrime/securesms/database/model/Quote.java index 8a05765e47..2c99d8f7f6 100644 --- a/src/org/thoughtcrime/securesms/database/model/Quote.java +++ b/src/org/thoughtcrime/securesms/database/model/Quote.java @@ -12,12 +12,14 @@ public class Quote { private final long id; private final Address author; private final String text; + private final boolean missing; private final SlideDeck attachment; - public Quote(long id, @NonNull Address author, @Nullable String text, @NonNull SlideDeck attachment) { + public Quote(long id, @NonNull Address author, @Nullable String text, boolean missing, @NonNull SlideDeck attachment) { this.id = id; this.author = author; this.text = text; + this.missing = missing; this.attachment = attachment; } @@ -33,6 +35,10 @@ public class Quote { return text; } + public boolean isOriginalMissing() { + return missing; + } + public @NonNull SlideDeck getAttachment() { return attachment; } diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 29225f0148..9b675a7b7d 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -891,13 +891,14 @@ public class PushDecryptJob extends ContextJob { attachments = ((MmsMessageRecord) message).getSlideDeck().asAttachments(); } - return Optional.of(new QuoteModel(quote.get().getId(), author, quote.get().getText(), attachments)); + return Optional.of(new QuoteModel(quote.get().getId(), author, message.getBody(), false, attachments)); } Log.w(TAG, "Didn't find matching message record..."); return Optional.of(new QuoteModel(quote.get().getId(), author, quote.get().getText(), + true, PointerAttachment.forPointers(quote.get().getAttachments()))); } diff --git a/src/org/thoughtcrime/securesms/mms/QuoteModel.java b/src/org/thoughtcrime/securesms/mms/QuoteModel.java index 1ed405d6e1..43eba6f39a 100644 --- a/src/org/thoughtcrime/securesms/mms/QuoteModel.java +++ b/src/org/thoughtcrime/securesms/mms/QuoteModel.java @@ -13,12 +13,14 @@ public class QuoteModel { private final long id; private final Address author; private final String text; + private final boolean missing; private final List attachments; - public QuoteModel(long id, Address author, String text, @Nullable List attachments) { - this.id = id; - this.author = author; - this.text = text; + public QuoteModel(long id, Address author, String text, boolean missing, @Nullable List attachments) { + this.id = id; + this.author = author; + this.text = text; + this.missing = missing; this.attachments = attachments; } @@ -34,6 +36,10 @@ public class QuoteModel { return text; } + public boolean isOriginalMissing() { + return missing; + } + public List getAttachments() { return attachments; }