kopia lustrzana https://github.com/ryukoposting/Signal-Android
Do not linkify message body if recipient is not message request accepted.
Co-authored-by: Greyson Parrelli <greyson@signal.org>fork-5.53.8
rodzic
213ffdab62
commit
ddb04c6ea3
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue