mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 17:29:32 +01:00
Replace glyphs in group update messages.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols.Glyph;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
@@ -93,7 +94,7 @@ public class InMemoryMessageRecord extends MessageRecord {
|
||||
@Override
|
||||
public @Nullable UpdateDescription getUpdateDisplayBody(@NonNull Context context, @Nullable Consumer<RecipientId> recipientClickHandler) {
|
||||
return UpdateDescription.staticDescription(context.getString(R.string.ConversationUpdateItem_hidden_contact_message_to_add_back),
|
||||
R.drawable.symbol_info_compact_16);
|
||||
Glyph.INFO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,7 +123,7 @@ public class InMemoryMessageRecord extends MessageRecord {
|
||||
String update = context.getString(R.string.ConversationUpdateItem_the_disappearing_message_time_will_be_set_to_s_when_you_message_them,
|
||||
ExpirationUtil.getExpirationDisplayValue(context, SignalStore.settings().getUniversalExpireTimer()));
|
||||
|
||||
return UpdateDescription.staticDescription(update, R.drawable.symbol_timer_compact_24);
|
||||
return UpdateDescription.staticDescription(update, Glyph.TIMER);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
package org.thoughtcrime.securesms.database.model;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
@@ -18,12 +13,13 @@ import androidx.lifecycle.Transformations;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols.Glyph;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols.Weight;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.ContextUtil;
|
||||
import org.thoughtcrime.securesms.util.SpanUtil;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||
|
||||
import java.util.List;
|
||||
@@ -66,31 +62,25 @@ public final class LiveUpdateMessage {
|
||||
}
|
||||
|
||||
private static @NonNull SpannableString toSpannable(@NonNull Context context, @NonNull UpdateDescription updateDescription, @NonNull Spannable string, @ColorInt int defaultTint, boolean adjustPosition) {
|
||||
boolean isDarkTheme = ThemeUtil.isDarkTheme(context);
|
||||
int drawableResource = updateDescription.getIconResource();
|
||||
int tint = isDarkTheme ? updateDescription.getDarkTint() : updateDescription.getLightTint();
|
||||
boolean isDarkTheme = ThemeUtil.isDarkTheme(context);
|
||||
Glyph glyph = updateDescription.getGlyph();
|
||||
int tint = isDarkTheme ? updateDescription.getDarkTint() : updateDescription.getLightTint();
|
||||
|
||||
if (tint == 0) {
|
||||
tint = defaultTint;
|
||||
}
|
||||
|
||||
if (drawableResource == 0) {
|
||||
if (glyph == null) {
|
||||
return new SpannableString(string);
|
||||
} else {
|
||||
Drawable drawable = ContextUtil.requireDrawable(context, drawableResource);
|
||||
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
|
||||
drawable.setColorFilter(tint, PorterDuff.Mode.SRC_ATOP);
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder();
|
||||
CharSequence glyphChar = SignalSymbols.getSpannedString(context, Weight.REGULAR, glyph, -1);
|
||||
|
||||
int insetTop = adjustPosition ? ViewUtil.dpToPx(2) : 0;
|
||||
InsetDrawable insetDrawable = new InsetDrawable(drawable, 0, insetTop, 0, 0);
|
||||
insetDrawable.setBounds(0, 0, drawable.getIntrinsicWidth(), insetDrawable.getIntrinsicHeight());
|
||||
builder.append(glyphChar);
|
||||
builder.append(" ");
|
||||
builder.append(string);
|
||||
|
||||
Drawable spaceDrawable = new ColorDrawable(Color.TRANSPARENT);
|
||||
spaceDrawable.setBounds(0, 0, ViewUtil.dpToPx(8), drawable.getIntrinsicHeight());
|
||||
|
||||
Spannable stringWithImage = new SpannableStringBuilder().append(SpanUtil.buildImageSpan(drawable)).append(SpanUtil.buildImageSpan(spaceDrawable)).append(string);
|
||||
|
||||
return new SpannableString(SpanUtil.color(tint, stringWithImage));
|
||||
return new SpannableString(SpanUtil.color(tint, builder));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.compose.ui.text.AnnotatedString;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
@@ -54,6 +55,9 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.SessionSwitchove
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.ThreadMergeEvent;
|
||||
import org.thoughtcrime.securesms.emoji.EmojiSource;
|
||||
import org.thoughtcrime.securesms.emoji.JumboEmoji;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols.Glyph;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols.Weight;
|
||||
import org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.mms.Slide;
|
||||
@@ -193,69 +197,69 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
return getGv2ChangeDescription(context, getBody(), recipientClickHandler);
|
||||
}
|
||||
} else if (isGroupUpdate() && isOutgoing()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_you_updated_group), R.drawable.ic_update_group_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_you_updated_group), Glyph.GROUP);
|
||||
} else if (isGroupUpdate()) {
|
||||
return fromRecipient(getFromRecipient(), r -> GroupUtil.getNonV2GroupDescription(context, getBody()).toString(r), R.drawable.ic_update_group_16);
|
||||
return fromRecipient(getFromRecipient(), r -> GroupUtil.getNonV2GroupDescription(context, getBody()).toString(r), Glyph.GROUP);
|
||||
} else if (isGroupQuit() && isOutgoing()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_left_group), R.drawable.ic_update_group_leave_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_left_group), Glyph.LEAVE);
|
||||
} else if (isGroupQuit()) {
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.ConversationItem_group_action_left, r.getDisplayName(context)), R.drawable.ic_update_group_leave_16);
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.ConversationItem_group_action_left, r.getDisplayName(context)), Glyph.LEAVE);
|
||||
} else if (isIncomingAudioCall()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_incoming_voice_call), getCallDateString(context)), R.drawable.ic_update_audio_call_incoming_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_incoming_voice_call), getCallDateString(context)), Glyph.PHONE);
|
||||
} else if (isIncomingVideoCall()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_incoming_video_call), getCallDateString(context)), R.drawable.ic_update_video_call_incoming_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_incoming_video_call), getCallDateString(context)), Glyph.VIDEO_CAMERA);
|
||||
} else if (isOutgoingAudioCall()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_outgoing_voice_call), getCallDateString(context)), R.drawable.ic_update_audio_call_outgoing_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_outgoing_voice_call), getCallDateString(context)), Glyph.PHONE);
|
||||
} else if (isOutgoingVideoCall()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_outgoing_video_call), getCallDateString(context)), R.drawable.ic_update_video_call_outgoing_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_outgoing_video_call), getCallDateString(context)), Glyph.VIDEO_CAMERA);
|
||||
} else if (isMissedAudioCall()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_missed_voice_call), getCallDateString(context)), R.drawable.ic_update_audio_call_missed_16, ContextCompat.getColor(context, R.color.core_red_shade), ContextCompat.getColor(context, R.color.core_red));
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_missed_voice_call), getCallDateString(context)), Glyph.PHONE, ContextCompat.getColor(context, R.color.core_red_shade), ContextCompat.getColor(context, R.color.core_red));
|
||||
} else if (isMissedVideoCall()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_missed_video_call), getCallDateString(context)), R.drawable.ic_update_video_call_missed_16, ContextCompat.getColor(context, R.color.core_red_shade), ContextCompat.getColor(context, R.color.core_red));
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(R.string.MessageRecord_missed_video_call), getCallDateString(context)), Glyph.VIDEO_CAMERA, ContextCompat.getColor(context, R.color.core_red_shade), ContextCompat.getColor(context, R.color.core_red));
|
||||
} else if (isGroupCall()) {
|
||||
return getGroupCallUpdateDescription(context, getBody(), true);
|
||||
} else if (isJoined()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_s_joined_signal, getFromRecipient().getDisplayName(context)), R.drawable.ic_update_group_add_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_s_joined_signal, getFromRecipient().getDisplayName(context)), Glyph.PERSON_PLUS);
|
||||
} else if (isExpirationTimerUpdate()) {
|
||||
int seconds = (int)(getExpiresIn() / 1000);
|
||||
if (seconds <= 0) {
|
||||
return isOutgoing() ? staticUpdateDescription(context.getString(R.string.MessageRecord_you_disabled_disappearing_messages), R.drawable.ic_update_timer_disabled_16)
|
||||
: fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_s_disabled_disappearing_messages, r.getDisplayName(context)), R.drawable.ic_update_timer_disabled_16);
|
||||
return isOutgoing() ? staticUpdateDescription(context.getString(R.string.MessageRecord_you_disabled_disappearing_messages), Glyph.TIMER_SLASH)
|
||||
: fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_s_disabled_disappearing_messages, r.getDisplayName(context)), Glyph.TIMER_SLASH);
|
||||
}
|
||||
String time = ExpirationUtil.getExpirationDisplayValue(context, seconds);
|
||||
return isOutgoing() ? staticUpdateDescription(context.getString(R.string.MessageRecord_you_set_disappearing_message_time_to_s, time), R.drawable.ic_update_timer_16)
|
||||
: fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_s_set_disappearing_message_time_to_s, r.getDisplayName(context), time), R.drawable.ic_update_timer_16);
|
||||
return isOutgoing() ? staticUpdateDescription(context.getString(R.string.MessageRecord_you_set_disappearing_message_time_to_s, time), Glyph.TIMER)
|
||||
: fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_s_set_disappearing_message_time_to_s, r.getDisplayName(context), time), Glyph.TIMER);
|
||||
} else if (isIdentityUpdate()) {
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_your_safety_number_with_s_has_changed, r.getDisplayName(context)), R.drawable.ic_update_safety_number_16);
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_your_safety_number_with_s_has_changed, r.getDisplayName(context)), Glyph.SAFETY_NUMBER);
|
||||
} else if (isIdentityVerified()) {
|
||||
if (isOutgoing()) return fromRecipient(getToRecipient(), r -> context.getString(R.string.MessageRecord_you_marked_your_safety_number_with_s_verified, r.getDisplayName(context)), R.drawable.ic_safety_number_16);
|
||||
else return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_you_marked_your_safety_number_with_s_verified_from_another_device, r.getDisplayName(context)), R.drawable.ic_safety_number_16);
|
||||
if (isOutgoing()) return fromRecipient(getToRecipient(), r -> context.getString(R.string.MessageRecord_you_marked_your_safety_number_with_s_verified, r.getDisplayName(context)), Glyph.SAFETY_NUMBER);
|
||||
else return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_you_marked_your_safety_number_with_s_verified_from_another_device, r.getDisplayName(context)), Glyph.SAFETY_NUMBER);
|
||||
} else if (isIdentityDefault()) {
|
||||
if (isOutgoing()) return fromRecipient(getToRecipient(), r -> context.getString(R.string.MessageRecord_you_marked_your_safety_number_with_s_unverified, r.getDisplayName(context)), R.drawable.ic_update_info_16);
|
||||
else return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_you_marked_your_safety_number_with_s_unverified_from_another_device, r.getDisplayName(context)), R.drawable.ic_update_info_16);
|
||||
if (isOutgoing()) return fromRecipient(getToRecipient(), r -> context.getString(R.string.MessageRecord_you_marked_your_safety_number_with_s_unverified, r.getDisplayName(context)), Glyph.INFO);
|
||||
else return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_you_marked_your_safety_number_with_s_unverified_from_another_device, r.getDisplayName(context)), Glyph.INFO);
|
||||
} else if (isProfileChange()) {
|
||||
return getProfileChangeDescription(context);
|
||||
} else if (isChangeNumber()) {
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_s_changed_their_phone_number, r.getDisplayName(context)), R.drawable.ic_phone_16);
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_s_changed_their_phone_number, r.getDisplayName(context)), Glyph.PHONE);
|
||||
} else if (isReleaseChannelDonationRequest()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_like_this_new_feature_help_support_signal_with_a_one_time_donation), 0);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_like_this_new_feature_help_support_signal_with_a_one_time_donation), null);
|
||||
} else if (isEndSession()) {
|
||||
if (isOutgoing()) return staticUpdateDescription(context.getString(R.string.SmsMessageRecord_secure_session_reset), R.drawable.ic_update_info_16);
|
||||
else return fromRecipient(getFromRecipient(), r-> context.getString(R.string.SmsMessageRecord_secure_session_reset_s, r.getDisplayName(context)), R.drawable.ic_update_info_16);
|
||||
if (isOutgoing()) return staticUpdateDescription(context.getString(R.string.SmsMessageRecord_secure_session_reset), Glyph.INFO);
|
||||
else return fromRecipient(getFromRecipient(), r-> context.getString(R.string.SmsMessageRecord_secure_session_reset_s, r.getDisplayName(context)), Glyph.INFO);
|
||||
} else if (isGroupV1MigrationEvent()) {
|
||||
return getGroupMigrationEventDescription(context);
|
||||
} else if (isChatSessionRefresh()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_chat_session_refreshed), R.drawable.ic_refresh_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_chat_session_refreshed), Glyph.REFRESH);
|
||||
} else if (isBadDecryptType()) {
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_a_message_from_s_couldnt_be_delivered, r.getDisplayName(context)), R.drawable.ic_error_outline_14);
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_a_message_from_s_couldnt_be_delivered, r.getDisplayName(context)), Glyph.ERROR);
|
||||
} else if (isThreadMergeEventType()) {
|
||||
try {
|
||||
ThreadMergeEvent event = ThreadMergeEvent.ADAPTER.decode(Base64.decodeOrThrow(getBody()));
|
||||
|
||||
if (event.previousE164.isEmpty()) {
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_your_message_history_with_s_and_another_chat_has_been_merged, r.getDisplayName(context)), R.drawable.ic_thread_merge_16);
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_your_message_history_with_s_and_another_chat_has_been_merged, r.getDisplayName(context)), Glyph.MERGE);
|
||||
} else {
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_your_message_history_with_s_and_their_number_s_has_been_merged, r.getDisplayName(context), SignalE164Util.prettyPrint(event.previousE164)), R.drawable.ic_thread_merge_16);
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_your_message_history_with_s_and_their_number_s_has_been_merged, r.getDisplayName(context), SignalE164Util.prettyPrint(event.previousE164)), Glyph.MERGE);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
@@ -265,30 +269,30 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
SessionSwitchoverEvent event = SessionSwitchoverEvent.ADAPTER.decode(Base64.decodeOrThrow(getBody()));
|
||||
|
||||
if (event.e164.isEmpty()) {
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_your_safety_number_with_s_has_changed, r.getDisplayName(context)), R.drawable.ic_update_safety_number_16);
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_your_safety_number_with_s_has_changed, r.getDisplayName(context)), Glyph.SAFETY_NUMBER);
|
||||
} else {
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_s_belongs_to_s, SignalE164Util.prettyPrint(event.e164), r.getDisplayName(context)), R.drawable.ic_update_info_16);
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_s_belongs_to_s, SignalE164Util.prettyPrint(event.e164), r.getDisplayName(context)), Glyph.INFO);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
} else if (isSmsExportType()) {
|
||||
int messageResource = R.string.MessageRecord__you_can_no_longer_send_sms_messages_in_signal;
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(messageResource, r.getDisplayName(context)), R.drawable.ic_update_info_16);
|
||||
return fromRecipient(getFromRecipient(), r -> context.getString(messageResource, r.getDisplayName(context)), Glyph.INFO);
|
||||
} else if (isPaymentsRequestToActivate()) {
|
||||
return isOutgoing() ? fromRecipient(getToRecipient(), r -> context.getString(R.string.MessageRecord_you_sent_request, r.getShortDisplayName(context)), R.drawable.ic_card_activate_payments)
|
||||
: fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_wants_you_to_activate_payments, r.getShortDisplayName(context)), R.drawable.ic_card_activate_payments);
|
||||
return isOutgoing() ? fromRecipient(getToRecipient(), r -> context.getString(R.string.MessageRecord_you_sent_request, r.getShortDisplayName(context)), Glyph.ACTIVATE_PAYMENTS)
|
||||
: fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_wants_you_to_activate_payments, r.getShortDisplayName(context)), Glyph.ACTIVATE_PAYMENTS);
|
||||
} else if (isPaymentsActivated()) {
|
||||
return isOutgoing() ? staticUpdateDescription(context.getString(R.string.MessageRecord_you_activated_payments), R.drawable.ic_card_activate_payments)
|
||||
: fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_can_accept_payments, r.getShortDisplayName(context)), R.drawable.ic_card_activate_payments);
|
||||
return isOutgoing() ? staticUpdateDescription(context.getString(R.string.MessageRecord_you_activated_payments), Glyph.ACTIVATE_PAYMENTS)
|
||||
: fromRecipient(getFromRecipient(), r -> context.getString(R.string.MessageRecord_can_accept_payments, r.getShortDisplayName(context)), Glyph.ACTIVATE_PAYMENTS);
|
||||
} else if (isReportedSpam()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_reported_as_spam), R.drawable.symbol_spam_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_reported_as_spam), Glyph.SPAM);
|
||||
} else if (isMessageRequestAccepted()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_you_accepted_the_message_request), R.drawable.symbol_thread_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_you_accepted_the_message_request), Glyph.THREAD);
|
||||
} else if (isBlocked()) {
|
||||
return staticUpdateDescription(context.getString(isGroupV2() ? R.string.MessageRecord_you_blocked_this_group : R.string.MessageRecord_you_blocked_this_person), R.drawable.symbol_block_16);
|
||||
return staticUpdateDescription(context.getString(isGroupV2() ? R.string.MessageRecord_you_blocked_this_group : R.string.MessageRecord_you_blocked_this_person), Glyph.BLOCK);
|
||||
} else if (isUnblocked()) {
|
||||
return staticUpdateDescription(context.getString(isGroupV2() ? R.string.MessageRecord_you_unblocked_this_group : R.string.MessageRecord_you_unblocked_this_person) , R.drawable.symbol_thread_16);
|
||||
return staticUpdateDescription(context.getString(isGroupV2() ? R.string.MessageRecord_you_unblocked_this_group : R.string.MessageRecord_you_unblocked_this_person) , Glyph.THREAD);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -352,7 +356,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
return getGv2ChangeDescription(context, decryptedGroupV2Context, recipientClickHandler);
|
||||
} catch (IOException | IllegalArgumentException | IllegalStateException e) {
|
||||
Log.w(TAG, "GV2 Message update detail could not be read", e);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_group_updated), R.drawable.ic_update_group_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_group_updated), Glyph.GROUP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +372,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
Log.w(TAG, "GV2 Update Description missing group change update!");
|
||||
}
|
||||
}
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_group_updated), R.drawable.ic_update_group_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_group_updated), Glyph.GROUP);
|
||||
}
|
||||
|
||||
public static @NonNull UpdateDescription getGv2ChangeDescription(@NonNull Context context, @NonNull DecryptedGroupV2Context decryptedGroupV2Context, @Nullable Consumer<RecipientId> recipientClickHandler) {
|
||||
@@ -386,20 +390,20 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
}
|
||||
|
||||
if (selfCreatedGroup(decryptedGroupV2Context.change)) {
|
||||
newGroupDescriptions.add(staticUpdateDescription(context.getString(R.string.MessageRecord_invite_friends_to_this_group), 0));
|
||||
newGroupDescriptions.add(staticUpdateDescription(context.getString(R.string.MessageRecord_invite_friends_to_this_group), null));
|
||||
}
|
||||
return concatWithNewLinesCapped(context, newGroupDescriptions);
|
||||
}
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
Log.w(TAG, "GV2 Message update detail could not be read", e);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_group_updated), R.drawable.ic_update_group_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_group_updated), Glyph.GROUP);
|
||||
}
|
||||
}
|
||||
|
||||
private static @NonNull UpdateDescription concatWithNewLinesCapped(@NonNull Context context, @NonNull List<UpdateDescription> updateDescriptions) {
|
||||
if (updateDescriptions.size() > 100) {
|
||||
// Arbitrary update description collapse cap, otherwise the long string can cause issues
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_group_updated), R.drawable.ic_update_group_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_group_updated), Glyph.GROUP);
|
||||
}
|
||||
return UpdateDescription.concatWithNewLines(updateDescriptions);
|
||||
}
|
||||
@@ -437,25 +441,25 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
|
||||
protected static @NonNull UpdateDescription fromRecipient(@NonNull Recipient recipient,
|
||||
@NonNull Function<Recipient, String> stringGenerator,
|
||||
@DrawableRes int iconResource)
|
||||
Glyph glyph)
|
||||
{
|
||||
return UpdateDescription.mentioning(Collections.singletonList(recipient.getAci().orElse(ACI.UNKNOWN)),
|
||||
() -> new SpannableString(stringGenerator.apply(recipient.resolve())),
|
||||
iconResource);
|
||||
glyph);
|
||||
}
|
||||
|
||||
protected static @NonNull UpdateDescription staticUpdateDescription(@NonNull String string,
|
||||
@DrawableRes int iconResource)
|
||||
Glyph glyph)
|
||||
{
|
||||
return UpdateDescription.staticDescription(string, iconResource);
|
||||
return UpdateDescription.staticDescription(string, glyph);
|
||||
}
|
||||
|
||||
protected static @NonNull UpdateDescription staticUpdateDescription(@NonNull String string,
|
||||
@DrawableRes int iconResource,
|
||||
Glyph glyph,
|
||||
@ColorInt int lightTint,
|
||||
@ColorInt int darkTint)
|
||||
{
|
||||
return UpdateDescription.staticDescription(string, iconResource, lightTint, darkTint);
|
||||
return UpdateDescription.staticDescription(string, glyph, lightTint, darkTint);
|
||||
}
|
||||
|
||||
private @NonNull UpdateDescription getProfileChangeDescription(@NonNull Context context) {
|
||||
@@ -486,9 +490,9 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
updateMessage = context.getString(R.string.MessageRecord_changed_their_profile_name_to, previousName, newName);
|
||||
}
|
||||
|
||||
return staticUpdateDescription(updateMessage, R.drawable.ic_update_profile_16);
|
||||
return staticUpdateDescription(updateMessage, Glyph.PERSON);
|
||||
} else if (profileChangeDetails.deprecatedLearnedProfileName != null) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_started_this_chat, profileChangeDetails.deprecatedLearnedProfileName.previous), R.drawable.symbol_thread_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_started_this_chat, profileChangeDetails.deprecatedLearnedProfileName.previous), Glyph.THREAD);
|
||||
} else if (profileChangeDetails.learnedProfileName != null) {
|
||||
String previouslyKnownAs;
|
||||
if (!Util.isEmpty(profileChangeDetails.learnedProfileName.e164)) {
|
||||
@@ -498,31 +502,31 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
}
|
||||
|
||||
if (!Util.isEmpty(previouslyKnownAs)) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_started_this_chat, previouslyKnownAs), R.drawable.symbol_thread_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_started_this_chat, previouslyKnownAs), Glyph.THREAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_changed_their_profile, getFromRecipient().getDisplayName(context)), R.drawable.ic_update_profile_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_changed_their_profile, getFromRecipient().getDisplayName(context)), Glyph.PERSON);
|
||||
}
|
||||
|
||||
private UpdateDescription getGroupMigrationEventDescription(@NonNull Context context) {
|
||||
if (Util.isEmpty(getBody())) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_this_group_was_updated_to_a_new_group), R.drawable.ic_update_group_role_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_this_group_was_updated_to_a_new_group), Glyph.MEGAPHONE);
|
||||
} else {
|
||||
GroupMigrationMembershipChange change = getGroupV1MigrationMembershipChanges();
|
||||
List<UpdateDescription> updates = new ArrayList<>(2);
|
||||
|
||||
if (change.getPending().size() == 1 && change.getPending().get(0).equals(Recipient.self().getId())) {
|
||||
updates.add(staticUpdateDescription(context.getString(R.string.MessageRecord_you_couldnt_be_added_to_the_new_group_and_have_been_invited_to_join), R.drawable.ic_update_group_add_16));
|
||||
updates.add(staticUpdateDescription(context.getString(R.string.MessageRecord_you_couldnt_be_added_to_the_new_group_and_have_been_invited_to_join), Glyph.PERSON_PLUS));
|
||||
} else if (change.getPending().size() > 0) {
|
||||
int count = change.getPending().size();
|
||||
updates.add(staticUpdateDescription(context.getResources().getQuantityString(R.plurals.MessageRecord_members_couldnt_be_added_to_the_new_group_and_have_been_invited, count, count), R.drawable.ic_update_group_add_16));
|
||||
updates.add(staticUpdateDescription(context.getResources().getQuantityString(R.plurals.MessageRecord_members_couldnt_be_added_to_the_new_group_and_have_been_invited, count, count), Glyph.PERSON_PLUS));
|
||||
}
|
||||
|
||||
if (change.getDropped().size() > 0) {
|
||||
int count = change.getDropped().size();
|
||||
updates.add(staticUpdateDescription(context.getResources().getQuantityString(R.plurals.MessageRecord_members_couldnt_be_added_to_the_new_group_and_have_been_removed, count, count), R.drawable.ic_update_group_remove_16));
|
||||
updates.add(staticUpdateDescription(context.getResources().getQuantityString(R.plurals.MessageRecord_members_couldnt_be_added_to_the_new_group_and_have_been_removed, count, count), Glyph.PERSON_MINUS));
|
||||
}
|
||||
|
||||
return concatWithNewLinesCapped(context, updates);
|
||||
@@ -540,7 +544,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
|
||||
UpdateDescription.SpannableFactory stringFactory = new GroupCallUpdateMessageFactory(context, joinedMembers, withTime, groupCallUpdateDetails);
|
||||
|
||||
return UpdateDescription.mentioning(joinedMembers, stringFactory, R.drawable.ic_video_16);
|
||||
return UpdateDescription.mentioning(joinedMembers, stringFactory, Glyph.VIDEO_CAMERA);
|
||||
}
|
||||
|
||||
public boolean isGroupV2DescriptionUpdate() {
|
||||
|
||||
@@ -28,6 +28,8 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.CryptoValue;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.GiftBadge;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.MessageExtras;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols.Glyph;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||
import org.thoughtcrime.securesms.mms.Slide;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
@@ -250,20 +252,20 @@ public class MmsMessageRecord extends MessageRecord {
|
||||
if (call.getDirection() == CallTable.Direction.OUTGOING) {
|
||||
if (call.getType() == CallTable.Type.AUDIO_CALL) {
|
||||
int updateString = R.string.MessageRecord_outgoing_voice_call;
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(updateString), callDateString), R.drawable.ic_update_audio_call_outgoing_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(updateString), callDateString), Glyph.PHONE);
|
||||
} else {
|
||||
int updateString = R.string.MessageRecord_outgoing_video_call;
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(updateString), callDateString), R.drawable.ic_update_video_call_outgoing_16);
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(updateString), callDateString), Glyph.VIDEO_CAMERA);
|
||||
}
|
||||
} else {
|
||||
boolean isVideoCall = call.getType() == CallTable.Type.VIDEO_CALL;
|
||||
|
||||
if (accepted || !call.isDisplayedAsMissedCallInUi()) {
|
||||
int updateString = isVideoCall ? R.string.MessageRecord_incoming_video_call : R.string.MessageRecord_incoming_voice_call;
|
||||
int icon = isVideoCall ? R.drawable.ic_update_video_call_incoming_16 : R.drawable.ic_update_audio_call_incoming_16;
|
||||
Glyph icon = isVideoCall ? Glyph.VIDEO_CAMERA : Glyph.PHONE;
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_call_message_with_date, context.getString(updateString), callDateString), icon);
|
||||
} else {
|
||||
int icon = isVideoCall ? R.drawable.ic_update_video_call_missed_16 : R.drawable.ic_update_audio_call_missed_16;
|
||||
Glyph icon = isVideoCall ? Glyph.VIDEO_CAMERA : Glyph.PHONE;
|
||||
int message;
|
||||
if (call.getEvent() == CallTable.Event.MISSED_NOTIFICATION_PROFILE) {
|
||||
message = isVideoCall ? R.string.MessageRecord_missed_video_call_notification_profile : R.string.MessageRecord_missed_voice_call_notification_profile;
|
||||
|
||||
@@ -11,7 +11,8 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import org.whispersystems.signalservice.api.push.ServiceId.ACI;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols.Glyph;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -33,14 +34,14 @@ public final class UpdateDescription {
|
||||
private final Collection<ServiceId> mentioned;
|
||||
private final SpannableFactory stringFactory;
|
||||
private final Spannable staticString;
|
||||
private final int lightIconResource;
|
||||
private final Glyph glyph;
|
||||
private final int lightTint;
|
||||
private final int darkTint;
|
||||
|
||||
private UpdateDescription(@NonNull Collection<ServiceId> mentioned,
|
||||
@Nullable SpannableFactory stringFactory,
|
||||
@Nullable Spannable staticString,
|
||||
@DrawableRes int iconResource,
|
||||
@NonNull Glyph glyph,
|
||||
@ColorInt int lightTint,
|
||||
@ColorInt int darkTint)
|
||||
{
|
||||
@@ -50,7 +51,7 @@ public final class UpdateDescription {
|
||||
this.mentioned = mentioned;
|
||||
this.stringFactory = stringFactory;
|
||||
this.staticString = staticString;
|
||||
this.lightIconResource = iconResource;
|
||||
this.glyph = glyph;
|
||||
this.lightTint = lightTint;
|
||||
this.darkTint = darkTint;
|
||||
}
|
||||
@@ -64,43 +65,43 @@ public final class UpdateDescription {
|
||||
*/
|
||||
public static UpdateDescription mentioning(@NonNull Collection<ServiceId> mentioned,
|
||||
@NonNull SpannableFactory stringFactory,
|
||||
@DrawableRes int iconResource)
|
||||
Glyph glyph)
|
||||
{
|
||||
return new UpdateDescription(mentioned.stream().filter(ServiceId::isValid).collect(Collectors.toList()),
|
||||
stringFactory,
|
||||
null,
|
||||
iconResource,
|
||||
glyph,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an update description that's string value is fixed.
|
||||
* Create an update description that's string value is fixed with a start glyph.
|
||||
*/
|
||||
public static UpdateDescription staticDescription(@NonNull String staticString,
|
||||
@DrawableRes int iconResource)
|
||||
Glyph glyph)
|
||||
{
|
||||
return new UpdateDescription(Collections.emptyList(), null, new SpannableString(staticString), iconResource, 0, 0);
|
||||
return new UpdateDescription(Collections.emptyList(), null, new SpannableString(staticString), glyph, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an update description that's string value is fixed.
|
||||
*/
|
||||
public static UpdateDescription staticDescription(@NonNull Spannable staticString,
|
||||
@DrawableRes int iconResource)
|
||||
Glyph glyph)
|
||||
{
|
||||
return new UpdateDescription(Collections.emptyList(), null, staticString, iconResource, 0, 0);
|
||||
return new UpdateDescription(Collections.emptyList(), null, staticString, glyph, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an update description that's string value is fixed with a specific tint color.
|
||||
*/
|
||||
public static UpdateDescription staticDescription(@NonNull String staticString,
|
||||
@DrawableRes int iconResource,
|
||||
Glyph glyph,
|
||||
@ColorInt int lightTint,
|
||||
@ColorInt int darkTint)
|
||||
{
|
||||
return new UpdateDescription(Collections.emptyList(), null, new SpannableString(staticString), iconResource, lightTint, darkTint);
|
||||
return new UpdateDescription(Collections.emptyList(), null, new SpannableString(staticString), glyph, lightTint, darkTint);
|
||||
}
|
||||
|
||||
public boolean isStringStatic() {
|
||||
@@ -131,8 +132,8 @@ public final class UpdateDescription {
|
||||
return mentioned;
|
||||
}
|
||||
|
||||
public @DrawableRes int getIconResource() {
|
||||
return lightIconResource;
|
||||
public @Nullable Glyph getGlyph() {
|
||||
return glyph;
|
||||
}
|
||||
|
||||
public @ColorInt int getLightTint() {
|
||||
@@ -154,7 +155,7 @@ public final class UpdateDescription {
|
||||
|
||||
if (allAreStatic(updateDescriptions)) {
|
||||
return UpdateDescription.staticDescription(concatStaticLines(updateDescriptions),
|
||||
updateDescriptions.get(0).getIconResource()
|
||||
updateDescriptions.get(0).getGlyph()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -166,7 +167,7 @@ public final class UpdateDescription {
|
||||
|
||||
return UpdateDescription.mentioning(allMentioned,
|
||||
() -> concatLines(updateDescriptions),
|
||||
updateDescriptions.get(0).getIconResource());
|
||||
updateDescriptions.get(0).getGlyph());
|
||||
}
|
||||
|
||||
private static boolean allAreStatic(@NonNull Collection<UpdateDescription> updateDescriptions) {
|
||||
|
||||
Reference in New Issue
Block a user