That fuck shit the fascists are using
at master 188 lines 7.5 kB view raw
1package org.tm.archive.messagedetails; 2 3import android.content.DialogInterface; 4import android.os.Bundle; 5import android.view.View; 6import android.widget.FrameLayout; 7 8import androidx.annotation.NonNull; 9import androidx.annotation.Nullable; 10import androidx.fragment.app.DialogFragment; 11import androidx.lifecycle.ViewModelProvider; 12import androidx.recyclerview.widget.RecyclerView; 13 14import com.bumptech.glide.Glide; 15import com.bumptech.glide.RequestManager; 16 17import org.tm.archive.R; 18import org.tm.archive.components.FullScreenDialogFragment; 19import org.tm.archive.conversation.colors.Colorizer; 20import org.tm.archive.conversation.colors.RecyclerViewColorizer; 21import org.tm.archive.conversation.ui.edit.EditMessageHistoryDialog; 22import org.tm.archive.database.model.MessageRecord; 23import org.tm.archive.giph.mp4.GiphyMp4PlaybackController; 24import org.tm.archive.giph.mp4.GiphyMp4ProjectionPlayerHolder; 25import org.tm.archive.giph.mp4.GiphyMp4ProjectionRecycler; 26import org.tm.archive.messagedetails.MessageDetailsAdapter.MessageDetailsViewState; 27import org.tm.archive.messagedetails.MessageDetailsViewModel.Factory; 28import org.tm.archive.recipients.RecipientId; 29import org.tm.archive.safety.SafetyNumberBottomSheet; 30import org.tm.archive.util.Material3OnScrollHelper; 31import org.tm.archive.util.MessageRecordUtil; 32 33import java.util.ArrayList; 34import java.util.Collection; 35import java.util.List; 36 37public final class MessageDetailsFragment extends FullScreenDialogFragment implements MessageDetailsAdapter.Callbacks { 38 39 private static final String MESSAGE_ID_EXTRA = "message_id"; 40 private static final String RECIPIENT_EXTRA = "recipient_id"; 41 42 private RequestManager requestManager; 43 private MessageDetailsViewModel viewModel; 44 private MessageDetailsAdapter adapter; 45 private Colorizer colorizer; 46 private RecyclerViewColorizer recyclerViewColorizer; 47 48 public static @NonNull DialogFragment create(@NonNull MessageRecord message, @NonNull RecipientId recipientId) { 49 DialogFragment dialogFragment = new MessageDetailsFragment(); 50 Bundle args = new Bundle(); 51 52 args.putLong(MESSAGE_ID_EXTRA, message.getId()); 53 args.putParcelable(RECIPIENT_EXTRA, recipientId); 54 55 dialogFragment.setArguments(args); 56 57 return dialogFragment; 58 } 59 60 @Override 61 protected int getTitle() { 62 return R.string.AndroidManifest__message_details; 63 } 64 65 @Override 66 protected int getDialogLayoutResource() { 67 return R.layout.message_details_fragment; 68 } 69 70 @Override 71 public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 72 requestManager = Glide.with(this); 73 74 initializeList(view); 75 initializeViewModel(); 76 initializeVideoPlayer(view); 77 } 78 79 @Override 80 public void onDismiss(@NonNull DialogInterface dialog) { 81 super.onDismiss(dialog); 82 83 if (getActivity() instanceof Callback) { 84 ((Callback) getActivity()).onMessageDetailsFragmentDismissed(); 85 } else if (getParentFragment() instanceof Callback) { 86 ((Callback) getParentFragment()).onMessageDetailsFragmentDismissed(); 87 } 88 } 89 90 private void initializeList(@NonNull View view) { 91 RecyclerView list = view.findViewById(R.id.message_details_list); 92 View toolbarShadow = view.findViewById(R.id.toolbar_shadow); 93 94 colorizer = new Colorizer(); 95 adapter = new MessageDetailsAdapter(getViewLifecycleOwner(), requestManager, colorizer, this); 96 recyclerViewColorizer = new RecyclerViewColorizer(list); 97 98 list.setAdapter(adapter); 99 list.setItemAnimator(null); 100 new Material3OnScrollHelper(requireActivity(), toolbarShadow, getViewLifecycleOwner()).attach(list); 101 } 102 103 private void initializeViewModel() { 104 final RecipientId recipientId = requireArguments().getParcelable(RECIPIENT_EXTRA); 105 final Long messageId = requireArguments().getLong(MESSAGE_ID_EXTRA, -1); 106 final Factory factory = new Factory(recipientId, messageId); 107 108 viewModel = new ViewModelProvider(this, factory).get(MessageDetailsViewModel.class); 109 viewModel.getMessageDetails().observe(this, details -> { 110 if (details == null) { 111 dismissAllowingStateLoss(); 112 } else { 113 adapter.submitList(convertToRows(details)); 114 } 115 }); 116 viewModel.getRecipient().observe(this, recipient -> recyclerViewColorizer.setChatColors(recipient.getChatColors())); 117 } 118 119 private void initializeVideoPlayer(@NonNull View view) { 120 FrameLayout videoContainer = view.findViewById(R.id.video_container); 121 RecyclerView recyclerView = view.findViewById(R.id.message_details_list); 122 List<GiphyMp4ProjectionPlayerHolder> holders = GiphyMp4ProjectionPlayerHolder.injectVideoViews(requireContext(), getLifecycle(), videoContainer, 1); 123 GiphyMp4ProjectionRecycler callback = new GiphyMp4ProjectionRecycler(holders); 124 125 GiphyMp4PlaybackController.attach(recyclerView, callback, 1); 126 } 127 128 private List<MessageDetailsViewState<?>> convertToRows(MessageDetails details) { 129 List<MessageDetailsViewState<?>> list = new ArrayList<>(); 130 131 list.add(new MessageDetailsViewState<>(details.getConversationMessage(), MessageDetailsViewState.MESSAGE_HEADER)); 132 133 if (MessageRecordUtil.isEditMessage(details.getConversationMessage().getMessageRecord())) { 134 list.add(new MessageDetailsViewState<>(details.getConversationMessage().getMessageRecord(), MessageDetailsViewState.EDIT_HISTORY)); 135 } 136 137 if (details.getConversationMessage().getMessageRecord().isOutgoing()) { 138 addRecipients(list, RecipientHeader.NOT_SENT, details.getNotSent()); 139 addRecipients(list, RecipientHeader.VIEWED, details.getViewed()); 140 addRecipients(list, RecipientHeader.READ, details.getRead()); 141 addRecipients(list, RecipientHeader.DELIVERED, details.getDelivered()); 142 addRecipients(list, RecipientHeader.SENT_TO, details.getSent()); 143 addRecipients(list, RecipientHeader.PENDING, details.getPending()); 144 addRecipients(list, RecipientHeader.SKIPPED, details.getSkipped()); 145 } else { 146 addRecipients(list, RecipientHeader.SENT_FROM, details.getSent()); 147 } 148 149 return list; 150 } 151 152 private boolean addRecipients(List<MessageDetailsViewState<?>> list, RecipientHeader header, Collection<RecipientDeliveryStatus> recipients) { 153 if (recipients.isEmpty()) { 154 return false; 155 } 156 157 list.add(new MessageDetailsViewState<>(header, MessageDetailsViewState.RECIPIENT_HEADER)); 158 for (RecipientDeliveryStatus status : recipients) { 159 list.add(new MessageDetailsViewState<>(status, MessageDetailsViewState.RECIPIENT)); 160 } 161 return true; 162 } 163 164 @Override 165 public void onErrorClicked(@NonNull MessageRecord messageRecord) { 166 SafetyNumberBottomSheet 167 .forMessageRecord(requireContext(), messageRecord) 168 .show(getChildFragmentManager()); 169 } 170 171 @Override 172 public void onViewEditHistoryClicked(MessageRecord record) { 173 if (record.isOutgoing()) { 174 EditMessageHistoryDialog.show(getParentFragmentManager(), record.getToRecipient().getId(), record); 175 } else { 176 EditMessageHistoryDialog.show(getParentFragmentManager(), record.getFromRecipient().getId(), record); 177 } 178 } 179 180 @Override 181 public void onInternalDetailsClicked(MessageRecord record) { 182 InternalMessageDetailsFragment.create(record).show(getParentFragmentManager(), InternalMessageDetailsFragment.class.getSimpleName()); 183 } 184 185 public interface Callback { 186 void onMessageDetailsFragmentDismissed(); 187 } 188}