Do not linkify message body if recipient is not message request accepted.

Co-authored-by: Greyson Parrelli <greyson@signal.org>
fork-5.53.8
Alan Evans 2021-02-03 12:45:14 -04:00 zatwierdzone przez Greyson Parrelli
rodzic 213ffdab62
commit ddb04c6ea3
8 zmienionych plików z 67 dodań i 29 usunięć

Wyświetl plik

@ -37,7 +37,8 @@ public interface BindableConversationItem extends Unbindable {
@NonNull Recipient recipients,
@Nullable String searchQuery,
boolean pulseMention,
boolean hasWallpaper);
boolean hasWallpaper,
boolean isMessageRequestAccepted);
ConversationMessage getConversationMessage();

Wyświetl plik

@ -17,7 +17,6 @@
package org.thoughtcrime.securesms.conversation;
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -44,6 +43,7 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.util.CachedInflater;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
@ -112,6 +112,7 @@ public class ConversationAdapter
private View footerView;
private PagingController pagingController;
private boolean hasWallpaper;
private boolean isMessageRequestAccepted;
ConversationAdapter(@NonNull LifecycleOwner lifecycleOwner,
@NonNull GlideRequests glideRequests,
@ -133,16 +134,17 @@ public class ConversationAdapter
this.lifecycleOwner = lifecycleOwner;
this.glideRequests = glideRequests;
this.locale = locale;
this.clickListener = clickListener;
this.recipient = recipient;
this.selected = new HashSet<>();
this.fastRecords = new ArrayList<>();
this.releasedFastRecords = new HashSet<>();
this.calendar = Calendar.getInstance();
this.digest = getMessageDigestOrThrow();
this.hasWallpaper = recipient.hasWallpaper();
this.glideRequests = glideRequests;
this.locale = locale;
this.clickListener = clickListener;
this.recipient = recipient;
this.selected = new HashSet<>();
this.fastRecords = new ArrayList<>();
this.releasedFastRecords = new HashSet<>();
this.calendar = Calendar.getInstance();
this.digest = getMessageDigestOrThrow();
this.hasWallpaper = recipient.hasWallpaper();
this.isMessageRequestAccepted = true;
setHasStableIds(true);
}
@ -254,7 +256,8 @@ public class ConversationAdapter
recipient,
searchQuery,
conversationMessage == recordToPulse,
hasWallpaper);
hasWallpaper,
isMessageRequestAccepted);
if (conversationMessage == recordToPulse) {
recordToPulse = null;
@ -595,6 +598,13 @@ public class ConversationAdapter
return getItem(position - ((hasFooter() && position == getItemCount() - 1) ? 1 : 0));
}
public void setMessageRequestAccepted(boolean messageRequestAccepted) {
if (this.isMessageRequestAccepted != messageRequestAccepted) {
this.isMessageRequestAccepted = messageRequestAccepted;
notifyDataSetChanged();
}
}
static class ConversationViewHolder extends RecyclerView.ViewHolder {
public ConversationViewHolder(final @NonNull View itemView) {
super(itemView);

Wyświetl plik

@ -23,7 +23,6 @@ import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@ -105,6 +104,7 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreview;
import org.thoughtcrime.securesms.longmessage.LongMessageActivity;
import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.messagedetails.MessageDetailsActivity;
import org.thoughtcrime.securesms.messagerequests.MessageRequestState;
import org.thoughtcrime.securesms.messagerequests.MessageRequestViewModel;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
@ -426,6 +426,13 @@ public class ConversationFragment extends LoggingFragment {
presentMessageRequestProfileView(requireContext(), recipientInfo, conversationBanner);
presentMessageRequestProfileView(requireContext(), recipientInfo, emptyConversationBanner);
});
messageRequestViewModel.getMessageData().observe(getViewLifecycleOwner(), data -> {
ConversationAdapter adapter = getListAdapter();
if (adapter != null) {
adapter.setMessageRequestAccepted(data.getMessageState() == MessageRequestState.NONE);
}
});
}
private static void presentMessageRequestProfileView(@NonNull Context context, @NonNull MessageRequestViewModel.RecipientInfo recipientInfo, @Nullable ConversationBannerView conversationBanner) {

Wyświetl plik

@ -259,7 +259,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
@NonNull Recipient conversationRecipient,
@Nullable String searchQuery,
boolean pulse,
boolean hasWallpaper)
boolean hasWallpaper,
boolean isMessageRequestAccepted)
{
if (this.recipient != null) this.recipient.removeForeverObserver(this);
if (this.conversationRecipient != null) this.conversationRecipient.removeForeverObserver(this);
@ -280,8 +281,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
setGutterSizes(messageRecord, groupThread);
setMessageShape(messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
setMediaAttributes(messageRecord, previousMessageRecord, nextMessageRecord, conversationRecipient, groupThread, hasWallpaper);
setBodyText(messageRecord, searchQuery);
setMediaAttributes(messageRecord, previousMessageRecord, nextMessageRecord, groupThread, hasWallpaper, isMessageRequestAccepted);
setBodyText(messageRecord, searchQuery, isMessageRequestAccepted);
setBubbleState(messageRecord, hasWallpaper);
setInteractionState(conversationMessage, pulse);
setStatusIcons(messageRecord, hasWallpaper);
@ -627,7 +628,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
}
private void setBodyText(@NonNull MessageRecord messageRecord,
@Nullable String searchQuery)
@Nullable String searchQuery,
boolean messageRequestAccepted)
{
bodyText.setClickable(false);
bodyText.setFocusable(false);
@ -649,7 +651,10 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
} else if (isCaptionlessMms(messageRecord)) {
bodyText.setVisibility(View.GONE);
} else {
Spannable styledText = linkifyMessageBody(conversationMessage.getDisplayBody(getContext()), batchSelected.isEmpty());
Spannable styledText = conversationMessage.getDisplayBody(getContext());
if (messageRequestAccepted) {
linkifyMessageBody(styledText, batchSelected.isEmpty());
}
styledText = SearchUtil.getHighlightedSpan(locale, () -> new BackgroundColorSpan(Color.YELLOW), styledText, searchQuery);
styledText = SearchUtil.getHighlightedSpan(locale, () -> new ForegroundColorSpan(Color.BLACK), styledText, searchQuery);
@ -673,9 +678,9 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
private void setMediaAttributes(@NonNull MessageRecord messageRecord,
@NonNull Optional<MessageRecord> previousRecord,
@NonNull Optional<MessageRecord> nextRecord,
@NonNull Recipient conversationRecipient,
boolean isGroupThread,
boolean hasWallpaper)
boolean hasWallpaper,
boolean messageRequestAccepted)
{
boolean showControls = !messageRecord.isFailed();
@ -717,7 +722,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ViewUtil.updateLayoutParamsIfNonNull(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
footer.setVisibility(GONE);
} else if (hasLinkPreview(messageRecord)) {
} else if (hasLinkPreview(messageRecord) && messageRequestAccepted) {
linkPreviewStub.get().setVisibility(View.VISIBLE);
if (audioViewStub.resolved()) audioViewStub.get().setVisibility(View.GONE);
if (mediaThumbnailStub.resolved()) mediaThumbnailStub.get().setVisibility(View.GONE);
@ -982,8 +987,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
contactPhoto.setAvatar(glideRequests, recipient, false);
}
private SpannableString linkifyMessageBody(@NonNull SpannableString messageBody,
boolean shouldLinkifyAllLinks)
private void linkifyMessageBody(@NonNull Spannable messageBody,
boolean shouldLinkifyAllLinks)
{
int linkPattern = Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS;
boolean hasLinks = Linkify.addLinks(messageBody, shouldLinkifyAllLinks ? linkPattern : 0);
@ -1007,8 +1012,6 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
for (Annotation annotation : mentionAnnotations) {
messageBody.setSpan(new MentionClickableSpan(RecipientId.from(annotation.getValue())), messageBody.getSpanStart(annotation), messageBody.getSpanEnd(annotation), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return messageBody;
}
private void setStatusIcons(MessageRecord messageRecord, boolean hasWallpaper) {

Wyświetl plik

@ -100,7 +100,8 @@ public final class ConversationUpdateItem extends FrameLayout
@NonNull Recipient conversationRecipient,
@Nullable String searchQuery,
boolean pulseMention,
boolean hasWallpaper)
boolean hasWallpaper,
boolean isMessageRequestAccepted)
{
this.batchSelected = batchSelected;

Wyświetl plik

@ -19,9 +19,9 @@ import org.thoughtcrime.securesms.database.DatabaseObserver;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.mediasend.MediaRepository;
import org.thoughtcrime.securesms.recipients.LiveRecipient;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
import org.whispersystems.libsignal.util.Pair;

Wyświetl plik

@ -88,7 +88,7 @@ final class MessageHeaderViewHolder extends RecyclerView.ViewHolder {
conversationItem = (ConversationItem) receivedStub.inflate();
}
}
conversationItem.bind(lifecycleOwner, conversationMessage, Optional.absent(), Optional.absent(), glideRequests, Locale.getDefault(), new HashSet<>(), conversationMessage.getMessageRecord().getRecipient(), null, false, false);
conversationItem.bind(lifecycleOwner, conversationMessage, Optional.absent(), Optional.absent(), glideRequests, Locale.getDefault(), new HashSet<>(), conversationMessage.getMessageRecord().getRecipient(), null, false, false, false);
}
private void bindErrorState(MessageRecord messageRecord) {

Wyświetl plik

@ -198,6 +198,22 @@ public final class LiveDataUtil {
return outputLiveData;
}
/**
* Observes a source until the predicate is met. The final value matching the predicate is emitted.
*/
public static @NonNull <A> LiveData<A> until(@NonNull LiveData<A> source, @NonNull Predicate<A> predicate) {
MediatorLiveData<A> mediator = new MediatorLiveData<>();
mediator.addSource(source, newValue -> {
mediator.setValue(newValue);
if (predicate.test(newValue)) {
mediator.removeSource(source);
}
});
return mediator;
}
public interface Combine<A, B, R> {
@NonNull R apply(@NonNull A a, @NonNull B b);
}