That fuck shit the fascists are using
at master 157 lines 6.7 kB view raw
1package org.tm.archive.longmessage; 2 3import android.graphics.PorterDuff; 4import android.os.Bundle; 5import android.text.SpannableString; 6import android.util.TypedValue; 7import android.view.View; 8import android.view.ViewGroup; 9import android.widget.Toast; 10 11import androidx.annotation.NonNull; 12import androidx.annotation.Nullable; 13import androidx.core.content.ContextCompat; 14import androidx.fragment.app.DialogFragment; 15import androidx.lifecycle.ViewModelProvider; 16 17import org.tm.archive.R; 18import org.tm.archive.components.ConversationItemFooter; 19import org.tm.archive.components.FullScreenDialogFragment; 20import org.tm.archive.components.emoji.EmojiTextView; 21import org.tm.archive.conversation.ConversationItemDisplayMode; 22import org.tm.archive.conversation.colors.ColorizerView; 23import org.tm.archive.conversation.v2.items.V2ConversationItemUtils; 24import org.tm.archive.keyvalue.SignalStore; 25import org.tm.archive.recipients.Recipient; 26import org.tm.archive.util.CommunicationActions; 27import org.tm.archive.util.LongClickMovementMethod; 28import org.tm.archive.util.Projection; 29import org.tm.archive.util.ThemeUtil; 30import org.tm.archive.util.views.Stub; 31 32import java.util.Collections; 33import java.util.Locale; 34 35public class LongMessageFragment extends FullScreenDialogFragment { 36 37 private static final String KEY_MESSAGE_ID = "message_id"; 38 private static final String KEY_IS_MMS = "is_mms"; 39 40 private static final int MAX_DISPLAY_LENGTH = 64 * 1024; 41 42 private Stub<ViewGroup> sentBubble; 43 private Stub<ViewGroup> receivedBubble; 44 private ColorizerView colorizerView; 45 private BubbleLayoutListener bubbleLayoutListener; 46 47 private LongMessageViewModel viewModel; 48 49 public static DialogFragment create(long messageId, boolean isMms) { 50 DialogFragment fragment = new LongMessageFragment(); 51 Bundle args = new Bundle(); 52 53 args.putLong(KEY_MESSAGE_ID, messageId); 54 args.putBoolean(KEY_IS_MMS, isMms); 55 56 fragment.setArguments(args); 57 58 return fragment; 59 } 60 61 62 @Override 63 protected int getTitle() { 64 return -1; 65 } 66 67 @Override 68 protected int getDialogLayoutResource() { 69 return R.layout.longmessage_fragment; 70 } 71 72 @Override 73 public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 74 sentBubble = new Stub<>(view.findViewById(R.id.longmessage_sent_stub)); 75 receivedBubble = new Stub<>(view.findViewById(R.id.longmessage_received_stub)); 76 colorizerView = view.findViewById(R.id.colorizer); 77 78 bubbleLayoutListener = new BubbleLayoutListener(); 79 80 initViewModel(requireArguments().getLong(KEY_MESSAGE_ID, -1), requireArguments().getBoolean(KEY_IS_MMS, false)); 81 } 82 83 private void initViewModel(long messageId, boolean isMms) { 84 viewModel = new ViewModelProvider(this, 85 new LongMessageViewModel.Factory(requireActivity().getApplication(), 86 new LongMessageRepository(), messageId, isMms)) 87 .get(LongMessageViewModel.class); 88 89 viewModel.getMessage().observe(this, message -> { 90 if (message == null) return; 91 92 if (!message.isPresent()) { 93 Toast.makeText(requireContext(), R.string.LongMessageActivity_unable_to_find_message, Toast.LENGTH_SHORT).show(); 94 dismissAllowingStateLoss(); 95 return; 96 } 97 98 99 if (message.get().getMessageRecord().isOutgoing()) { 100 toolbar.setTitle(getString(R.string.LongMessageActivity_your_message)); 101 } else { 102 Recipient recipient = message.get().getMessageRecord().getFromRecipient(); 103 String name = recipient.getDisplayName(requireContext()); 104 105 toolbar.setTitle(getString(R.string.LongMessageActivity_message_from_s, name)); 106 } 107 108 ViewGroup bubble; 109 110 if (message.get().getMessageRecord().isOutgoing()) { 111 bubble = sentBubble.get(); 112 colorizerView.setVisibility(View.VISIBLE); 113 colorizerView.setBackground(message.get().getMessageRecord().getToRecipient().getChatColors().getChatBubbleMask()); 114 bubble.getBackground().setColorFilter(message.get().getMessageRecord().getToRecipient().getChatColors().getChatBubbleColorFilter()); 115 bubble.addOnLayoutChangeListener(bubbleLayoutListener); 116 bubbleLayoutListener.onLayoutChange(bubble, 0, 0, 0, 0, 0, 0, 0, 0); 117 } else { 118 bubble = receivedBubble.get(); 119 bubble.getBackground().setColorFilter(ContextCompat.getColor(requireContext(), R.color.signal_background_secondary), PorterDuff.Mode.MULTIPLY); 120 } 121 122 EmojiTextView text = bubble.findViewById(R.id.longmessage_text); 123 ConversationItemFooter footer = bubble.findViewById(R.id.longmessage_footer); 124 125 SpannableString body = new SpannableString(getTrimmedBody(message.get().getFullBody(requireContext()))); 126 V2ConversationItemUtils.linkifyUrlLinks(body, 127 true, 128 url -> CommunicationActions.handlePotentialGroupLinkUrl(requireActivity(), url) || 129 CommunicationActions.handlePotentialProxyLinkUrl(requireActivity(), url)); 130 131 bubble.setVisibility(View.VISIBLE); 132 text.setText(body); 133 text.setMovementMethod(LongClickMovementMethod.getInstance(getContext())); 134 text.setTextSize(TypedValue.COMPLEX_UNIT_SP, SignalStore.settings().getMessageFontSize()); 135 if (!message.get().getMessageRecord().isOutgoing()) { 136 text.setMentionBackgroundTint(ContextCompat.getColor(requireContext(), ThemeUtil.isDarkTheme(requireActivity()) ? R.color.core_grey_60 : R.color.core_grey_20)); 137 } else { 138 text.setMentionBackgroundTint(ContextCompat.getColor(requireContext(), R.color.transparent_black_40)); 139 } 140 footer.setMessageRecord(message.get().getMessageRecord(), Locale.getDefault(), ConversationItemDisplayMode.Standard.INSTANCE); 141 }); 142 } 143 144 private CharSequence getTrimmedBody(@NonNull CharSequence text) { 145 return text.length() <= MAX_DISPLAY_LENGTH ? text 146 : text.subSequence(0, MAX_DISPLAY_LENGTH); 147 } 148 149 private final class BubbleLayoutListener implements View.OnLayoutChangeListener { 150 @Override 151 public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 152 Projection projection = Projection.relativeToViewWithCommonRoot(v, colorizerView, new Projection.Corners(16)); 153 154 colorizerView.setProjections(Collections.singletonList(projection)); 155 } 156 } 157}