mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-11 18:43:49 +00:00
Align quote behaviour, move the media message outside of text bubble to simplify layouts (#935)
* refactor: remove text from quote model * refactor: add docs for TODOs where quote text should be refactored * refactor: remove the references to stored text in the quote and get the quote text from referenced DB lookup * refactor: drop the quote data from DB * fix: turns out we can't drop columns using this version of sqlite * fix: fixing an attachment download bug, fixing up UI issues with quotes and body text * feat: split off the message attachment UI from message bubble * refactor: replace media thumbnails with new designs * refactor: add debug drawing to troubleshoot swipe gesture * fix: fix the swipe to reply gesture drawing
This commit is contained in:
parent
b1e954084c
commit
d53752713e
@ -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<TransferControlView> 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<Slide> 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<Slide> 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) {
|
||||
}
|
||||
}
|
@ -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<Slide> 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);
|
||||
}
|
||||
}
|
@ -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<ViewGroup>(R.id.albumCellContainer).findViewById(R.id.album_cell_1)
|
||||
1 -> binding.albumCellContainer.findViewById<ViewGroup>(R.id.albumCellContainer).findViewById(R.id.album_cell_2)
|
||||
2 -> binding.albumCellContainer.findViewById<ViewGroup>(R.id.albumCellContainer).findViewById(R.id.album_cell_3)
|
||||
3 -> binding.albumCellContainer.findViewById<ViewGroup>(R.id.albumCellContainer).findViewById(R.id.album_cell_4)
|
||||
4 -> binding.albumCellContainer.findViewById<ViewGroup>(R.id.albumCellContainer).findViewById(R.id.album_cell_5)
|
||||
else -> throw Exception("Can't get thumbnail view for non-existent thumbnail at position: $position")
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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 =
|
||||
|
@ -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 {
|
||||
|
@ -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<Attachment?>? = 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<MessageRecord> = 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<String>(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<Attachment?>? =
|
||||
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;"
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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"/>
|
||||
|
||||
</FrameLayout>
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/album_thumbnail_root"
|
||||
android:layout_width="@dimen/album_total_width"
|
||||
android:layout_height="@dimen/album_3_total_height">
|
||||
@ -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"/>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_3"
|
||||
android:layout_width="@dimen/album_3_cell_size_small"
|
||||
android:layout_height="@dimen/album_3_cell_size_small"
|
||||
android:layout_gravity="right|end|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="@dimen/album_5_cell_size_small"
|
||||
android:layout_height="@dimen/album_5_cell_size_small"
|
||||
android:layout_gravity="end|bottom">
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_3"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<TextView
|
||||
tools:visibility="visible"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/album_cell_overflow_text"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:gravity="center"
|
||||
android:textSize="@dimen/text_size"
|
||||
android:textColor="@color/core_white"
|
||||
android:background="@color/transparent_black_70"
|
||||
tools:text="+2" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/album_thumbnail_root"
|
||||
android:layout_width="@dimen/album_total_width"
|
||||
android:layout_height="@dimen/album_4_total_height">
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_1"
|
||||
android:layout_width="@dimen/album_4_cell_size"
|
||||
android:layout_height="@dimen/album_4_cell_size"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_2"
|
||||
android:layout_width="@dimen/album_4_cell_size"
|
||||
android:layout_height="@dimen/album_4_cell_size"
|
||||
android:layout_gravity="right|end|top"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_3"
|
||||
android:layout_width="@dimen/album_4_cell_size"
|
||||
android:layout_height="@dimen/album_4_cell_size"
|
||||
android:layout_gravity="left|start|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_4"
|
||||
android:layout_width="@dimen/album_4_cell_size"
|
||||
android:layout_height="@dimen/album_4_cell_size"
|
||||
android:layout_gravity="right|end|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
</FrameLayout>
|
@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/album_thumbnail_root"
|
||||
android:layout_width="@dimen/album_total_width"
|
||||
android:layout_height="@dimen/album_5_total_height">
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_1"
|
||||
android:layout_width="@dimen/album_5_cell_size_big"
|
||||
android:layout_height="@dimen/album_5_cell_size_big"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_2"
|
||||
android:layout_width="@dimen/album_5_cell_size_big"
|
||||
android:layout_height="@dimen/album_5_cell_size_big"
|
||||
android:layout_gravity="right|end|top"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_3"
|
||||
android:layout_width="@dimen/album_5_cell_size_small"
|
||||
android:layout_height="@dimen/album_5_cell_size_small"
|
||||
android:layout_gravity="left|start|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_4"
|
||||
android:layout_width="@dimen/album_5_cell_size_small"
|
||||
android:layout_height="@dimen/album_5_cell_size_small"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_5"
|
||||
android:layout_width="@dimen/album_5_cell_size_small"
|
||||
android:layout_height="@dimen/album_5_cell_size_small"
|
||||
android:layout_gravity="right|end|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
</FrameLayout>
|
@ -1,61 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/album_thumbnail_root"
|
||||
android:layout_width="@dimen/album_total_width"
|
||||
android:layout_height="@dimen/album_5_total_height">
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_1"
|
||||
android:layout_width="@dimen/album_5_cell_size_big"
|
||||
android:layout_height="@dimen/album_5_cell_size_big"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_2"
|
||||
android:layout_width="@dimen/album_5_cell_size_big"
|
||||
android:layout_height="@dimen/album_5_cell_size_big"
|
||||
android:layout_gravity="right|end|top"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_3"
|
||||
android:layout_width="@dimen/album_5_cell_size_small"
|
||||
android:layout_height="@dimen/album_5_cell_size_small"
|
||||
android:layout_gravity="left|start|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_4"
|
||||
android:layout_width="@dimen/album_5_cell_size_small"
|
||||
android:layout_height="@dimen/album_5_cell_size_small"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="@dimen/album_5_cell_size_small"
|
||||
android:layout_height="@dimen/album_5_cell_size_small"
|
||||
android:layout_gravity="right|end|bottom">
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||
android:id="@+id/album_cell_5"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/album_cell_overflow_text"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:gravity="center"
|
||||
android:textSize="@dimen/text_size"
|
||||
android:textColor="@color/core_white"
|
||||
android:background="@color/transparent_black_40"
|
||||
tools:text="+2" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
@ -1,48 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView
|
||||
android:id="@+id/conversation_thumbnail_image"
|
||||
android:layout_width="@dimen/media_bubble_default_dimens"
|
||||
android:layout_height="@dimen/media_bubble_default_dimens"
|
||||
android:adjustViewBounds="true"
|
||||
android:clickable="false"
|
||||
android:longClickable="false"
|
||||
android:scaleType="fitCenter"
|
||||
android:contentDescription="@string/conversation_item__mms_image_description"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
app:thumbnail_radius="1dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.AlbumThumbnailView
|
||||
android:id="@+id/conversation_thumbnail_album"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="false"
|
||||
android:longClickable="false"
|
||||
android:contentDescription="@string/conversation_item__mms_image_description"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/conversation_thumbnail_shade"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:visibility="gone"
|
||||
android:src="@drawable/image_shade" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.ConversationItemFooter
|
||||
android:id="@+id/conversation_thumbnail_footer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginStart="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginEnd="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_bottom_padding"
|
||||
app:footer_text_color="@android:color/white"
|
||||
app:footer_icon_color="@android:color/white"/>
|
||||
|
||||
</merge>
|
@ -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" />
|
||||
|
||||
<RelativeLayout
|
||||
tools:visibility="visible"
|
||||
android:id="@+id/quoteViewAttachmentPreviewContainer"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
@ -71,30 +71,27 @@
|
||||
android:textColor="@color/text"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone"
|
||||
android:maxWidth="240dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/quoteViewBodyTextView"
|
||||
app:layout_constraintEnd_toEndOf="@+id/quoteViewBodyTextView"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintStart_toEndOf="@+id/quoteStartBarrier"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
tools:text="Spiderman" />
|
||||
tools:text="@tools:sample/full_names" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/quoteViewBodyTextView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/medium_spacing"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="3"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/text"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/quoteStartBarrier"
|
||||
app:layout_constraintTop_toBottomOf="@+id/quoteViewAuthorTextView"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
android:maxWidth="240dp"
|
||||
tools:maxLines="1"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
@ -31,7 +31,7 @@
|
||||
android:layout_height="1dp"/>
|
||||
|
||||
<include
|
||||
tools:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
android:id="@+id/profilePictureView"
|
||||
layout="@layout/view_profile_picture"
|
||||
android:layout_marginBottom="@dimen/small_spacing"
|
||||
@ -44,6 +44,7 @@
|
||||
android:layout_gravity="center" />
|
||||
|
||||
<ImageView
|
||||
tools:visibility="visible"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/moderatorIconImageView"
|
||||
android:layout_width="16dp"
|
||||
@ -87,7 +88,7 @@
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.components.ExpirationTimerView
|
||||
tools:visibility="visible"
|
||||
android:visibility="gone"
|
||||
android:visibility="invisible"
|
||||
android:id="@+id/expirationTimerView"
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="12dp"
|
||||
|
@ -7,104 +7,120 @@
|
||||
android:id="@+id/mainContainerConstraint"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<!-- Content that will only show on its own -->
|
||||
<include layout="@layout/view_deleted_message"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/deletedMessageView"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/contentParent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
<include layout="@layout/view_untrusted_attachment"
|
||||
tools:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/untrustedView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
>
|
||||
<!-- Content that will only show on its own -->
|
||||
<include layout="@layout/view_deleted_message"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/deletedMessageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
<include layout="@layout/view_voice_message"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/voiceMessageView"
|
||||
android:layout_width="160dp"
|
||||
android:layout_height="36dp"/>
|
||||
<include layout="@layout/view_untrusted_attachment"
|
||||
tools:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/untrustedView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<include layout="@layout/view_open_group_invitation"
|
||||
tools:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/openGroupInvitationView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
<include layout="@layout/view_voice_message"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/voiceMessageView"
|
||||
android:layout_width="160dp"
|
||||
android:layout_height="36dp"/>
|
||||
|
||||
<include layout="@layout/view_document"
|
||||
tools:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/documentView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
<include layout="@layout/view_open_group_invitation"
|
||||
tools:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/openGroupInvitationView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- Content that will show with other elements -->
|
||||
<include layout="@layout/view_document"
|
||||
tools:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/documentView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<include layout="@layout/view_quote"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:visibility="visible"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/quoteView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
<org.thoughtcrime.securesms.conversation.v2.messages.LinkPreviewView
|
||||
app:layout_constraintTop_toBottomOf="@+id/quoteView"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/linkPreviewView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
app:barrierAllowsGoneWidgets="true"
|
||||
android:id="@+id/bodyBarrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="end"
|
||||
app:constraint_referenced_ids="albumThumbnailView,linkPreviewView,quoteView,voiceMessageView"/>
|
||||
<!-- Content that will show with other elements -->
|
||||
|
||||
<include layout="@layout/view_quote"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:visibility="visible"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/quoteView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.messages.LinkPreviewView
|
||||
app:layout_constraintTop_toBottomOf="@+id/quoteView"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/linkPreviewView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
app:barrierAllowsGoneWidgets="true"
|
||||
android:id="@+id/bodyBarrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="end"
|
||||
app:constraint_referenced_ids="linkPreviewView,quoteView,voiceMessageView"/>
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/bodyTopBarrier"
|
||||
app:constraint_referenced_ids="linkPreviewView,quoteView"
|
||||
app:barrierDirection="bottom"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
tools:visibility="visible"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@+id/bodyTopBarrier"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:maxWidth="300dp"
|
||||
android:paddingHorizontal="12dp"
|
||||
android:paddingVertical="@dimen/small_spacing"
|
||||
android:id="@+id/bodyTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<org.thoughtcrime.securesms.conversation.v2.components.AlbumThumbnailView
|
||||
app:layout_constraintTop_toBottomOf="@+id/linkPreviewView"
|
||||
app:layout_constraintHorizontal_bias="1"
|
||||
android:visibility="visible"
|
||||
android:id="@+id/albumThumbnailView"
|
||||
android:layout_marginTop="4dp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/contentParent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/albumThumbnailView"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@+id/albumThumbnailView"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@+id/bodyBarrier"
|
||||
android:paddingHorizontal="12dp"
|
||||
android:paddingVertical="@dimen/small_spacing"
|
||||
android:id="@+id/bodyTextView"
|
||||
android:layout_width="0dp"
|
||||
android:maxWidth="300dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -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 ->
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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<Attachment>?)
|
||||
val author: Address,
|
||||
val text: String?,
|
||||
val missing: Boolean,
|
||||
val attachments: List<Attachment>?)
|
||||
|
Loading…
x
Reference in New Issue
Block a user