kopia lustrzana https://github.com/ryukoposting/Signal-Android
rodzic
cdb7f07368
commit
c131fb500d
|
@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.contactshare.Contact;
|
||||||
import org.thoughtcrime.securesms.conversation.ConversationMessage;
|
import org.thoughtcrime.securesms.conversation.ConversationMessage;
|
||||||
import org.thoughtcrime.securesms.conversation.colors.Colorizable;
|
import org.thoughtcrime.securesms.conversation.colors.Colorizable;
|
||||||
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
|
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
|
||||||
|
import org.thoughtcrime.securesms.conversation.ConversationItemDisplayMode;
|
||||||
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart;
|
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart;
|
||||||
import org.thoughtcrime.securesms.conversation.mutiselect.Multiselectable;
|
import org.thoughtcrime.securesms.conversation.mutiselect.Multiselectable;
|
||||||
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord;
|
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord;
|
||||||
|
@ -47,7 +48,7 @@ public interface BindableConversationItem extends Unbindable, GiphyMp4Playable,
|
||||||
boolean isMessageRequestAccepted,
|
boolean isMessageRequestAccepted,
|
||||||
boolean canPlayInline,
|
boolean canPlayInline,
|
||||||
@NonNull Colorizer colorizer,
|
@NonNull Colorizer colorizer,
|
||||||
boolean isCondensedMode);
|
@NonNull ConversationItemDisplayMode displayMode);
|
||||||
|
|
||||||
@NonNull ConversationMessage getConversationMessage();
|
@NonNull ConversationMessage getConversationMessage();
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,8 @@ public class DocumentView extends FrameLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDocument(final @NonNull Slide documentSlide,
|
public void setDocument(final @NonNull Slide documentSlide,
|
||||||
final boolean showControls)
|
final boolean showControls,
|
||||||
|
final boolean showSingleLineFilename)
|
||||||
{
|
{
|
||||||
if (showControls && documentSlide.isPendingDownload()) {
|
if (showControls && documentSlide.isPendingDownload()) {
|
||||||
controlToggle.displayQuick(downloadButton);
|
controlToggle.displayQuick(downloadButton);
|
||||||
|
@ -106,6 +107,11 @@ public class DocumentView extends FrameLayout {
|
||||||
|
|
||||||
this.documentSlide = documentSlide;
|
this.documentSlide = documentSlide;
|
||||||
|
|
||||||
|
// Android OS filenames are limited to 256 characters, so
|
||||||
|
// we don't need an additional max characters/lines constraint when
|
||||||
|
// [showSingleLineFilename] is false.
|
||||||
|
this.fileName.setSingleLine(showSingleLineFilename);
|
||||||
|
|
||||||
this.fileName.setText(OptionalUtil.or(documentSlide.getFileName(),
|
this.fileName.setText(OptionalUtil.or(documentSlide.getFileName(),
|
||||||
documentSlide.getCaption())
|
documentSlide.getCaption())
|
||||||
.orElse(getContext().getString(R.string.DocumentView_unnamed_file)));
|
.orElse(getContext().getString(R.string.DocumentView_unnamed_file)));
|
||||||
|
@ -114,6 +120,12 @@ public class DocumentView extends FrameLayout {
|
||||||
this.setOnClickListener(new OpenClickedListener(documentSlide));
|
this.setOnClickListener(new OpenClickedListener(documentSlide));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDocument(final @NonNull Slide documentSlide,
|
||||||
|
final boolean showControls)
|
||||||
|
{
|
||||||
|
setDocument(documentSlide, showControls, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFocusable(boolean focusable) {
|
public void setFocusable(boolean focusable) {
|
||||||
super.setFocusable(focusable);
|
super.setFocusable(focusable);
|
||||||
|
|
|
@ -280,6 +280,8 @@ public class ConversationAdapter
|
||||||
ConversationMessage previousMessage = adapterPosition < getItemCount() - 1 && !isFooterPosition(adapterPosition + 1) ? getItem(adapterPosition + 1) : null;
|
ConversationMessage previousMessage = adapterPosition < getItemCount() - 1 && !isFooterPosition(adapterPosition + 1) ? getItem(adapterPosition + 1) : null;
|
||||||
ConversationMessage nextMessage = adapterPosition > 0 && !isHeaderPosition(adapterPosition - 1) ? getItem(adapterPosition - 1) : null;
|
ConversationMessage nextMessage = adapterPosition > 0 && !isHeaderPosition(adapterPosition - 1) ? getItem(adapterPosition - 1) : null;
|
||||||
|
|
||||||
|
ConversationItemDisplayMode displayMode = condensedMode ? ConversationItemDisplayMode.CONDENSED : ConversationItemDisplayMode.STANDARD;
|
||||||
|
|
||||||
conversationViewHolder.getBindable().bind(lifecycleOwner,
|
conversationViewHolder.getBindable().bind(lifecycleOwner,
|
||||||
conversationMessage,
|
conversationMessage,
|
||||||
Optional.ofNullable(previousMessage != null ? previousMessage.getMessageRecord() : null),
|
Optional.ofNullable(previousMessage != null ? previousMessage.getMessageRecord() : null),
|
||||||
|
@ -294,7 +296,7 @@ public class ConversationAdapter
|
||||||
isMessageRequestAccepted,
|
isMessageRequestAccepted,
|
||||||
conversationMessage == inlineContent,
|
conversationMessage == inlineContent,
|
||||||
colorizer,
|
colorizer,
|
||||||
condensedMode);
|
displayMode);
|
||||||
|
|
||||||
if (conversationMessage == recordToPulse) {
|
if (conversationMessage == recordToPulse) {
|
||||||
recordToPulse = null;
|
recordToPulse = null;
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.thoughtcrime.securesms.conversation;
|
||||||
|
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -114,7 +113,6 @@ import org.thoughtcrime.securesms.jobs.SmsSendJob;
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||||
import org.thoughtcrime.securesms.mediapreview.MediaIntentFactory;
|
import org.thoughtcrime.securesms.mediapreview.MediaIntentFactory;
|
||||||
import org.thoughtcrime.securesms.mediapreview.MediaPreviewV2Activity;
|
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
import org.thoughtcrime.securesms.mms.ImageSlide;
|
import org.thoughtcrime.securesms.mms.ImageSlide;
|
||||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||||
|
@ -130,7 +128,6 @@ import org.thoughtcrime.securesms.recipients.RecipientForeverObserver;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||||
import org.thoughtcrime.securesms.revealable.ViewOnceMessageView;
|
import org.thoughtcrime.securesms.revealable.ViewOnceMessageView;
|
||||||
import org.thoughtcrime.securesms.util.DateUtils;
|
import org.thoughtcrime.securesms.util.DateUtils;
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
|
||||||
import org.thoughtcrime.securesms.util.InterceptableLongClickCopyLinkSpan;
|
import org.thoughtcrime.securesms.util.InterceptableLongClickCopyLinkSpan;
|
||||||
import org.thoughtcrime.securesms.util.LinkUtil;
|
import org.thoughtcrime.securesms.util.LinkUtil;
|
||||||
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
|
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
|
||||||
|
@ -191,13 +188,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||||
private LiveRecipient recipient;
|
private LiveRecipient recipient;
|
||||||
private GlideRequests glideRequests;
|
private GlideRequests glideRequests;
|
||||||
private ValueAnimator pulseOutlinerAlphaAnimator;
|
private ValueAnimator pulseOutlinerAlphaAnimator;
|
||||||
private Optional<MessageRecord> previousMessage;
|
private Optional<MessageRecord> previousMessage;
|
||||||
|
private ConversationItemDisplayMode displayMode;
|
||||||
/**
|
|
||||||
* Whether or not we're rendering this item in a constrained space.
|
|
||||||
* Today this is only {@link org.thoughtcrime.securesms.conversation.quotes.MessageQuotesBottomSheet}.
|
|
||||||
*/
|
|
||||||
private boolean isCondensedMode;
|
|
||||||
|
|
||||||
protected ConversationItemBodyBubble bodyBubble;
|
protected ConversationItemBodyBubble bodyBubble;
|
||||||
protected View reply;
|
protected View reply;
|
||||||
|
@ -355,7 +347,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||||
boolean isMessageRequestAccepted,
|
boolean isMessageRequestAccepted,
|
||||||
boolean allowedToPlayInline,
|
boolean allowedToPlayInline,
|
||||||
@NonNull Colorizer colorizer,
|
@NonNull Colorizer colorizer,
|
||||||
boolean isCondensedMode)
|
@NonNull ConversationItemDisplayMode displayMode)
|
||||||
{
|
{
|
||||||
if (this.recipient != null) this.recipient.removeForeverObserver(this);
|
if (this.recipient != null) this.recipient.removeForeverObserver(this);
|
||||||
if (this.conversationRecipient != null) this.conversationRecipient.removeForeverObserver(this);
|
if (this.conversationRecipient != null) this.conversationRecipient.removeForeverObserver(this);
|
||||||
|
@ -376,7 +368,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||||
this.canPlayContent = false;
|
this.canPlayContent = false;
|
||||||
this.mediaItem = null;
|
this.mediaItem = null;
|
||||||
this.colorizer = colorizer;
|
this.colorizer = colorizer;
|
||||||
this.isCondensedMode = isCondensedMode;
|
this.displayMode = displayMode;
|
||||||
this.previousMessage = previousMessageRecord;
|
this.previousMessage = previousMessageRecord;
|
||||||
|
|
||||||
this.recipient.observeForever(this);
|
this.recipient.observeForever(this);
|
||||||
|
@ -422,7 +414,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||||
if (isCondensedMode) return super.dispatchTouchEvent(ev);
|
if (isCondensedMode()) return super.dispatchTouchEvent(ev);
|
||||||
|
|
||||||
switch (ev.getAction()) {
|
switch (ev.getAction()) {
|
||||||
case MotionEvent.ACTION_DOWN:
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
@ -906,12 +898,20 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not we're rendering this item in a constrained space.
|
||||||
|
* Today this is only {@link org.thoughtcrime.securesms.conversation.quotes.MessageQuotesBottomSheet}.
|
||||||
|
*/
|
||||||
|
private boolean isCondensedMode() {
|
||||||
|
return displayMode == ConversationItemDisplayMode.CONDENSED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not we want to condense the actual content of the bubble. e.g. shorten image height, text content, etc.
|
* Whether or not we want to condense the actual content of the bubble. e.g. shorten image height, text content, etc.
|
||||||
* Today, we only want to do this for the first message when we're in condensed mode.
|
* Today, we only want to do this for the first message when we're in condensed mode.
|
||||||
*/
|
*/
|
||||||
private boolean isContentCondensed() {
|
private boolean isContentCondensed() {
|
||||||
return isCondensedMode && !previousMessage.isPresent();
|
return isCondensedMode() && !previousMessage.isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isStoryReaction(MessageRecord messageRecord) {
|
private boolean isStoryReaction(MessageRecord messageRecord) {
|
||||||
|
@ -1187,7 +1187,11 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||||
if (giftViewStub.resolved()) giftViewStub.get().setVisibility(View.GONE);
|
if (giftViewStub.resolved()) giftViewStub.get().setVisibility(View.GONE);
|
||||||
|
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
documentViewStub.get().setDocument(((MediaMmsMessageRecord) messageRecord).getSlideDeck().getDocumentSlide(), showControls);
|
documentViewStub.get().setDocument(
|
||||||
|
((MediaMmsMessageRecord) messageRecord).getSlideDeck().getDocumentSlide(),
|
||||||
|
showControls,
|
||||||
|
displayMode != ConversationItemDisplayMode.DETAILED
|
||||||
|
);
|
||||||
documentViewStub.get().setDocumentClickListener(new ThumbnailClickListener());
|
documentViewStub.get().setDocumentClickListener(new ThumbnailClickListener());
|
||||||
documentViewStub.get().setDownloadClickListener(singleDownloadClickListener);
|
documentViewStub.get().setDownloadClickListener(singleDownloadClickListener);
|
||||||
documentViewStub.get().setOnLongClickListener(passthroughClickListener);
|
documentViewStub.get().setOnLongClickListener(passthroughClickListener);
|
||||||
|
@ -1690,7 +1694,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setHasBeenQuoted(@NonNull ConversationMessage message) {
|
private void setHasBeenQuoted(@NonNull ConversationMessage message) {
|
||||||
if (message.hasBeenQuoted() && !isCondensedMode && quotedIndicator != null && batchSelected.isEmpty()) {
|
if (message.hasBeenQuoted() && !isCondensedMode() && quotedIndicator != null && batchSelected.isEmpty()) {
|
||||||
quotedIndicator.setVisibility(VISIBLE);
|
quotedIndicator.setVisibility(VISIBLE);
|
||||||
quotedIndicator.setOnClickListener(quotedIndicatorClickListener);
|
quotedIndicator.setOnClickListener(quotedIndicatorClickListener);
|
||||||
} else if (quotedIndicator != null) {
|
} else if (quotedIndicator != null) {
|
||||||
|
@ -2312,7 +2316,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||||
|
|
||||||
private class ThumbnailClickListener implements SlideClickListener {
|
private class ThumbnailClickListener implements SlideClickListener {
|
||||||
public void onClick(final View v, final Slide slide) {
|
public void onClick(final View v, final Slide slide) {
|
||||||
if (shouldInterceptClicks(messageRecord) || !batchSelected.isEmpty() || isCondensedMode) {
|
if (shouldInterceptClicks(messageRecord) || !batchSelected.isEmpty() || isCondensedMode()) {
|
||||||
performClick();
|
performClick();
|
||||||
} else if (!canPlayContent && mediaItem != null && eventListener != null) {
|
} else if (!canPlayContent && mediaItem != null && eventListener != null) {
|
||||||
eventListener.onPlayInlineContent(conversationMessage);
|
eventListener.onPlayInlineContent(conversationMessage);
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package org.thoughtcrime.securesms.conversation
|
||||||
|
|
||||||
|
enum class ConversationItemDisplayMode {
|
||||||
|
/** Normal rendering, used for normal bubbles in the conversation view */
|
||||||
|
STANDARD,
|
||||||
|
/** Smaller bubbles, often trimming text and shrinking images. Used for quote threads. */
|
||||||
|
CONDENSED,
|
||||||
|
/** Less length restrictions. Used to show more info in message details. */
|
||||||
|
DETAILED,
|
||||||
|
}
|
|
@ -14,9 +14,7 @@ import android.widget.TextView;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.content.res.AppCompatResources;
|
import androidx.appcompat.content.res.AppCompatResources;
|
||||||
import androidx.cardview.widget.CardView;
|
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.core.content.res.ColorStateListInflaterCompat;
|
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.Observer;
|
||||||
|
@ -51,8 +49,6 @@ import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||||
import org.thoughtcrime.securesms.util.views.AutoRounder;
|
|
||||||
import org.thoughtcrime.securesms.util.views.Stub;
|
|
||||||
import org.thoughtcrime.securesms.verify.VerifyIdentityActivity;
|
import org.thoughtcrime.securesms.verify.VerifyIdentityActivity;
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||||
|
|
||||||
|
@ -129,7 +125,7 @@ public final class ConversationUpdateItem extends FrameLayout
|
||||||
boolean isMessageRequestAccepted,
|
boolean isMessageRequestAccepted,
|
||||||
boolean allowedToPlayInline,
|
boolean allowedToPlayInline,
|
||||||
@NonNull Colorizer colorizer,
|
@NonNull Colorizer colorizer,
|
||||||
boolean isCondensedMode)
|
@NonNull ConversationItemDisplayMode displayMode)
|
||||||
{
|
{
|
||||||
this.batchSelected = batchSelected;
|
this.batchSelected = batchSelected;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.conversation.ConversationItem;
|
||||||
import org.thoughtcrime.securesms.conversation.ConversationMessage;
|
import org.thoughtcrime.securesms.conversation.ConversationMessage;
|
||||||
import org.thoughtcrime.securesms.conversation.colors.Colorizable;
|
import org.thoughtcrime.securesms.conversation.colors.Colorizable;
|
||||||
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
|
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
|
||||||
|
import org.thoughtcrime.securesms.conversation.ConversationItemDisplayMode;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4Playable;
|
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4Playable;
|
||||||
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicyEnforcer;
|
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicyEnforcer;
|
||||||
|
@ -110,7 +111,7 @@ final class MessageHeaderViewHolder extends RecyclerView.ViewHolder implements G
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
colorizer,
|
colorizer,
|
||||||
false);
|
ConversationItemDisplayMode.DETAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindErrorState(MessageRecord messageRecord) {
|
private void bindErrorState(MessageRecord messageRecord) {
|
||||||
|
|
|
@ -91,8 +91,6 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/Signal.Text.Body"
|
style="@style/Signal.Text.Body"
|
||||||
android:singleLine="true"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:clickable="false"
|
android:clickable="false"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
tools:text="The-Anarchist-Tension-by-Alfredo-Bonanno.pdf"/>
|
tools:text="The-Anarchist-Tension-by-Alfredo-Bonanno.pdf"/>
|
||||||
|
|
Ładowanie…
Reference in New Issue