diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/AlbumThumbnailView.java b/app/src/main/java/org/thoughtcrime/securesms/components/AlbumThumbnailView.java deleted file mode 100644 index fde2cd6b52..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/AlbumThumbnailView.java +++ /dev/null @@ -1,153 +0,0 @@ -package org.thoughtcrime.securesms.components; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.ViewGroup; -import android.widget.FrameLayout; -import android.widget.TextView; - -import androidx.annotation.ColorInt; -import androidx.annotation.IdRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.session.libsession.utilities.Stub; -import org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView; -import org.thoughtcrime.securesms.mms.GlideRequests; -import org.thoughtcrime.securesms.mms.Slide; -import org.thoughtcrime.securesms.mms.SlideClickListener; -import org.thoughtcrime.securesms.mms.SlidesClickedListener; - -import java.util.List; - -import network.loki.messenger.R; - -public class AlbumThumbnailView extends FrameLayout { - - private @Nullable SlideClickListener thumbnailClickListener; - private @Nullable SlidesClickedListener downloadClickListener; - - private int currentSizeClass; - - private ViewGroup albumCellContainer; - private Stub transferControls; - - private final SlideClickListener defaultThumbnailClickListener = (v, slide) -> { - if (thumbnailClickListener != null) { - thumbnailClickListener.onClick(v, slide); - } - }; - - private final OnLongClickListener defaultLongClickListener = v -> this.performLongClick(); - - public AlbumThumbnailView(@NonNull Context context) { - super(context); - initialize(); - } - - public AlbumThumbnailView(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - initialize(); - } - - private void initialize() { - inflate(getContext(), R.layout.album_thumbnail_view, this); - - albumCellContainer = findViewById(R.id.albumCellContainer); - transferControls = new Stub<>(findViewById(R.id.albumTransferControlsStub)); - } - - public void setSlides(@NonNull GlideRequests glideRequests, @NonNull List slides, boolean showControls) { - if (slides.size() < 2) { - throw new IllegalStateException("Provided less than two slides."); - } - - if (showControls) { - transferControls.get().setShowDownloadText(true); - transferControls.get().setSlides(slides); - transferControls.get().setDownloadClickListener(v -> { - if (downloadClickListener != null) { - downloadClickListener.onClick(v, slides); - } - }); - } else { - if (transferControls.resolved()) { - transferControls.get().setVisibility(GONE); - } - } - - int sizeClass = Math.min(slides.size(), 6); - - if (sizeClass != currentSizeClass) { - inflateLayout(sizeClass); - currentSizeClass = sizeClass; - } - - showSlides(glideRequests, slides); - } - - public void setCellBackgroundColor(@ColorInt int color) { - ViewGroup cellRoot = findViewById(R.id.album_thumbnail_root); - - if (cellRoot != null) { - for (int i = 0; i < cellRoot.getChildCount(); i++) { - cellRoot.getChildAt(i).setBackgroundColor(color); - } - } - } - - public void setThumbnailClickListener(@Nullable SlideClickListener listener) { - thumbnailClickListener = listener; - } - - public void setDownloadClickListener(@Nullable SlidesClickedListener listener) { - downloadClickListener = listener; - } - - private void inflateLayout(int sizeClass) { - albumCellContainer.removeAllViews(); - - switch (sizeClass) { - case 2: - inflate(getContext(), R.layout.album_thumbnail_2, albumCellContainer); - break; - case 3: - inflate(getContext(), R.layout.album_thumbnail_3, albumCellContainer); - break; - case 4: - inflate(getContext(), R.layout.album_thumbnail_4, albumCellContainer); - break; - case 5: - inflate(getContext(), R.layout.album_thumbnail_5, albumCellContainer); - break; - default: - inflate(getContext(), R.layout.album_thumbnail_many, albumCellContainer); - break; - } - } - - private void showSlides(@NonNull GlideRequests glideRequests, @NonNull List slides) { - setSlide(glideRequests, slides.get(0), R.id.album_cell_1); - setSlide(glideRequests, slides.get(1), R.id.album_cell_2); - - if (slides.size() >= 3) { - setSlide(glideRequests, slides.get(2), R.id.album_cell_3); - } - - if (slides.size() >= 4) { - setSlide(glideRequests, slides.get(3), R.id.album_cell_4); - } - - if (slides.size() >= 5) { - setSlide(glideRequests, slides.get(4), R.id.album_cell_5); - } - - if (slides.size() > 5) { - TextView text = findViewById(R.id.album_cell_overflow_text); - text.setText(getContext().getString(R.string.AlbumThumbnailView_plus, slides.size() - 5)); - } - } - - private void setSlide(@NonNull GlideRequests glideRequests, @NonNull Slide slide, @IdRes int id) { - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnail.java b/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnail.java deleted file mode 100644 index af9e766416..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnail.java +++ /dev/null @@ -1,158 +0,0 @@ -package org.thoughtcrime.securesms.components; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.widget.FrameLayout; -import android.widget.ImageView; - -import androidx.annotation.ColorInt; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.UiThread; - -import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView; -import org.thoughtcrime.securesms.mms.GlideRequests; - -import org.thoughtcrime.securesms.mms.Slide; -import org.thoughtcrime.securesms.mms.SlideClickListener; -import org.thoughtcrime.securesms.mms.SlidesClickedListener; - -import org.session.libsession.messaging.sending_receiving.attachments.Attachment; -import org.session.libsession.utilities.ThemeUtil; - -import java.util.List; - -import network.loki.messenger.R; - -public class ConversationItemThumbnail extends FrameLayout { - - private ThumbnailView thumbnail; - private AlbumThumbnailView album; - private ImageView shade; - private ConversationItemFooter footer; - private CornerMask cornerMask; - private Outliner outliner; - private boolean borderless; - - public ConversationItemThumbnail(Context context) { - super(context); - init(null); - } - - public ConversationItemThumbnail(Context context, AttributeSet attrs) { - super(context, attrs); - init(attrs); - } - - public ConversationItemThumbnail(final Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(attrs); - } - - private void init(@Nullable AttributeSet attrs) { - inflate(getContext(), R.layout.conversation_item_thumbnail, this); - - this.thumbnail = findViewById(R.id.conversation_thumbnail_image); - this.album = findViewById(R.id.conversation_thumbnail_album); - this.shade = findViewById(R.id.conversation_thumbnail_shade); - this.footer = findViewById(R.id.conversation_thumbnail_footer); - this.cornerMask = new CornerMask(this); - this.outliner = new Outliner(); - - outliner.setColor(ThemeUtil.getThemedColor(getContext(), R.attr.conversation_item_image_outline_color)); - - if (attrs != null) { - TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.ConversationItemThumbnail, 0, 0); - typedArray.recycle(); - } - } - - @Override - protected void dispatchDraw(Canvas canvas) { - super.dispatchDraw(canvas); - - if (!borderless) { - cornerMask.mask(canvas); - - if (album.getVisibility() != VISIBLE) { - outliner.draw(canvas); - } - } - } - - @Override - public void setFocusable(boolean focusable) { - thumbnail.setFocusable(focusable); - album.setFocusable(focusable); - } - - @Override - public void setClickable(boolean clickable) { - thumbnail.setClickable(clickable); - album.setClickable(clickable); - } - - @Override - public void setOnLongClickListener(@Nullable OnLongClickListener l) { - thumbnail.setOnLongClickListener(l); - album.setOnLongClickListener(l); - } - - public void showShade(boolean show) { - shade.setVisibility(show ? VISIBLE : GONE); - forceLayout(); - } - - public void setCorners(int topLeft, int topRight, int bottomRight, int bottomLeft) { - cornerMask.setRadii(topLeft, topRight, bottomRight, bottomLeft); - outliner.setRadii(topLeft, topRight, bottomRight, bottomLeft); - } - - public void setBorderless(boolean borderless) { - this.borderless = borderless; - } - - public ConversationItemFooter getFooter() { - return footer; - } - - @UiThread - public void setImageResource(@NonNull GlideRequests glideRequests, @NonNull List slides, - boolean showControls, boolean isPreview) - { - if (slides.size() == 1) { - thumbnail.setVisibility(VISIBLE); - album.setVisibility(GONE); - - Slide slide = slides.get(0); - Attachment attachment = slide.asAttachment(); - thumbnail.setImageResource(glideRequests, slide, showControls, isPreview, attachment.getWidth(), attachment.getHeight()); - thumbnail.setLoadIndicatorVisibile(slide.isInProgress()); - setTouchDelegate(thumbnail.getTouchDelegate()); - } else { - thumbnail.setVisibility(GONE); - album.setVisibility(VISIBLE); - - album.setSlides(glideRequests, slides, showControls); - setTouchDelegate(album.getTouchDelegate()); - } - } - - public void setConversationColor(@ColorInt int color) { - if (album.getVisibility() == VISIBLE) { - album.setCellBackgroundColor(color); - } - } - - public void setThumbnailClickListener(SlideClickListener listener) { - thumbnail.setThumbnailClickListener(listener); - album.setThumbnailClickListener(listener); - } - - public void setDownloadClickListener(SlidesClickedListener listener) { - thumbnail.setDownloadClickListener(listener); - album.setDownloadClickListener(listener); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/AlbumThumbnailView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/AlbumThumbnailView.kt index 3dc7c76985..8f0ddd8bef 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/AlbumThumbnailView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/AlbumThumbnailView.kt @@ -31,7 +31,7 @@ class AlbumThumbnailView : FrameLayout { private lateinit var binding: AlbumThumbnailViewBinding companion object { - const val MAX_ALBUM_DISPLAY_SIZE = 5 + const val MAX_ALBUM_DISPLAY_SIZE = 3 } // region Lifecycle @@ -130,18 +130,13 @@ class AlbumThumbnailView : FrameLayout { fun layoutRes(slideCount: Int) = when (slideCount) { 1 -> R.layout.album_thumbnail_1 // single 2 -> R.layout.album_thumbnail_2// two sidebyside - 3 -> R.layout.album_thumbnail_3// three stacked - 4 -> R.layout.album_thumbnail_4// four square - 5 -> R.layout.album_thumbnail_5// - else -> R.layout.album_thumbnail_many// five or more + else -> R.layout.album_thumbnail_3 // three stacked with additional text } fun getThumbnailView(position: Int): KThumbnailView = when (position) { 0 -> binding.albumCellContainer.findViewById(R.id.albumCellContainer).findViewById(R.id.album_cell_1) 1 -> binding.albumCellContainer.findViewById(R.id.albumCellContainer).findViewById(R.id.album_cell_2) 2 -> binding.albumCellContainer.findViewById(R.id.albumCellContainer).findViewById(R.id.album_cell_3) - 3 -> binding.albumCellContainer.findViewById(R.id.albumCellContainer).findViewById(R.id.album_cell_4) - 4 -> binding.albumCellContainer.findViewById(R.id.albumCellContainer).findViewById(R.id.album_cell_5) else -> throw Exception("Can't get thumbnail view for non-existent thumbnail at position: $position") } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt index 12f840ff76..f98fccd150 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt @@ -67,18 +67,11 @@ class QuoteView @JvmOverloads constructor(context: Context, attrs: AttributeSet? fun bind(authorPublicKey: String, body: String?, attachments: SlideDeck?, thread: Recipient, isOutgoingMessage: Boolean, isOpenGroupInvitation: Boolean, threadID: Long, isOriginalMissing: Boolean, glide: GlideRequests) { - // Reduce the max body text view line count to 2 if this is a group thread because - // we'll be showing the author text view and we don't want the overall quote view height - // to get too big. - binding.quoteViewBodyTextView.maxLines = if (thread.isGroupRecipient) 2 else 3 // Author - if (thread.isGroupRecipient) { - val author = contactDb.getContactWithSessionID(authorPublicKey) - val authorDisplayName = author?.displayName(Contact.contextForRecipient(thread)) ?: "${authorPublicKey.take(4)}...${authorPublicKey.takeLast(4)}" - binding.quoteViewAuthorTextView.text = authorDisplayName - binding.quoteViewAuthorTextView.setTextColor(getTextColor(isOutgoingMessage)) - } - binding.quoteViewAuthorTextView.isVisible = thread.isGroupRecipient + val author = contactDb.getContactWithSessionID(authorPublicKey) + val authorDisplayName = author?.displayName(Contact.contextForRecipient(thread)) ?: "${authorPublicKey.take(4)}...${authorPublicKey.takeLast(4)}" + binding.quoteViewAuthorTextView.text = authorDisplayName + binding.quoteViewAuthorTextView.setTextColor(getTextColor(isOutgoingMessage)) // Body binding.quoteViewBodyTextView.text = if (isOpenGroupInvitation) resources.getString(R.string.open_group_invitation_view__open_group_invitation) else MentionUtilities.highlightMentions((body ?: "").toSpannable(), threadID, context) binding.quoteViewBodyTextView.setTextColor(getTextColor(isOutgoingMessage)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt index b4af5a6139..4dc454dda1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt @@ -13,11 +13,11 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.view.MotionEvent import android.view.View -import android.view.ViewGroup import android.widget.LinearLayout import androidx.annotation.ColorInt import androidx.annotation.DrawableRes import androidx.appcompat.app.AppCompatActivity +import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.BlendModeColorFilterCompat import androidx.core.graphics.BlendModeCompat @@ -46,7 +46,6 @@ import org.thoughtcrime.securesms.mms.GlideRequests import org.thoughtcrime.securesms.util.SearchUtil import org.thoughtcrime.securesms.util.UiModeUtilities import org.thoughtcrime.securesms.util.getColorWithID -import org.thoughtcrime.securesms.util.toPx import java.util.Locale import kotlin.math.roundToInt @@ -76,7 +75,7 @@ class VisibleMessageContentView : LinearLayout { val color = ThemeUtil.getThemedColor(context, colorID) val filter = BlendModeColorFilterCompat.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_IN) background.colorFilter = filter - setBackground(background) + binding.contentParent.background = background val onlyBodyMessage = message is SmsMessageRecord val mediaThumbnailMessage = contactIsTrusted && message is MmsMessageRecord && message.slideDeck.thumbnailSlide != null @@ -94,17 +93,13 @@ class VisibleMessageContentView : LinearLayout { binding.deletedMessageView.root.isVisible = false } // clear the - binding.bodyTextView.text = null + binding.bodyTextView.text = "" binding.quoteView.root.isVisible = message is MmsMessageRecord && message.quote != null binding.linkPreviewView.isVisible = message is MmsMessageRecord && message.linkPreviews.isNotEmpty() - val linkPreviewLayout = binding.linkPreviewView.layoutParams - linkPreviewLayout.width = if (mediaThumbnailMessage) 0 else ViewGroup.LayoutParams.WRAP_CONTENT - binding.linkPreviewView.layoutParams = linkPreviewLayout - binding.untrustedView.root.isVisible = !contactIsTrusted && message is MmsMessageRecord && message.quote == null && message.linkPreviews.isEmpty() binding.voiceMessageView.root.isVisible = contactIsTrusted && message is MmsMessageRecord && message.slideDeck.audioSlide != null binding.documentView.root.isVisible = contactIsTrusted && message is MmsMessageRecord && message.slideDeck.documentSlide != null @@ -131,9 +126,7 @@ class VisibleMessageContentView : LinearLayout { delegate?.scrollToMessageIfPossible(quote.id) } } - val layoutParams = binding.quoteView.root.layoutParams as MarginLayoutParams val hasMedia = message.slideDeck.asAttachments().isNotEmpty() - binding.quoteView.root.minWidth = if (hasMedia) 0 else toPx(300,context.resources) } if (message is MmsMessageRecord) { @@ -198,6 +191,9 @@ class VisibleMessageContentView : LinearLayout { isStart = isStartOfMessageCluster, isEnd = isEndOfMessageCluster ) + val layoutParams = binding.albumThumbnailView.layoutParams as ConstraintLayout.LayoutParams + layoutParams.horizontalBias = if (message.isOutgoing) 1f else 0f + binding.albumThumbnailView.layoutParams = layoutParams onContentClick.add { event -> binding.albumThumbnailView.calculateHitObject(event, message, thread) } @@ -215,11 +211,6 @@ class VisibleMessageContentView : LinearLayout { binding.bodyTextView.isVisible = message.body.isNotEmpty() && !hideBody - // set it to use constraints if not only a text message, otherwise wrap content to whatever width it wants - val params = binding.bodyTextView.layoutParams - params.width = if (onlyBodyMessage || binding.barrierViewsGone()) ViewGroup.LayoutParams.MATCH_PARENT else 0 - binding.bodyTextView.layoutParams = params - if (message.body.isNotEmpty() && !hideBody) { val color = getTextColor(context, message) binding.bodyTextView.setTextColor(color) @@ -232,6 +223,9 @@ class VisibleMessageContentView : LinearLayout { } } } + val layoutParams = binding.contentParent.layoutParams as ConstraintLayout.LayoutParams + layoutParams.horizontalBias = if (message.isOutgoing) 1f else 0f + binding.contentParent.layoutParams = layoutParams } private fun ViewVisibleMessageContentBinding.barrierViewsGone(): Boolean = diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt index a8527b09b1..56d6051913 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt @@ -17,7 +17,9 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.core.os.bundleOf +import androidx.core.view.isInvisible import androidx.core.view.isVisible +import androidx.core.view.marginBottom import dagger.hilt.android.AndroidEntryPoint import network.loki.messenger.R import network.loki.messenger.databinding.ViewVisibleMessageBinding @@ -41,6 +43,7 @@ import org.thoughtcrime.securesms.util.getColorWithID import org.thoughtcrime.securesms.util.toDp import org.thoughtcrime.securesms.util.toPx import java.util.Date +import java.util.Locale import javax.inject.Inject import kotlin.math.abs import kotlin.math.min @@ -152,18 +155,15 @@ class VisibleMessageView : LinearLayout { binding.moderatorIconImageView.isVisible = !message.isOutgoing && isModerator } } - binding.senderNameTextView.isVisible = isStartOfMessageCluster - val context = - if (thread.isOpenGroupRecipient) ContactContext.OPEN_GROUP else ContactContext.REGULAR - binding.senderNameTextView.text = contact?.displayName(context) ?: senderSessionID - } else { - binding.senderNameTextView.visibility = View.GONE } + binding.senderNameTextView.isVisible = !message.isOutgoing && (isStartOfMessageCluster && (isGroupThread || snIsSelected)) + val contactContext = + if (thread.isOpenGroupRecipient) ContactContext.OPEN_GROUP else ContactContext.REGULAR + binding.senderNameTextView.text = contact?.displayName(contactContext) ?: senderSessionID // Date break - binding.dateBreakTextView.showDateBreak(message, previous) - // Timestamp - // binding.messageTimestampTextView.text = DateUtils.getDisplayFormattedTimeSpanString(context, Locale.getDefault(), message.timestamp) - // Set inter-message spacing + val showDateBreak = isStartOfMessageCluster || snIsSelected + binding.dateBreakTextView.text = if (showDateBreak) DateUtils.getDisplayFormattedTimeSpanString(context, Locale.getDefault(), message.timestamp) else null + binding.dateBreakTextView.isVisible = showDateBreak // Message status indicator val (iconID, iconColor) = getMessageStatusImage(message) if (iconID != null) { @@ -242,7 +242,7 @@ class VisibleMessageView : LinearLayout { container.layoutParams = containerParams if (message.expiresIn > 0 && !message.isPending) { binding.expirationTimerView.setColorFilter(ResourcesCompat.getColor(resources, R.color.text, context.theme)) - binding.expirationTimerView.isVisible = true + binding.expirationTimerView.isInvisible = false binding.expirationTimerView.setPercentComplete(0.0f) if (message.expireStarted > 0) { binding.expirationTimerView.setExpirationTime(message.expireStarted, message.expiresIn) @@ -265,7 +265,7 @@ class VisibleMessageView : LinearLayout { binding.expirationTimerView.setPercentComplete(0.0f) } } else { - binding.expirationTimerView.isVisible = false + binding.expirationTimerView.isInvisible = true } container.requestLayout() } @@ -279,15 +279,19 @@ class VisibleMessageView : LinearLayout { } override fun onDraw(canvas: Canvas) { + val spacing = context.resources.getDimensionPixelSize(R.dimen.small_spacing) + val iconSize = toPx(24, context.resources) + val left = binding.expirationTimerViewContainer.left + binding.messageContentView.right + spacing + val top = height - (binding.expirationTimerViewContainer.height / 2) - binding.profilePictureView.root.marginBottom - (iconSize / 2) + val right = left + iconSize + val bottom = top + iconSize + swipeToReplyIconRect.left = left + swipeToReplyIconRect.top = top + swipeToReplyIconRect.right = right + swipeToReplyIconRect.bottom = bottom + if (translationX < 0 && !binding.expirationTimerView.isVisible) { - val spacing = context.resources.getDimensionPixelSize(R.dimen.small_spacing) val threshold = swipeToReplyThreshold - val iconSize = toPx(24, context.resources) - val bottomVOffset = paddingBottom + binding.messageStatusImageView.height + (binding.messageContentView.height - iconSize) / 2 - swipeToReplyIconRect.left = binding.messageContentView.right - binding.messageContentView.paddingEnd + spacing - swipeToReplyIconRect.top = height - bottomVOffset - iconSize - swipeToReplyIconRect.right = binding.messageContentView.right - binding.messageContentView.paddingEnd + iconSize + spacing - swipeToReplyIconRect.bottom = height - bottomVOffset swipeToReplyIcon.bounds = swipeToReplyIconRect swipeToReplyIcon.alpha = (255.0f * (min(abs(translationX), threshold) / threshold)).roundToInt() } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt index fdb9d1c161..b7d6d42582 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt @@ -62,7 +62,6 @@ import org.thoughtcrime.securesms.database.SmsDatabase.InsertListener import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper 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.NotificationMmsMessageRecord import org.thoughtcrime.securesms.database.model.Quote import org.thoughtcrime.securesms.dependencies.DatabaseComponent.Companion.get @@ -479,7 +478,7 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa ) val quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_ID)) val quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_AUTHOR)) - val quoteText = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_BODY)) + val quoteText = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_BODY)) // TODO: this should be the referenced quote val quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(QUOTE_MISSING)) == 1 val quoteAttachments = associatedAttachments .filter { obj: DatabaseAttachment -> obj.isQuote } @@ -502,7 +501,7 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa quote = QuoteModel( quoteId, fromSerialized(quoteAuthor), - quoteText, + quoteText, // TODO: refactor this to use referenced quote quoteMissing, quoteAttachments ) @@ -669,7 +668,6 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa var quoteAttachments: List? = LinkedList() if (retrieved.quote != null) { contentValues.put(QUOTE_ID, retrieved.quote.id) - contentValues.put(QUOTE_BODY, retrieved.quote.text) contentValues.put(QUOTE_AUTHOR, retrieved.quote.author.serialize()) contentValues.put(QUOTE_MISSING, if (retrieved.quote.missing) 1 else 0) quoteAttachments = retrieved.quote.attachments @@ -816,7 +814,6 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa if (message.outgoingQuote != null) { contentValues.put(QUOTE_ID, message.outgoingQuote!!.id) contentValues.put(QUOTE_AUTHOR, message.outgoingQuote!!.author.serialize()) - contentValues.put(QUOTE_BODY, message.outgoingQuote!!.text) contentValues.put(QUOTE_MISSING, if (message.outgoingQuote!!.missing) 1 else 0) quoteAttachments.addAll(message.outgoingQuote!!.attachments!!) } @@ -949,31 +946,12 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa } val query = queryBuilder.toString() val db = databaseHelper.writableDatabase - val values = ContentValues(3) + val values = ContentValues(2) values.put(QUOTE_MISSING, 1) - values.put(QUOTE_BODY, "") values.put(QUOTE_AUTHOR, "") db!!.update(TABLE_NAME, values, query, null) } - fun deleteQuotedFromMessages(toDeleteRecord: MessageRecord?) { - if (toDeleteRecord == null) { - return - } - val query = "$THREAD_ID = ?" - rawQuery(query, arrayOf(toDeleteRecord.threadId.toString())).use { threadMmsCursor -> - val reader = readerFor(threadMmsCursor) - var messageRecord: MmsMessageRecord? = reader.next as MmsMessageRecord? - while (messageRecord != null) { - if (messageRecord.quote != null && toDeleteRecord.dateSent == messageRecord.quote?.id) { - setQuoteMissing(messageRecord.id) - } - messageRecord = reader.next as MmsMessageRecord? - } - reader.close() - } - } - /** * Delete all the messages in single queries where possible * @param messageIds a String array representation of regularly Long types representing message IDs @@ -997,13 +975,6 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa queue(Runnable { attachmentDatabase.deleteAttachmentsForMessages(messageIds) }) val groupReceiptDatabase = get(context).groupReceiptDatabase() groupReceiptDatabase.deleteRowsForMessages(messageIds) - val toDeleteList: MutableList = ArrayList() - getMessages(idsAsString).use { messageCursor -> - while (messageCursor.moveToNext()) { - toDeleteList.add(readerFor(messageCursor).current) - } - } - deleteQuotedFromMessages(toDeleteList) val database = databaseHelper.writableDatabase database.delete(TABLE_NAME, idsAsString, null) notifyConversationListListeners() @@ -1017,13 +988,8 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa queue(Runnable { attachmentDatabase.deleteAttachmentsForMessage(messageId) }) val groupReceiptDatabase = get(context).groupReceiptDatabase() groupReceiptDatabase.deleteRowsForMessage(messageId) - var toDelete: MessageRecord? - getMessage(messageId).use { messageCursor -> - toDelete = readerFor(messageCursor).next - } - deleteQuotedFromMessages(toDelete) val database = databaseHelper.writableDatabase - database!!.delete(TABLE_NAME, ID_WHERE, arrayOf(messageId.toString())) + database!!.delete(TABLE_NAME, ID_WHERE, arrayOf(messageId.toString())) val threadDeleted = get(context).threadDatabase().update(threadId, false) notifyConversationListeners(threadId) notifyStickerListeners() @@ -1287,7 +1253,7 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa if (message.outgoingQuote != null) Quote( message.outgoingQuote!!.id, message.outgoingQuote!!.author, - message.outgoingQuote!!.text, + message.outgoingQuote!!.text, // TODO: use the referenced message's content message.outgoingQuote!!.missing, SlideDeck(context, message.outgoingQuote!!.attachments!!) ) else null, @@ -1466,8 +1432,9 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa private fun getQuote(cursor: Cursor): Quote? { val quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_ID)) val quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_AUTHOR)) - val quoteText = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_BODY)) - val quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(QUOTE_MISSING)) == 1 + val retrievedQuote = get(context).mmsSmsDatabase().getMessageFor(quoteId, quoteAuthor) + val quoteText = retrievedQuote?.body + val quoteMissing = retrievedQuote == null val attachments = get(context).attachmentDatabase().getAttachment(cursor) val quoteAttachments: List? = Stream.of(attachments).filter { obj: DatabaseAttachment? -> obj!!.isQuote } @@ -1601,7 +1568,6 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa ")) AS " + AttachmentDatabase.ATTACHMENT_JSON_ALIAS ) private const val RAW_ID_WHERE: String = "$TABLE_NAME._id = ?" - private const val RAW_ID_IN: String = "$TABLE_NAME._id IN (?)" const val createMessageRequestResponseCommand: String = "ALTER TABLE $TABLE_NAME ADD COLUMN $MESSAGE_REQUEST_RESPONSE INTEGER DEFAULT 0;" } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index 3e8f37cc36..75f1352418 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -563,12 +563,6 @@ public class SmsDatabase extends MessagingDatabase { Log.i("MessageDatabase", "Deleting: " + messageId); SQLiteDatabase db = databaseHelper.getWritableDatabase(); long threadId = getThreadIdForMessage(messageId); - try { - SmsMessageRecord toDelete = getMessage(messageId); - DatabaseComponent.get(context).mmsDatabase().deleteQuotedFromMessages(toDelete); - } catch (NoSuchMessageException e) { - Log.e(TAG, "Couldn't find message record for messageId "+messageId, e); - } db.delete(TABLE_NAME, ID_WHERE, new String[] {messageId+""}); boolean threadDeleted = DatabaseComponent.get(context).threadDatabase().update(threadId, false); notifyConversationListeners(threadId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java index 63709a0e9e..9c0d6c5c35 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java @@ -258,7 +258,7 @@ public class DefaultMessageNotifier implements MessageNotifier { Cursor pushCursor = null; try { - telcoCursor = DatabaseComponent.get(context).mmsSmsDatabase().getUnread(); + telcoCursor = DatabaseComponent.get(context).mmsSmsDatabase().getUnread(); // TODO: add a notification specific lighter query here if ((telcoCursor == null || telcoCursor.isAfterLast()) || !TextSecurePreferences.hasSeenWelcomeScreen(context)) { diff --git a/app/src/main/res/layout/album_thumbnail_2.xml b/app/src/main/res/layout/album_thumbnail_2.xml index 9ac5866113..3bb4a6a367 100644 --- a/app/src/main/res/layout/album_thumbnail_2.xml +++ b/app/src/main/res/layout/album_thumbnail_2.xml @@ -17,7 +17,7 @@ android:id="@+id/album_cell_2" android:layout_width="@dimen/album_2_cell_width" android:layout_height="@dimen/album_2_total_height" - android:layout_gravity="right|end" + android:layout_gravity="end" app:thumbnail_radius="0dp"/> \ No newline at end of file diff --git a/app/src/main/res/layout/album_thumbnail_3.xml b/app/src/main/res/layout/album_thumbnail_3.xml index e758d65178..319f78ee78 100644 --- a/app/src/main/res/layout/album_thumbnail_3.xml +++ b/app/src/main/res/layout/album_thumbnail_3.xml @@ -1,7 +1,7 @@ - @@ -16,14 +16,34 @@ android:id="@+id/album_cell_2" android:layout_width="@dimen/album_3_cell_size_small" android:layout_height="@dimen/album_3_cell_size_small" - android:layout_gravity="right|end|top" + android:layout_gravity="end|top" app:thumbnail_radius="0dp"/> - + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/album_thumbnail_4.xml b/app/src/main/res/layout/album_thumbnail_4.xml deleted file mode 100644 index e2b4844c77..0000000000 --- a/app/src/main/res/layout/album_thumbnail_4.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/album_thumbnail_5.xml b/app/src/main/res/layout/album_thumbnail_5.xml deleted file mode 100644 index ba766ddd40..0000000000 --- a/app/src/main/res/layout/album_thumbnail_5.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/album_thumbnail_many.xml b/app/src/main/res/layout/album_thumbnail_many.xml deleted file mode 100644 index de60462995..0000000000 --- a/app/src/main/res/layout/album_thumbnail_many.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/conversation_item_thumbnail.xml b/app/src/main/res/layout/conversation_item_thumbnail.xml deleted file mode 100644 index a6f029745f..0000000000 --- a/app/src/main/res/layout/conversation_item_thumbnail.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - diff --git a/app/src/main/res/layout/view_quote.xml b/app/src/main/res/layout/view_quote.xml index 71ea481e7e..f5c1abfd14 100644 --- a/app/src/main/res/layout/view_quote.xml +++ b/app/src/main/res/layout/view_quote.xml @@ -6,7 +6,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/input_bar_background" - android:minWidth="300dp" android:minHeight="52dp" android:paddingVertical="12dp" android:paddingHorizontal="12dp" @@ -24,6 +23,7 @@ app:layout_constraintTop_toTopOf="parent" /> + tools:text="@tools:sample/full_names" /> diff --git a/app/src/main/res/layout/view_visible_message.xml b/app/src/main/res/layout/view_visible_message.xml index f7281c75f1..28377be50c 100644 --- a/app/src/main/res/layout/view_visible_message.xml +++ b/app/src/main/res/layout/view_visible_message.xml @@ -31,7 +31,7 @@ android:layout_height="1dp"/> - - - - + > + + - + - + - + - + - - - + + + + + + + + + + + + - + \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt index 70d08db019..799f91ea79 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt @@ -60,6 +60,15 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long) messageDataProvider.setAttachmentState(AttachmentState.FAILED, AttachmentId(attachmentID,0), databaseMessageID) } this.handlePermanentFailure(exception) + } else if (exception == Error.DuplicateData) { + attachment?.let { id -> + Log.d("AttachmentDownloadJob", "Setting attachment state = done from duplicate data") + messageDataProvider.setAttachmentState(AttachmentState.DONE, id, databaseMessageID) + } ?: run { + Log.d("AttachmentDownloadJob", "Setting attachment state = done from duplicate data") + messageDataProvider.setAttachmentState(AttachmentState.DONE, AttachmentId(attachmentID,0), databaseMessageID) + } + this.handleSuccess() } else { if (failureCount + 1 >= maxFailureCount) { attachment?.let { id -> diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt index 291658190a..04d896aeb3 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt @@ -30,7 +30,7 @@ class Quote() { fun from(signalQuote: SignalQuote?): Quote? { if (signalQuote == null) { return null } val attachmentID = (signalQuote.attachments?.firstOrNull() as? DatabaseAttachment)?.attachmentId?.rowId - return Quote(signalQuote.id, signalQuote.author.serialize(), signalQuote.text, attachmentID) + return Quote(signalQuote.id, signalQuote.author.serialize(), "", attachmentID) // TODO: re-add this } } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt index b824c55226..774287f459 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt @@ -254,9 +254,9 @@ fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, val messageInfo = messageDataProvider.getMessageForQuote(quote.id, author) if (messageInfo != null) { val attachments = if (messageInfo.second) messageDataProvider.getAttachmentsAndLinkPreviewFor(messageInfo.first) else ArrayList() - quoteModel = QuoteModel(quote.id, author, messageDataProvider.getMessageBodyFor(quote.id, quote.author), false, attachments) + quoteModel = QuoteModel(quote.id, author,null,false, attachments) } else { - quoteModel = QuoteModel(quote.id, author, quote.text, true, PointerAttachment.forPointers(proto.dataMessage.quote.attachmentsList)) + quoteModel = QuoteModel(quote.id, author,null, true, PointerAttachment.forPointers(proto.dataMessage.quote.attachmentsList)) } } // Parse link preview if needed diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/quotes/QuoteModel.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/quotes/QuoteModel.kt index ab47690db5..0764b35c32 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/quotes/QuoteModel.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/quotes/QuoteModel.kt @@ -4,7 +4,7 @@ import org.session.libsession.messaging.sending_receiving.attachments.Attachment import org.session.libsession.utilities.Address class QuoteModel(val id: Long, - val author: Address, - val text: String, - val missing: Boolean, - val attachments: List?) + val author: Address, + val text: String?, + val missing: Boolean, + val attachments: List?)