mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-30 14:20:47 +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
|
private lateinit var binding: AlbumThumbnailViewBinding
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val MAX_ALBUM_DISPLAY_SIZE = 5
|
const val MAX_ALBUM_DISPLAY_SIZE = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
// region Lifecycle
|
// region Lifecycle
|
||||||
@ -130,18 +130,13 @@ class AlbumThumbnailView : FrameLayout {
|
|||||||
fun layoutRes(slideCount: Int) = when (slideCount) {
|
fun layoutRes(slideCount: Int) = when (slideCount) {
|
||||||
1 -> R.layout.album_thumbnail_1 // single
|
1 -> R.layout.album_thumbnail_1 // single
|
||||||
2 -> R.layout.album_thumbnail_2// two sidebyside
|
2 -> R.layout.album_thumbnail_2// two sidebyside
|
||||||
3 -> R.layout.album_thumbnail_3// three stacked
|
else -> R.layout.album_thumbnail_3 // three stacked with additional text
|
||||||
4 -> R.layout.album_thumbnail_4// four square
|
|
||||||
5 -> R.layout.album_thumbnail_5//
|
|
||||||
else -> R.layout.album_thumbnail_many// five or more
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getThumbnailView(position: Int): KThumbnailView = when (position) {
|
fun getThumbnailView(position: Int): KThumbnailView = when (position) {
|
||||||
0 -> binding.albumCellContainer.findViewById<ViewGroup>(R.id.albumCellContainer).findViewById(R.id.album_cell_1)
|
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)
|
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)
|
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")
|
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,
|
fun bind(authorPublicKey: String, body: String?, attachments: SlideDeck?, thread: Recipient,
|
||||||
isOutgoingMessage: Boolean, isOpenGroupInvitation: Boolean, threadID: Long,
|
isOutgoingMessage: Boolean, isOpenGroupInvitation: Boolean, threadID: Long,
|
||||||
isOriginalMissing: Boolean, glide: GlideRequests) {
|
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
|
// Author
|
||||||
if (thread.isGroupRecipient) {
|
|
||||||
val author = contactDb.getContactWithSessionID(authorPublicKey)
|
val author = contactDb.getContactWithSessionID(authorPublicKey)
|
||||||
val authorDisplayName = author?.displayName(Contact.contextForRecipient(thread)) ?: "${authorPublicKey.take(4)}...${authorPublicKey.takeLast(4)}"
|
val authorDisplayName = author?.displayName(Contact.contextForRecipient(thread)) ?: "${authorPublicKey.take(4)}...${authorPublicKey.takeLast(4)}"
|
||||||
binding.quoteViewAuthorTextView.text = authorDisplayName
|
binding.quoteViewAuthorTextView.text = authorDisplayName
|
||||||
binding.quoteViewAuthorTextView.setTextColor(getTextColor(isOutgoingMessage))
|
binding.quoteViewAuthorTextView.setTextColor(getTextColor(isOutgoingMessage))
|
||||||
}
|
|
||||||
binding.quoteViewAuthorTextView.isVisible = thread.isGroupRecipient
|
|
||||||
// Body
|
// 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.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))
|
binding.quoteViewBodyTextView.setTextColor(getTextColor(isOutgoingMessage))
|
||||||
|
@ -13,11 +13,11 @@ import android.util.AttributeSet
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.core.graphics.BlendModeColorFilterCompat
|
import androidx.core.graphics.BlendModeColorFilterCompat
|
||||||
import androidx.core.graphics.BlendModeCompat
|
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.SearchUtil
|
||||||
import org.thoughtcrime.securesms.util.UiModeUtilities
|
import org.thoughtcrime.securesms.util.UiModeUtilities
|
||||||
import org.thoughtcrime.securesms.util.getColorWithID
|
import org.thoughtcrime.securesms.util.getColorWithID
|
||||||
import org.thoughtcrime.securesms.util.toPx
|
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@ -76,7 +75,7 @@ class VisibleMessageContentView : LinearLayout {
|
|||||||
val color = ThemeUtil.getThemedColor(context, colorID)
|
val color = ThemeUtil.getThemedColor(context, colorID)
|
||||||
val filter = BlendModeColorFilterCompat.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_IN)
|
val filter = BlendModeColorFilterCompat.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_IN)
|
||||||
background.colorFilter = filter
|
background.colorFilter = filter
|
||||||
setBackground(background)
|
binding.contentParent.background = background
|
||||||
|
|
||||||
val onlyBodyMessage = message is SmsMessageRecord
|
val onlyBodyMessage = message is SmsMessageRecord
|
||||||
val mediaThumbnailMessage = contactIsTrusted && message is MmsMessageRecord && message.slideDeck.thumbnailSlide != null
|
val mediaThumbnailMessage = contactIsTrusted && message is MmsMessageRecord && message.slideDeck.thumbnailSlide != null
|
||||||
@ -94,17 +93,13 @@ class VisibleMessageContentView : LinearLayout {
|
|||||||
binding.deletedMessageView.root.isVisible = false
|
binding.deletedMessageView.root.isVisible = false
|
||||||
}
|
}
|
||||||
// clear the
|
// clear the
|
||||||
binding.bodyTextView.text = null
|
binding.bodyTextView.text = ""
|
||||||
|
|
||||||
|
|
||||||
binding.quoteView.root.isVisible = message is MmsMessageRecord && message.quote != null
|
binding.quoteView.root.isVisible = message is MmsMessageRecord && message.quote != null
|
||||||
|
|
||||||
binding.linkPreviewView.isVisible = message is MmsMessageRecord && message.linkPreviews.isNotEmpty()
|
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.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.voiceMessageView.root.isVisible = contactIsTrusted && message is MmsMessageRecord && message.slideDeck.audioSlide != null
|
||||||
binding.documentView.root.isVisible = contactIsTrusted && message is MmsMessageRecord && message.slideDeck.documentSlide != null
|
binding.documentView.root.isVisible = contactIsTrusted && message is MmsMessageRecord && message.slideDeck.documentSlide != null
|
||||||
@ -131,9 +126,7 @@ class VisibleMessageContentView : LinearLayout {
|
|||||||
delegate?.scrollToMessageIfPossible(quote.id)
|
delegate?.scrollToMessageIfPossible(quote.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val layoutParams = binding.quoteView.root.layoutParams as MarginLayoutParams
|
|
||||||
val hasMedia = message.slideDeck.asAttachments().isNotEmpty()
|
val hasMedia = message.slideDeck.asAttachments().isNotEmpty()
|
||||||
binding.quoteView.root.minWidth = if (hasMedia) 0 else toPx(300,context.resources)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message is MmsMessageRecord) {
|
if (message is MmsMessageRecord) {
|
||||||
@ -198,6 +191,9 @@ class VisibleMessageContentView : LinearLayout {
|
|||||||
isStart = isStartOfMessageCluster,
|
isStart = isStartOfMessageCluster,
|
||||||
isEnd = isEndOfMessageCluster
|
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 ->
|
onContentClick.add { event ->
|
||||||
binding.albumThumbnailView.calculateHitObject(event, message, thread)
|
binding.albumThumbnailView.calculateHitObject(event, message, thread)
|
||||||
}
|
}
|
||||||
@ -215,11 +211,6 @@ class VisibleMessageContentView : LinearLayout {
|
|||||||
|
|
||||||
binding.bodyTextView.isVisible = message.body.isNotEmpty() && !hideBody
|
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) {
|
if (message.body.isNotEmpty() && !hideBody) {
|
||||||
val color = getTextColor(context, message)
|
val color = getTextColor(context, message)
|
||||||
binding.bodyTextView.setTextColor(color)
|
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 =
|
private fun ViewVisibleMessageContentBinding.barrierViewsGone(): Boolean =
|
||||||
|
@ -17,7 +17,9 @@ import androidx.constraintlayout.widget.ConstraintLayout
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.core.view.marginBottom
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import network.loki.messenger.databinding.ViewVisibleMessageBinding
|
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.toDp
|
||||||
import org.thoughtcrime.securesms.util.toPx
|
import org.thoughtcrime.securesms.util.toPx
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
@ -152,18 +155,15 @@ class VisibleMessageView : LinearLayout {
|
|||||||
binding.moderatorIconImageView.isVisible = !message.isOutgoing && isModerator
|
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
|
// Date break
|
||||||
binding.dateBreakTextView.showDateBreak(message, previous)
|
val showDateBreak = isStartOfMessageCluster || snIsSelected
|
||||||
// Timestamp
|
binding.dateBreakTextView.text = if (showDateBreak) DateUtils.getDisplayFormattedTimeSpanString(context, Locale.getDefault(), message.timestamp) else null
|
||||||
// binding.messageTimestampTextView.text = DateUtils.getDisplayFormattedTimeSpanString(context, Locale.getDefault(), message.timestamp)
|
binding.dateBreakTextView.isVisible = showDateBreak
|
||||||
// Set inter-message spacing
|
|
||||||
// Message status indicator
|
// Message status indicator
|
||||||
val (iconID, iconColor) = getMessageStatusImage(message)
|
val (iconID, iconColor) = getMessageStatusImage(message)
|
||||||
if (iconID != null) {
|
if (iconID != null) {
|
||||||
@ -242,7 +242,7 @@ class VisibleMessageView : LinearLayout {
|
|||||||
container.layoutParams = containerParams
|
container.layoutParams = containerParams
|
||||||
if (message.expiresIn > 0 && !message.isPending) {
|
if (message.expiresIn > 0 && !message.isPending) {
|
||||||
binding.expirationTimerView.setColorFilter(ResourcesCompat.getColor(resources, R.color.text, context.theme))
|
binding.expirationTimerView.setColorFilter(ResourcesCompat.getColor(resources, R.color.text, context.theme))
|
||||||
binding.expirationTimerView.isVisible = true
|
binding.expirationTimerView.isInvisible = false
|
||||||
binding.expirationTimerView.setPercentComplete(0.0f)
|
binding.expirationTimerView.setPercentComplete(0.0f)
|
||||||
if (message.expireStarted > 0) {
|
if (message.expireStarted > 0) {
|
||||||
binding.expirationTimerView.setExpirationTime(message.expireStarted, message.expiresIn)
|
binding.expirationTimerView.setExpirationTime(message.expireStarted, message.expiresIn)
|
||||||
@ -265,7 +265,7 @@ class VisibleMessageView : LinearLayout {
|
|||||||
binding.expirationTimerView.setPercentComplete(0.0f)
|
binding.expirationTimerView.setPercentComplete(0.0f)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
binding.expirationTimerView.isVisible = false
|
binding.expirationTimerView.isInvisible = true
|
||||||
}
|
}
|
||||||
container.requestLayout()
|
container.requestLayout()
|
||||||
}
|
}
|
||||||
@ -279,15 +279,19 @@ class VisibleMessageView : LinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDraw(canvas: Canvas) {
|
override fun onDraw(canvas: Canvas) {
|
||||||
if (translationX < 0 && !binding.expirationTimerView.isVisible) {
|
|
||||||
val spacing = context.resources.getDimensionPixelSize(R.dimen.small_spacing)
|
val spacing = context.resources.getDimensionPixelSize(R.dimen.small_spacing)
|
||||||
val threshold = swipeToReplyThreshold
|
|
||||||
val iconSize = toPx(24, context.resources)
|
val iconSize = toPx(24, context.resources)
|
||||||
val bottomVOffset = paddingBottom + binding.messageStatusImageView.height + (binding.messageContentView.height - iconSize) / 2
|
val left = binding.expirationTimerViewContainer.left + binding.messageContentView.right + spacing
|
||||||
swipeToReplyIconRect.left = binding.messageContentView.right - binding.messageContentView.paddingEnd + spacing
|
val top = height - (binding.expirationTimerViewContainer.height / 2) - binding.profilePictureView.root.marginBottom - (iconSize / 2)
|
||||||
swipeToReplyIconRect.top = height - bottomVOffset - iconSize
|
val right = left + iconSize
|
||||||
swipeToReplyIconRect.right = binding.messageContentView.right - binding.messageContentView.paddingEnd + iconSize + spacing
|
val bottom = top + iconSize
|
||||||
swipeToReplyIconRect.bottom = height - bottomVOffset
|
swipeToReplyIconRect.left = left
|
||||||
|
swipeToReplyIconRect.top = top
|
||||||
|
swipeToReplyIconRect.right = right
|
||||||
|
swipeToReplyIconRect.bottom = bottom
|
||||||
|
|
||||||
|
if (translationX < 0 && !binding.expirationTimerView.isVisible) {
|
||||||
|
val threshold = swipeToReplyThreshold
|
||||||
swipeToReplyIcon.bounds = swipeToReplyIconRect
|
swipeToReplyIcon.bounds = swipeToReplyIconRect
|
||||||
swipeToReplyIcon.alpha = (255.0f * (min(abs(translationX), threshold) / threshold)).roundToInt()
|
swipeToReplyIcon.alpha = (255.0f * (min(abs(translationX), threshold) / threshold)).roundToInt()
|
||||||
} else {
|
} else {
|
||||||
|
@ -62,7 +62,6 @@ import org.thoughtcrime.securesms.database.SmsDatabase.InsertListener
|
|||||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
|
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
|
||||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
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.NotificationMmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.Quote
|
import org.thoughtcrime.securesms.database.model.Quote
|
||||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent.Companion.get
|
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 quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_ID))
|
||||||
val quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_AUTHOR))
|
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 quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(QUOTE_MISSING)) == 1
|
||||||
val quoteAttachments = associatedAttachments
|
val quoteAttachments = associatedAttachments
|
||||||
.filter { obj: DatabaseAttachment -> obj.isQuote }
|
.filter { obj: DatabaseAttachment -> obj.isQuote }
|
||||||
@ -502,7 +501,7 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
quote = QuoteModel(
|
quote = QuoteModel(
|
||||||
quoteId,
|
quoteId,
|
||||||
fromSerialized(quoteAuthor),
|
fromSerialized(quoteAuthor),
|
||||||
quoteText,
|
quoteText, // TODO: refactor this to use referenced quote
|
||||||
quoteMissing,
|
quoteMissing,
|
||||||
quoteAttachments
|
quoteAttachments
|
||||||
)
|
)
|
||||||
@ -669,7 +668,6 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
var quoteAttachments: List<Attachment?>? = LinkedList()
|
var quoteAttachments: List<Attachment?>? = LinkedList()
|
||||||
if (retrieved.quote != null) {
|
if (retrieved.quote != null) {
|
||||||
contentValues.put(QUOTE_ID, retrieved.quote.id)
|
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_AUTHOR, retrieved.quote.author.serialize())
|
||||||
contentValues.put(QUOTE_MISSING, if (retrieved.quote.missing) 1 else 0)
|
contentValues.put(QUOTE_MISSING, if (retrieved.quote.missing) 1 else 0)
|
||||||
quoteAttachments = retrieved.quote.attachments
|
quoteAttachments = retrieved.quote.attachments
|
||||||
@ -816,7 +814,6 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
if (message.outgoingQuote != null) {
|
if (message.outgoingQuote != null) {
|
||||||
contentValues.put(QUOTE_ID, message.outgoingQuote!!.id)
|
contentValues.put(QUOTE_ID, message.outgoingQuote!!.id)
|
||||||
contentValues.put(QUOTE_AUTHOR, message.outgoingQuote!!.author.serialize())
|
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)
|
contentValues.put(QUOTE_MISSING, if (message.outgoingQuote!!.missing) 1 else 0)
|
||||||
quoteAttachments.addAll(message.outgoingQuote!!.attachments!!)
|
quoteAttachments.addAll(message.outgoingQuote!!.attachments!!)
|
||||||
}
|
}
|
||||||
@ -949,31 +946,12 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
}
|
}
|
||||||
val query = queryBuilder.toString()
|
val query = queryBuilder.toString()
|
||||||
val db = databaseHelper.writableDatabase
|
val db = databaseHelper.writableDatabase
|
||||||
val values = ContentValues(3)
|
val values = ContentValues(2)
|
||||||
values.put(QUOTE_MISSING, 1)
|
values.put(QUOTE_MISSING, 1)
|
||||||
values.put(QUOTE_BODY, "")
|
|
||||||
values.put(QUOTE_AUTHOR, "")
|
values.put(QUOTE_AUTHOR, "")
|
||||||
db!!.update(TABLE_NAME, values, query, null)
|
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
|
* Delete all the messages in single queries where possible
|
||||||
* @param messageIds a String array representation of regularly Long types representing message IDs
|
* @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) })
|
queue(Runnable { attachmentDatabase.deleteAttachmentsForMessages(messageIds) })
|
||||||
val groupReceiptDatabase = get(context).groupReceiptDatabase()
|
val groupReceiptDatabase = get(context).groupReceiptDatabase()
|
||||||
groupReceiptDatabase.deleteRowsForMessages(messageIds)
|
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
|
val database = databaseHelper.writableDatabase
|
||||||
database.delete(TABLE_NAME, idsAsString, null)
|
database.delete(TABLE_NAME, idsAsString, null)
|
||||||
notifyConversationListListeners()
|
notifyConversationListListeners()
|
||||||
@ -1017,13 +988,8 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
queue(Runnable { attachmentDatabase.deleteAttachmentsForMessage(messageId) })
|
queue(Runnable { attachmentDatabase.deleteAttachmentsForMessage(messageId) })
|
||||||
val groupReceiptDatabase = get(context).groupReceiptDatabase()
|
val groupReceiptDatabase = get(context).groupReceiptDatabase()
|
||||||
groupReceiptDatabase.deleteRowsForMessage(messageId)
|
groupReceiptDatabase.deleteRowsForMessage(messageId)
|
||||||
var toDelete: MessageRecord?
|
|
||||||
getMessage(messageId).use { messageCursor ->
|
|
||||||
toDelete = readerFor(messageCursor).next
|
|
||||||
}
|
|
||||||
deleteQuotedFromMessages(toDelete)
|
|
||||||
val database = databaseHelper.writableDatabase
|
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)
|
val threadDeleted = get(context).threadDatabase().update(threadId, false)
|
||||||
notifyConversationListeners(threadId)
|
notifyConversationListeners(threadId)
|
||||||
notifyStickerListeners()
|
notifyStickerListeners()
|
||||||
@ -1287,7 +1253,7 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
if (message.outgoingQuote != null) Quote(
|
if (message.outgoingQuote != null) Quote(
|
||||||
message.outgoingQuote!!.id,
|
message.outgoingQuote!!.id,
|
||||||
message.outgoingQuote!!.author,
|
message.outgoingQuote!!.author,
|
||||||
message.outgoingQuote!!.text,
|
message.outgoingQuote!!.text, // TODO: use the referenced message's content
|
||||||
message.outgoingQuote!!.missing,
|
message.outgoingQuote!!.missing,
|
||||||
SlideDeck(context, message.outgoingQuote!!.attachments!!)
|
SlideDeck(context, message.outgoingQuote!!.attachments!!)
|
||||||
) else null,
|
) else null,
|
||||||
@ -1466,8 +1432,9 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
private fun getQuote(cursor: Cursor): Quote? {
|
private fun getQuote(cursor: Cursor): Quote? {
|
||||||
val quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_ID))
|
val quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_ID))
|
||||||
val quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_AUTHOR))
|
val quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_AUTHOR))
|
||||||
val quoteText = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_BODY))
|
val retrievedQuote = get(context).mmsSmsDatabase().getMessageFor(quoteId, quoteAuthor)
|
||||||
val quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(QUOTE_MISSING)) == 1
|
val quoteText = retrievedQuote?.body
|
||||||
|
val quoteMissing = retrievedQuote == null
|
||||||
val attachments = get(context).attachmentDatabase().getAttachment(cursor)
|
val attachments = get(context).attachmentDatabase().getAttachment(cursor)
|
||||||
val quoteAttachments: List<Attachment?>? =
|
val quoteAttachments: List<Attachment?>? =
|
||||||
Stream.of(attachments).filter { obj: DatabaseAttachment? -> obj!!.isQuote }
|
Stream.of(attachments).filter { obj: DatabaseAttachment? -> obj!!.isQuote }
|
||||||
@ -1601,7 +1568,6 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
|
|||||||
")) AS " + AttachmentDatabase.ATTACHMENT_JSON_ALIAS
|
")) AS " + AttachmentDatabase.ATTACHMENT_JSON_ALIAS
|
||||||
)
|
)
|
||||||
private const val RAW_ID_WHERE: String = "$TABLE_NAME._id = ?"
|
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;"
|
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);
|
Log.i("MessageDatabase", "Deleting: " + messageId);
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
long threadId = getThreadIdForMessage(messageId);
|
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+""});
|
db.delete(TABLE_NAME, ID_WHERE, new String[] {messageId+""});
|
||||||
boolean threadDeleted = DatabaseComponent.get(context).threadDatabase().update(threadId, false);
|
boolean threadDeleted = DatabaseComponent.get(context).threadDatabase().update(threadId, false);
|
||||||
notifyConversationListeners(threadId);
|
notifyConversationListeners(threadId);
|
||||||
|
@ -258,7 +258,7 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
Cursor pushCursor = null;
|
Cursor pushCursor = null;
|
||||||
|
|
||||||
try {
|
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))
|
if ((telcoCursor == null || telcoCursor.isAfterLast()) || !TextSecurePreferences.hasSeenWelcomeScreen(context))
|
||||||
{
|
{
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
android:id="@+id/album_cell_2"
|
android:id="@+id/album_cell_2"
|
||||||
android:layout_width="@dimen/album_2_cell_width"
|
android:layout_width="@dimen/album_2_cell_width"
|
||||||
android:layout_height="@dimen/album_2_total_height"
|
android:layout_height="@dimen/album_2_total_height"
|
||||||
android:layout_gravity="right|end"
|
android:layout_gravity="end"
|
||||||
app:thumbnail_radius="0dp"/>
|
app:thumbnail_radius="0dp"/>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/album_thumbnail_root"
|
android:id="@+id/album_thumbnail_root"
|
||||||
android:layout_width="@dimen/album_total_width"
|
android:layout_width="@dimen/album_total_width"
|
||||||
android:layout_height="@dimen/album_3_total_height">
|
android:layout_height="@dimen/album_3_total_height">
|
||||||
@ -16,14 +16,34 @@
|
|||||||
android:id="@+id/album_cell_2"
|
android:id="@+id/album_cell_2"
|
||||||
android:layout_width="@dimen/album_3_cell_size_small"
|
android:layout_width="@dimen/album_3_cell_size_small"
|
||||||
android:layout_height="@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"/>
|
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
|
<org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||||
android:id="@+id/album_cell_3"
|
android:id="@+id/album_cell_3"
|
||||||
android:layout_width="@dimen/album_3_cell_size_small"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="@dimen/album_3_cell_size_small"
|
android:layout_width="match_parent"
|
||||||
android:layout_gravity="right|end|bottom"
|
android:layout_gravity="center_horizontal|bottom"
|
||||||
app:thumbnail_radius="0dp"/>
|
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>
|
</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_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@color/input_bar_background"
|
android:background="@color/input_bar_background"
|
||||||
android:minWidth="300dp"
|
|
||||||
android:minHeight="52dp"
|
android:minHeight="52dp"
|
||||||
android:paddingVertical="12dp"
|
android:paddingVertical="12dp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
@ -24,6 +23,7 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
tools:visibility="visible"
|
||||||
android:id="@+id/quoteViewAttachmentPreviewContainer"
|
android:id="@+id/quoteViewAttachmentPreviewContainer"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
@ -71,30 +71,27 @@
|
|||||||
android:textColor="@color/text"
|
android:textColor="@color/text"
|
||||||
android:textSize="@dimen/small_font_size"
|
android:textSize="@dimen/small_font_size"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:visibility="gone"
|
android:maxWidth="240dp"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/quoteViewBodyTextView"
|
app:layout_constraintBottom_toTopOf="@+id/quoteViewBodyTextView"
|
||||||
app:layout_constraintEnd_toEndOf="@+id/quoteViewBodyTextView"
|
|
||||||
app:layout_constraintHorizontal_bias="0"
|
app:layout_constraintHorizontal_bias="0"
|
||||||
app:layout_constraintStart_toEndOf="@+id/quoteStartBarrier"
|
app:layout_constraintStart_toEndOf="@+id/quoteStartBarrier"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintVertical_chainStyle="packed"
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
tools:text="Spiderman" />
|
tools:text="@tools:sample/full_names" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/quoteViewBodyTextView"
|
android:id="@+id/quoteViewBodyTextView"
|
||||||
android:layout_width="0dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/medium_spacing"
|
android:layout_marginStart="@dimen/medium_spacing"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="3"
|
android:maxLines="1"
|
||||||
android:textColor="@color/text"
|
android:textColor="@color/text"
|
||||||
android:textSize="@dimen/small_font_size"
|
android:textSize="@dimen/small_font_size"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
app:layout_constraintStart_toEndOf="@+id/quoteStartBarrier"
|
app:layout_constraintStart_toEndOf="@+id/quoteStartBarrier"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/quoteViewAuthorTextView"
|
app:layout_constraintTop_toBottomOf="@+id/quoteViewAuthorTextView"
|
||||||
app:layout_constraintVertical_chainStyle="packed"
|
|
||||||
android:maxWidth="240dp"
|
android:maxWidth="240dp"
|
||||||
tools:maxLines="1"
|
tools:maxLines="1"
|
||||||
tools:text="@tools:sample/lorem/random" />
|
tools:text="@tools:sample/lorem/random" />
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
android:layout_height="1dp"/>
|
android:layout_height="1dp"/>
|
||||||
|
|
||||||
<include
|
<include
|
||||||
tools:visibility="gone"
|
tools:visibility="visible"
|
||||||
android:id="@+id/profilePictureView"
|
android:id="@+id/profilePictureView"
|
||||||
layout="@layout/view_profile_picture"
|
layout="@layout/view_profile_picture"
|
||||||
android:layout_marginBottom="@dimen/small_spacing"
|
android:layout_marginBottom="@dimen/small_spacing"
|
||||||
@ -44,6 +44,7 @@
|
|||||||
android:layout_gravity="center" />
|
android:layout_gravity="center" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
tools:visibility="visible"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:id="@+id/moderatorIconImageView"
|
android:id="@+id/moderatorIconImageView"
|
||||||
android:layout_width="16dp"
|
android:layout_width="16dp"
|
||||||
@ -87,7 +88,7 @@
|
|||||||
|
|
||||||
<org.thoughtcrime.securesms.conversation.v2.components.ExpirationTimerView
|
<org.thoughtcrime.securesms.conversation.v2.components.ExpirationTimerView
|
||||||
tools:visibility="visible"
|
tools:visibility="visible"
|
||||||
android:visibility="gone"
|
android:visibility="invisible"
|
||||||
android:id="@+id/expirationTimerView"
|
android:id="@+id/expirationTimerView"
|
||||||
android:layout_width="12dp"
|
android:layout_width="12dp"
|
||||||
android:layout_height="12dp"
|
android:layout_height="12dp"
|
||||||
|
@ -7,12 +7,19 @@
|
|||||||
android:id="@+id/mainContainerConstraint"
|
android:id="@+id/mainContainerConstraint"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/contentParent"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
>
|
||||||
<!-- Content that will only show on its own -->
|
<!-- Content that will only show on its own -->
|
||||||
<include layout="@layout/view_deleted_message"
|
<include layout="@layout/view_deleted_message"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:id="@+id/deletedMessageView"
|
android:id="@+id/deletedMessageView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -24,7 +31,6 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:id="@+id/untrustedView"
|
android:id="@+id/untrustedView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -34,7 +40,6 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:id="@+id/voiceMessageView"
|
android:id="@+id/voiceMessageView"
|
||||||
android:layout_width="160dp"
|
android:layout_width="160dp"
|
||||||
@ -45,7 +50,6 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:id="@+id/openGroupInvitationView"
|
android:id="@+id/openGroupInvitationView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -55,7 +59,6 @@
|
|||||||
tools:visibility="gone"
|
tools:visibility="gone"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:id="@+id/documentView"
|
android:id="@+id/documentView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -71,6 +74,7 @@
|
|||||||
android:id="@+id/quoteView"
|
android:id="@+id/quoteView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.conversation.v2.messages.LinkPreviewView
|
<org.thoughtcrime.securesms.conversation.v2.messages.LinkPreviewView
|
||||||
app:layout_constraintTop_toBottomOf="@+id/quoteView"
|
app:layout_constraintTop_toBottomOf="@+id/quoteView"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
@ -78,33 +82,45 @@
|
|||||||
android:id="@+id/linkPreviewView"
|
android:id="@+id/linkPreviewView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Barrier
|
<androidx.constraintlayout.widget.Barrier
|
||||||
app:barrierAllowsGoneWidgets="true"
|
app:barrierAllowsGoneWidgets="true"
|
||||||
android:id="@+id/bodyBarrier"
|
android:id="@+id/bodyBarrier"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:barrierDirection="end"
|
app:barrierDirection="end"
|
||||||
app:constraint_referenced_ids="albumThumbnailView,linkPreviewView,quoteView,voiceMessageView"/>
|
app:constraint_referenced_ids="linkPreviewView,quoteView,voiceMessageView"/>
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.conversation.v2.components.AlbumThumbnailView
|
<androidx.constraintlayout.widget.Barrier
|
||||||
app:layout_constraintTop_toBottomOf="@+id/linkPreviewView"
|
|
||||||
app:layout_constraintHorizontal_bias="1"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:id="@+id/albumThumbnailView"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="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
|
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||||
app:layout_constraintHorizontal_bias="0"
|
app:layout_constraintHorizontal_bias="0"
|
||||||
|
tools:visibility="visible"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/albumThumbnailView"
|
app:layout_constraintTop_toBottomOf="@+id/bodyTopBarrier"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="@+id/bodyBarrier"
|
android:maxWidth="300dp"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:paddingVertical="@dimen/small_spacing"
|
android:paddingVertical="@dimen/small_spacing"
|
||||||
android:id="@+id/bodyTextView"
|
android:id="@+id/bodyTextView"
|
||||||
android:layout_width="0dp"
|
android:layout_width="wrap_content"
|
||||||
android:maxWidth="300dp"
|
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"/>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.conversation.v2.components.AlbumThumbnailView
|
||||||
|
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"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -60,6 +60,15 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long)
|
|||||||
messageDataProvider.setAttachmentState(AttachmentState.FAILED, AttachmentId(attachmentID,0), databaseMessageID)
|
messageDataProvider.setAttachmentState(AttachmentState.FAILED, AttachmentId(attachmentID,0), databaseMessageID)
|
||||||
}
|
}
|
||||||
this.handlePermanentFailure(exception)
|
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 {
|
} else {
|
||||||
if (failureCount + 1 >= maxFailureCount) {
|
if (failureCount + 1 >= maxFailureCount) {
|
||||||
attachment?.let { id ->
|
attachment?.let { id ->
|
||||||
|
@ -30,7 +30,7 @@ class Quote() {
|
|||||||
fun from(signalQuote: SignalQuote?): Quote? {
|
fun from(signalQuote: SignalQuote?): Quote? {
|
||||||
if (signalQuote == null) { return null }
|
if (signalQuote == null) { return null }
|
||||||
val attachmentID = (signalQuote.attachments?.firstOrNull() as? DatabaseAttachment)?.attachmentId?.rowId
|
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)
|
val messageInfo = messageDataProvider.getMessageForQuote(quote.id, author)
|
||||||
if (messageInfo != null) {
|
if (messageInfo != null) {
|
||||||
val attachments = if (messageInfo.second) messageDataProvider.getAttachmentsAndLinkPreviewFor(messageInfo.first) else ArrayList()
|
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 {
|
} 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
|
// Parse link preview if needed
|
||||||
|
@ -5,6 +5,6 @@ import org.session.libsession.utilities.Address
|
|||||||
|
|
||||||
class QuoteModel(val id: Long,
|
class QuoteModel(val id: Long,
|
||||||
val author: Address,
|
val author: Address,
|
||||||
val text: String,
|
val text: String?,
|
||||||
val missing: Boolean,
|
val missing: Boolean,
|
||||||
val attachments: List<Attachment>?)
|
val attachments: List<Attachment>?)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user