Fix view-once sync and quote descriptions.
This commit is contained in:
parent
e2a48d1714
commit
fd7aa9ccfa
17 changed files with 87 additions and 38 deletions
|
@ -154,10 +154,9 @@ public class InputPanel extends LinearLayout
|
||||||
long id,
|
long id,
|
||||||
@NonNull Recipient author,
|
@NonNull Recipient author,
|
||||||
@NonNull String body,
|
@NonNull String body,
|
||||||
@NonNull SlideDeck attachments,
|
@NonNull SlideDeck attachments)
|
||||||
boolean isViewOnce)
|
|
||||||
{
|
{
|
||||||
this.quoteView.setQuote(glideRequests, id, author, body, false, attachments, isViewOnce);
|
this.quoteView.setQuote(glideRequests, id, author, body, false, attachments);
|
||||||
this.quoteView.setVisibility(View.VISIBLE);
|
this.quoteView.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
if (this.linkPreview.getVisibility() == View.VISIBLE) {
|
if (this.linkPreview.getVisibility() == View.VISIBLE) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||||
import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver;
|
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver;
|
||||||
|
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
|
|
||||||
|
@ -149,8 +150,7 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||||
@NonNull Recipient author,
|
@NonNull Recipient author,
|
||||||
@Nullable String body,
|
@Nullable String body,
|
||||||
boolean originalMissing,
|
boolean originalMissing,
|
||||||
@NonNull SlideDeck attachments,
|
@NonNull SlideDeck attachments)
|
||||||
boolean isViewOnce)
|
|
||||||
{
|
{
|
||||||
if (this.author != null) this.author.removeForeverObserver(this);
|
if (this.author != null) this.author.removeForeverObserver(this);
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||||
|
|
||||||
this.author.observeForever(this);
|
this.author.observeForever(this);
|
||||||
setQuoteAuthor(author);
|
setQuoteAuthor(author);
|
||||||
setQuoteText(body, attachments, isViewOnce);
|
setQuoteText(body, attachments);
|
||||||
setQuoteAttachment(glideRequests, attachments);
|
setQuoteAttachment(glideRequests, attachments);
|
||||||
setQuoteMissingFooter(originalMissing);
|
setQuoteMissingFooter(originalMissing);
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||||
mainView.setBackgroundColor(author.getColor().toQuoteBackgroundColor(getContext(), outgoing));
|
mainView.setBackgroundColor(author.getColor().toQuoteBackgroundColor(getContext(), outgoing));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setQuoteText(@Nullable String body, @NonNull SlideDeck attachments, boolean isViewOnce) {
|
private void setQuoteText(@Nullable String body, @NonNull SlideDeck attachments) {
|
||||||
if (!TextUtils.isEmpty(body) || !attachments.containsMediaSlide()) {
|
if (!TextUtils.isEmpty(body) || !attachments.containsMediaSlide()) {
|
||||||
bodyView.setVisibility(VISIBLE);
|
bodyView.setVisibility(VISIBLE);
|
||||||
bodyView.setText(body == null ? "" : body);
|
bodyView.setText(body == null ? "" : body);
|
||||||
|
@ -213,9 +213,10 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||||
List<Slide> imageSlides = Stream.of(attachments.getSlides()).filter(Slide::hasImage).limit(1).toList();
|
List<Slide> imageSlides = Stream.of(attachments.getSlides()).filter(Slide::hasImage).limit(1).toList();
|
||||||
List<Slide> videoSlides = Stream.of(attachments.getSlides()).filter(Slide::hasVideo).limit(1).toList();
|
List<Slide> videoSlides = Stream.of(attachments.getSlides()).filter(Slide::hasVideo).limit(1).toList();
|
||||||
List<Slide> stickerSlides = Stream.of(attachments.getSlides()).filter(Slide::hasSticker).limit(1).toList();
|
List<Slide> stickerSlides = Stream.of(attachments.getSlides()).filter(Slide::hasSticker).limit(1).toList();
|
||||||
|
List<Slide> viewOnceSlides = Stream.of(attachments.getSlides()).filter(Slide::hasViewOnce).limit(1).toList();
|
||||||
|
|
||||||
// Given that most types have images, we specifically check images last
|
// Given that most types have images, we specifically check images last
|
||||||
if (isViewOnce) {
|
if (!viewOnceSlides.isEmpty()) {
|
||||||
mediaDescriptionText.setText(R.string.QuoteView_media);
|
mediaDescriptionText.setText(R.string.QuoteView_media);
|
||||||
} else if (!audioSlides.isEmpty()) {
|
} else if (!audioSlides.isEmpty()) {
|
||||||
mediaDescriptionText.setText(R.string.QuoteView_audio);
|
mediaDescriptionText.setText(R.string.QuoteView_audio);
|
||||||
|
@ -233,10 +234,14 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||||
private void setQuoteAttachment(@NonNull GlideRequests glideRequests, @NonNull SlideDeck slideDeck) {
|
private void setQuoteAttachment(@NonNull GlideRequests glideRequests, @NonNull SlideDeck slideDeck) {
|
||||||
List<Slide> imageVideoSlides = Stream.of(slideDeck.getSlides()).filter(s -> s.hasImage() || s.hasVideo() || s.hasSticker()).limit(1).toList();
|
List<Slide> imageVideoSlides = Stream.of(slideDeck.getSlides()).filter(s -> s.hasImage() || s.hasVideo() || s.hasSticker()).limit(1).toList();
|
||||||
List<Slide> documentSlides = Stream.of(attachments.getSlides()).filter(Slide::hasDocument).limit(1).toList();
|
List<Slide> documentSlides = Stream.of(attachments.getSlides()).filter(Slide::hasDocument).limit(1).toList();
|
||||||
|
List<Slide> viewOnceSlides = Stream.of(attachments.getSlides()).filter(Slide::hasViewOnce).limit(1).toList();
|
||||||
|
|
||||||
attachmentVideoOverlayView.setVisibility(GONE);
|
attachmentVideoOverlayView.setVisibility(GONE);
|
||||||
|
|
||||||
if (!imageVideoSlides.isEmpty() && imageVideoSlides.get(0).getThumbnailUri() != null) {
|
if (!viewOnceSlides.isEmpty()) {
|
||||||
|
thumbnailView.setVisibility(GONE);
|
||||||
|
attachmentContainerView.setVisibility(GONE);
|
||||||
|
} else if (!imageVideoSlides.isEmpty() && imageVideoSlides.get(0).getThumbnailUri() != null) {
|
||||||
thumbnailView.setVisibility(VISIBLE);
|
thumbnailView.setVisibility(VISIBLE);
|
||||||
attachmentContainerView.setVisibility(GONE);
|
attachmentContainerView.setVisibility(GONE);
|
||||||
dismissView.setBackgroundResource(R.drawable.dismiss_background);
|
dismissView.setBackgroundResource(R.drawable.dismiss_background);
|
||||||
|
|
|
@ -2836,8 +2836,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||||
messageRecord.getDateSent(),
|
messageRecord.getDateSent(),
|
||||||
author,
|
author,
|
||||||
body,
|
body,
|
||||||
slideDeck,
|
slideDeck);
|
||||||
messageRecord.isViewOnce());
|
|
||||||
|
|
||||||
} else if (messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getLinkPreviews().isEmpty()) {
|
} else if (messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getLinkPreviews().isEmpty()) {
|
||||||
LinkPreview linkPreview = ((MmsMessageRecord) messageRecord).getLinkPreviews().get(0);
|
LinkPreview linkPreview = ((MmsMessageRecord) messageRecord).getLinkPreviews().get(0);
|
||||||
|
@ -2851,8 +2850,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||||
messageRecord.getDateSent(),
|
messageRecord.getDateSent(),
|
||||||
author,
|
author,
|
||||||
messageRecord.getBody(),
|
messageRecord.getBody(),
|
||||||
slideDeck,
|
slideDeck);
|
||||||
messageRecord.isViewOnce());
|
|
||||||
} else {
|
} else {
|
||||||
SlideDeck slideDeck = messageRecord.isMms() ? ((MmsMessageRecord) messageRecord).getSlideDeck() : new SlideDeck();
|
SlideDeck slideDeck = messageRecord.isMms() ? ((MmsMessageRecord) messageRecord).getSlideDeck() : new SlideDeck();
|
||||||
|
|
||||||
|
@ -2866,8 +2864,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||||
messageRecord.getDateSent(),
|
messageRecord.getDateSent(),
|
||||||
author,
|
author,
|
||||||
messageRecord.getBody(),
|
messageRecord.getBody(),
|
||||||
slideDeck,
|
slideDeck);
|
||||||
messageRecord.isViewOnce());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inputPanel.clickOnComposeInput();
|
inputPanel.clickOnComposeInput();
|
||||||
|
|
|
@ -1077,7 +1077,7 @@ public class ConversationFragment extends Fragment
|
||||||
.withMimeType(thumbnailSlide.getContentType())
|
.withMimeType(thumbnailSlide.getContentType())
|
||||||
.createForSingleSessionOnDisk(requireContext());
|
.createForSingleSessionOnDisk(requireContext());
|
||||||
|
|
||||||
DatabaseFactory.getAttachmentDatabase(requireContext()).deleteAttachmentFilesForMessage(messageRecord.getId());
|
DatabaseFactory.getAttachmentDatabase(requireContext()).deleteAttachmentFilesForViewOnceMessage(messageRecord.getId());
|
||||||
|
|
||||||
ApplicationContext.getInstance(requireContext())
|
ApplicationContext.getInstance(requireContext())
|
||||||
.getViewOnceMessageManager()
|
.getViewOnceMessageManager()
|
||||||
|
@ -1095,7 +1095,7 @@ public class ConversationFragment extends Fragment
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Failed to open view-once photo. Showing a toast and deleting the attachments for the message just in case.");
|
Log.w(TAG, "Failed to open view-once photo. Showing a toast and deleting the attachments for the message just in case.");
|
||||||
Toast.makeText(requireContext(), R.string.ConversationFragment_failed_to_open_message, Toast.LENGTH_SHORT).show();
|
Toast.makeText(requireContext(), R.string.ConversationFragment_failed_to_open_message, Toast.LENGTH_SHORT).show();
|
||||||
SignalExecutors.BOUNDED.execute(() -> DatabaseFactory.getAttachmentDatabase(requireContext()).deleteAttachmentFilesForMessage(messageRecord.getId()));
|
SignalExecutors.BOUNDED.execute(() -> DatabaseFactory.getAttachmentDatabase(requireContext()).deleteAttachmentFilesForViewOnceMessage(messageRecord.getId()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -855,7 +855,7 @@ public class ConversationItem extends LinearLayout implements BindableConversati
|
||||||
if (current.isMms() && !current.isMmsNotification() && ((MediaMmsMessageRecord)current).getQuote() != null) {
|
if (current.isMms() && !current.isMmsNotification() && ((MediaMmsMessageRecord)current).getQuote() != null) {
|
||||||
Quote quote = ((MediaMmsMessageRecord)current).getQuote();
|
Quote quote = ((MediaMmsMessageRecord)current).getQuote();
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
quoteView.setQuote(glideRequests, quote.getId(), Recipient.live(quote.getAuthor()).get(), quote.getText(), quote.isOriginalMissing(), quote.getAttachment(), messageRecord.isViewOnce());
|
quoteView.setQuote(glideRequests, quote.getId(), Recipient.live(quote.getAuthor()).get(), quote.getText(), quote.isOriginalMissing(), quote.getAttachment());
|
||||||
quoteView.setVisibility(View.VISIBLE);
|
quoteView.setVisibility(View.VISIBLE);
|
||||||
quoteView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
|
quoteView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||||
|
|
||||||
|
|
|
@ -320,8 +320,8 @@ public class AttachmentDatabase extends Database {
|
||||||
notifyAttachmentListeners();
|
notifyAttachmentListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAttachmentFilesForMessage(long mmsId) {
|
public void deleteAttachmentFilesForViewOnceMessage(long mmsId) {
|
||||||
Log.d(TAG, "[deleteAttachmentFilesForMessage] mmsId: " + mmsId);
|
Log.d(TAG, "[deleteAttachmentFilesForViewOnceMessage] mmsId: " + mmsId);
|
||||||
|
|
||||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
|
@ -355,6 +355,7 @@ public class AttachmentDatabase extends Database {
|
||||||
values.put(HEIGHT, 0);
|
values.put(HEIGHT, 0);
|
||||||
values.put(TRANSFER_STATE, TRANSFER_PROGRESS_DONE);
|
values.put(TRANSFER_STATE, TRANSFER_PROGRESS_DONE);
|
||||||
values.put(BLUR_HASH, (String) null);
|
values.put(BLUR_HASH, (String) null);
|
||||||
|
values.put(CONTENT_TYPE, MediaUtil.VIEW_ONCE);
|
||||||
|
|
||||||
database.update(TABLE_NAME, values, MMS_ID + " = ?", new String[] {mmsId + ""});
|
database.update(TABLE_NAME, values, MMS_ID + " = ?", new String[] {mmsId + ""});
|
||||||
notifyAttachmentListeners();
|
notifyAttachmentListeners();
|
||||||
|
@ -365,7 +366,6 @@ public class AttachmentDatabase extends Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void deleteAttachment(@NonNull AttachmentId id) {
|
public void deleteAttachment(@NonNull AttachmentId id) {
|
||||||
Log.d(TAG, "[deleteAttachment] attachmentId: " + id);
|
Log.d(TAG, "[deleteAttachment] attachmentId: " + id);
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,9 @@ public class ThreadRecord extends DisplayRecord {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getViewOnceDescription(@NonNull Context context, @Nullable String contentType) {
|
private String getViewOnceDescription(@NonNull Context context, @Nullable String contentType) {
|
||||||
if (MediaUtil.isVideoType(contentType)) {
|
if (MediaUtil.isViewOnceType(contentType)) {
|
||||||
|
return context.getString(R.string.ThreadRecord_disappearing_media);
|
||||||
|
} else if (MediaUtil.isVideoType(contentType)) {
|
||||||
return context.getString(R.string.ThreadRecord_disappearing_video);
|
return context.getString(R.string.ThreadRecord_disappearing_video);
|
||||||
} else {
|
} else {
|
||||||
return context.getString(R.string.ThreadRecord_disappearing_photo);
|
return context.getString(R.string.ThreadRecord_disappearing_photo);
|
||||||
|
|
|
@ -12,7 +12,6 @@ import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
|
||||||
import org.thoughtcrime.securesms.database.GroupReceiptDatabase.GroupReceiptInfo;
|
import org.thoughtcrime.securesms.database.GroupReceiptDatabase.GroupReceiptInfo;
|
||||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||||
import org.thoughtcrime.securesms.database.NoSuchMessageException;
|
import org.thoughtcrime.securesms.database.NoSuchMessageException;
|
||||||
|
@ -203,7 +202,7 @@ public class PushGroupSendJob extends PushSendJob {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.isViewOnce()) {
|
if (message.isViewOnce()) {
|
||||||
DatabaseFactory.getAttachmentDatabase(context).deleteAttachmentFilesForMessage(messageId);
|
DatabaseFactory.getAttachmentDatabase(context).deleteAttachmentFilesForViewOnceMessage(messageId);
|
||||||
}
|
}
|
||||||
} else if (!networkFailures.isEmpty()) {
|
} else if (!networkFailures.isEmpty()) {
|
||||||
throw new RetryLaterException();
|
throw new RetryLaterException();
|
||||||
|
|
|
@ -150,7 +150,7 @@ public class PushMediaSendJob extends PushSendJob {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.isViewOnce()) {
|
if (message.isViewOnce()) {
|
||||||
DatabaseFactory.getAttachmentDatabase(context).deleteAttachmentFilesForMessage(messageId);
|
DatabaseFactory.getAttachmentDatabase(context).deleteAttachmentFilesForViewOnceMessage(messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
log(TAG, "Sent message: " + messageId);
|
log(TAG, "Sent message: " + messageId);
|
||||||
|
|
|
@ -656,7 +656,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
||||||
handleReaction(content, message.getMessage());
|
handleReaction(content, message.getMessage());
|
||||||
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(getSyncMessageDestination(message));
|
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(getSyncMessageDestination(message));
|
||||||
threadId = threadId != -1 ? threadId : null;
|
threadId = threadId != -1 ? threadId : null;
|
||||||
} else if (message.getMessage().getAttachments().isPresent() || message.getMessage().getQuote().isPresent() || message.getMessage().getPreviews().isPresent() || message.getMessage().getSticker().isPresent()) {
|
} else if (message.getMessage().getAttachments().isPresent() || message.getMessage().getQuote().isPresent() || message.getMessage().getPreviews().isPresent() || message.getMessage().getSticker().isPresent() || message.getMessage().isViewOnce()) {
|
||||||
threadId = handleSynchronizeSentMediaMessage(message);
|
threadId = handleSynchronizeSentMediaMessage(message);
|
||||||
} else {
|
} else {
|
||||||
threadId = handleSynchronizeSentTextMessage(message);
|
threadId = handleSynchronizeSentTextMessage(message);
|
||||||
|
@ -742,7 +742,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
||||||
MessageRecord record = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(timestamp, author);
|
MessageRecord record = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(timestamp, author);
|
||||||
|
|
||||||
if (record != null && record.isMms()) {
|
if (record != null && record.isMms()) {
|
||||||
DatabaseFactory.getAttachmentDatabase(context).deleteAttachmentFilesForMessage(record.getId());
|
DatabaseFactory.getAttachmentDatabase(context).deleteAttachmentFilesForViewOnceMessage(record.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageNotifier.setLastDesktopActivityTimestamp(envelopeTimestamp);
|
MessageNotifier.setLastDesktopActivityTimestamp(envelopeTimestamp);
|
||||||
|
@ -842,7 +842,8 @@ public final class PushProcessMessageJob extends BaseJob {
|
||||||
Optional<List<Contact>> sharedContacts = getContacts(message.getMessage().getSharedContacts());
|
Optional<List<Contact>> sharedContacts = getContacts(message.getMessage().getSharedContacts());
|
||||||
Optional<List<LinkPreview>> previews = getLinkPreviews(message.getMessage().getPreviews(), message.getMessage().getBody().or(""));
|
Optional<List<LinkPreview>> previews = getLinkPreviews(message.getMessage().getPreviews(), message.getMessage().getBody().or(""));
|
||||||
boolean viewOnce = message.getMessage().isViewOnce();
|
boolean viewOnce = message.getMessage().isViewOnce();
|
||||||
List<Attachment> syncAttachments = viewOnce ? Collections.emptyList() : PointerAttachment.forPointers(message.getMessage().getAttachments());
|
List<Attachment> syncAttachments = viewOnce ? Collections.singletonList(new TombstoneAttachment(MediaUtil.VIEW_ONCE, false))
|
||||||
|
: PointerAttachment.forPointers(message.getMessage().getAttachments());
|
||||||
|
|
||||||
if (sticker.isPresent()) {
|
if (sticker.isPresent()) {
|
||||||
syncAttachments.add(sticker.get());
|
syncAttachments.add(sticker.get());
|
||||||
|
@ -1289,7 +1290,9 @@ public final class PushProcessMessageJob extends BaseJob {
|
||||||
if (message.isMms()) {
|
if (message.isMms()) {
|
||||||
MmsMessageRecord mmsMessage = (MmsMessageRecord) message;
|
MmsMessageRecord mmsMessage = (MmsMessageRecord) message;
|
||||||
|
|
||||||
if (!mmsMessage.isViewOnce()) {
|
if (mmsMessage.isViewOnce()) {
|
||||||
|
attachments.add(new TombstoneAttachment(MediaUtil.VIEW_ONCE, true));
|
||||||
|
} else {
|
||||||
attachments = mmsMessage.getSlideDeck().asAttachments();
|
attachments = mmsMessage.getSlideDeck().asAttachments();
|
||||||
|
|
||||||
if (attachments.isEmpty()) {
|
if (attachments.isEmpty()) {
|
||||||
|
@ -1298,8 +1301,6 @@ public final class PushProcessMessageJob extends BaseJob {
|
||||||
.map(lp -> lp.getThumbnail().get())
|
.map(lp -> lp.getThumbnail().get())
|
||||||
.toList());
|
.toList());
|
||||||
}
|
}
|
||||||
} else if (quote.get().getAttachments().size() > 0) {
|
|
||||||
attachments.add(new TombstoneAttachment(quote.get().getAttachments().get(0).getContentType(), true));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -217,12 +217,15 @@ public abstract class PushSendJob extends SendJob {
|
||||||
protected Optional<SignalServiceDataMessage.Quote> getQuoteFor(OutgoingMediaMessage message) {
|
protected Optional<SignalServiceDataMessage.Quote> getQuoteFor(OutgoingMediaMessage message) {
|
||||||
if (message.getOutgoingQuote() == null) return Optional.absent();
|
if (message.getOutgoingQuote() == null) return Optional.absent();
|
||||||
|
|
||||||
long quoteId = message.getOutgoingQuote().getId();
|
long quoteId = message.getOutgoingQuote().getId();
|
||||||
String quoteBody = message.getOutgoingQuote().getText();
|
String quoteBody = message.getOutgoingQuote().getText();
|
||||||
RecipientId quoteAuthor = message.getOutgoingQuote().getAuthor();
|
RecipientId quoteAuthor = message.getOutgoingQuote().getAuthor();
|
||||||
List<SignalServiceDataMessage.Quote.QuotedAttachment> quoteAttachments = new LinkedList<>();
|
List<SignalServiceDataMessage.Quote.QuotedAttachment> quoteAttachments = new LinkedList<>();
|
||||||
|
List<Attachment> filteredAttachments = Stream.of(message.getOutgoingQuote().getAttachments())
|
||||||
|
.filterNot(a -> MediaUtil.isViewOnceType(a.getContentType()))
|
||||||
|
.toList();
|
||||||
|
|
||||||
for (Attachment attachment : message.getOutgoingQuote().getAttachments()) {
|
for (Attachment attachment : filteredAttachments) {
|
||||||
BitmapUtil.ScaleResult thumbnailData = null;
|
BitmapUtil.ScaleResult thumbnailData = null;
|
||||||
SignalServiceAttachment thumbnail = null;
|
SignalServiceAttachment thumbnail = null;
|
||||||
String thumbnailType = MediaUtil.IMAGE_JPEG;
|
String thumbnailType = MediaUtil.IMAGE_JPEG;
|
||||||
|
|
|
@ -105,6 +105,10 @@ public abstract class Slide {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasViewOnce() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public @NonNull String getContentDescription() { return ""; }
|
public @NonNull String getContentDescription() { return ""; }
|
||||||
|
|
||||||
public @NonNull Attachment asAttachment() {
|
public @NonNull Attachment asAttachment() {
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class SlideDeck {
|
||||||
|
|
||||||
public boolean containsMediaSlide() {
|
public boolean containsMediaSlide() {
|
||||||
for (Slide slide : slides) {
|
for (Slide slide : slides) {
|
||||||
if (slide.hasImage() || slide.hasVideo() || slide.hasAudio() || slide.hasDocument() || slide.hasSticker()) {
|
if (slide.hasImage() || slide.hasVideo() || slide.hasAudio() || slide.hasDocument() || slide.hasSticker() || slide.hasViewOnce()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package org.thoughtcrime.securesms.mms;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||||
|
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slide used for attachments with contentType {@link MediaUtil#VIEW_ONCE}.
|
||||||
|
* Attachments will only get this type *after* they've been viewed, or if they were synced from a
|
||||||
|
* linked device. Incoming unviewed messages will have the appropriate image/video contentType.
|
||||||
|
*/
|
||||||
|
public class ViewOnceSlide extends Slide {
|
||||||
|
|
||||||
|
public ViewOnceSlide(@NonNull Context context, @NonNull Attachment attachment) {
|
||||||
|
super(context, attachment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasViewOnce() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,7 +54,7 @@ public class ViewOnceMessageManager extends TimedEventManager<ViewOnceExpiration
|
||||||
@Override
|
@Override
|
||||||
protected void executeEvent(@NonNull ViewOnceExpirationInfo event) {
|
protected void executeEvent(@NonNull ViewOnceExpirationInfo event) {
|
||||||
Log.i(TAG, "Deleting attachments for message " + event.getMessageId());
|
Log.i(TAG, "Deleting attachments for message " + event.getMessageId());
|
||||||
attachmentDatabase.deleteAttachmentFilesForMessage(event.getMessageId());
|
attachmentDatabase.deleteAttachmentFilesForViewOnceMessage(event.getMessageId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.thoughtcrime.securesms.mms.Slide;
|
||||||
import org.thoughtcrime.securesms.mms.StickerSlide;
|
import org.thoughtcrime.securesms.mms.StickerSlide;
|
||||||
import org.thoughtcrime.securesms.mms.TextSlide;
|
import org.thoughtcrime.securesms.mms.TextSlide;
|
||||||
import org.thoughtcrime.securesms.mms.VideoSlide;
|
import org.thoughtcrime.securesms.mms.VideoSlide;
|
||||||
|
import org.thoughtcrime.securesms.mms.ViewOnceSlide;
|
||||||
import org.thoughtcrime.securesms.providers.BlobProvider;
|
import org.thoughtcrime.securesms.providers.BlobProvider;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
@ -56,6 +57,7 @@ public class MediaUtil {
|
||||||
public static final String VIDEO_UNSPECIFIED = "video/*";
|
public static final String VIDEO_UNSPECIFIED = "video/*";
|
||||||
public static final String VCARD = "text/x-vcard";
|
public static final String VCARD = "text/x-vcard";
|
||||||
public static final String LONG_TEXT = "text/x-signal-plain";
|
public static final String LONG_TEXT = "text/x-signal-plain";
|
||||||
|
public static final String VIEW_ONCE = "application/x-signal-view-once";
|
||||||
|
|
||||||
public static SlideType getSlideTypeFromContentType(@NonNull String contentType) {
|
public static SlideType getSlideTypeFromContentType(@NonNull String contentType) {
|
||||||
if (isGif(contentType)) {
|
if (isGif(contentType)) {
|
||||||
|
@ -70,6 +72,8 @@ public class MediaUtil {
|
||||||
return SlideType.MMS;
|
return SlideType.MMS;
|
||||||
} else if (isLongTextType(contentType)) {
|
} else if (isLongTextType(contentType)) {
|
||||||
return SlideType.LONG_TEXT;
|
return SlideType.LONG_TEXT;
|
||||||
|
} else if (isViewOnceType(contentType)) {
|
||||||
|
return SlideType.VIEW_ONCE;
|
||||||
} else {
|
} else {
|
||||||
return SlideType.DOCUMENT;
|
return SlideType.DOCUMENT;
|
||||||
}
|
}
|
||||||
|
@ -87,6 +91,7 @@ public class MediaUtil {
|
||||||
case AUDIO : return new AudioSlide(context, attachment);
|
case AUDIO : return new AudioSlide(context, attachment);
|
||||||
case MMS : return new MmsSlide(context, attachment);
|
case MMS : return new MmsSlide(context, attachment);
|
||||||
case LONG_TEXT : return new TextSlide(context, attachment);
|
case LONG_TEXT : return new TextSlide(context, attachment);
|
||||||
|
case VIEW_ONCE : return new ViewOnceSlide(context, attachment);
|
||||||
case DOCUMENT : return new DocumentSlide(context, attachment);
|
case DOCUMENT : return new DocumentSlide(context, attachment);
|
||||||
default : throw new AssertionError();
|
default : throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
@ -269,6 +274,10 @@ public class MediaUtil {
|
||||||
return (null != contentType) && contentType.equals(LONG_TEXT);
|
return (null != contentType) && contentType.equals(LONG_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isViewOnceType(String contentType) {
|
||||||
|
return (null != contentType) && contentType.equals(VIEW_ONCE);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean hasVideoThumbnail(Uri uri) {
|
public static boolean hasVideoThumbnail(Uri uri) {
|
||||||
if (BlobProvider.isAuthority(uri) && MediaUtil.isVideo(BlobProvider.getMimeType(uri)) && Build.VERSION.SDK_INT >= 23) {
|
if (BlobProvider.isAuthority(uri) && MediaUtil.isVideo(BlobProvider.getMimeType(uri)) && Build.VERSION.SDK_INT >= 23) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -373,6 +382,7 @@ public class MediaUtil {
|
||||||
AUDIO,
|
AUDIO,
|
||||||
MMS,
|
MMS,
|
||||||
LONG_TEXT,
|
LONG_TEXT,
|
||||||
|
VIEW_ONCE,
|
||||||
DOCUMENT
|
DOCUMENT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -819,6 +819,7 @@
|
||||||
<string name="ThreadRecord_sticker">Sticker</string>
|
<string name="ThreadRecord_sticker">Sticker</string>
|
||||||
<string name="ThreadRecord_disappearing_photo">Disappearing photo</string>
|
<string name="ThreadRecord_disappearing_photo">Disappearing photo</string>
|
||||||
<string name="ThreadRecord_disappearing_video">Disappearing video</string>
|
<string name="ThreadRecord_disappearing_video">Disappearing video</string>
|
||||||
|
<string name="ThreadRecord_disappearing_media">Disappearing media</string>
|
||||||
<string name="ThreadRecord_s_is_on_signal">%s is on Signal!</string>
|
<string name="ThreadRecord_s_is_on_signal">%s is on Signal!</string>
|
||||||
<string name="ThreadRecord_disappearing_messages_disabled">Disappearing messages disabled</string>
|
<string name="ThreadRecord_disappearing_messages_disabled">Disappearing messages disabled</string>
|
||||||
<string name="ThreadRecord_disappearing_message_time_updated_to_s">Disappearing message time set to %s</string>
|
<string name="ThreadRecord_disappearing_message_time_updated_to_s">Disappearing message time set to %s</string>
|
||||||
|
|
Loading…
Add table
Reference in a new issue