Add message editing feature.

This commit is contained in:
Clark
2023-04-14 16:29:26 -04:00
committed by Cody Henthorne
parent 4f06a0d27c
commit 07f6baf7c1
73 changed files with 2051 additions and 304 deletions

View File

@@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.conversation.ConversationMessage;
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.databinding.MessageDetailsViewEditHistoryBinding;
import org.thoughtcrime.securesms.mms.GlideRequests;
final class MessageDetailsAdapter extends ListAdapter<MessageDetailsAdapter.MessageDetailsViewState<?>, RecyclerView.ViewHolder> {
@@ -40,6 +41,8 @@ final class MessageDetailsAdapter extends ListAdapter<MessageDetailsAdapter.Mess
return new RecipientHeaderViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.message_details_recipient_header, parent, false));
case MessageDetailsViewState.RECIPIENT:
return new RecipientViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.message_details_recipient, parent, false), callbacks);
case MessageDetailsViewState.EDIT_HISTORY:
return new ViewEditHistoryViewHolder(MessageDetailsViewEditHistoryBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false), callbacks);
default:
throw new AssertionError("unknown view type");
}
@@ -53,6 +56,8 @@ final class MessageDetailsAdapter extends ListAdapter<MessageDetailsAdapter.Mess
((RecipientHeaderViewHolder) holder).bind((RecipientHeader) getItem(position).data);
} else if (holder instanceof RecipientViewHolder) {
((RecipientViewHolder) holder).bind((RecipientDeliveryStatus) getItem(position).data);
} else if (holder instanceof ViewEditHistoryViewHolder) {
((ViewEditHistoryViewHolder) holder).bind((MessageRecord) getItem(position).data);
} else {
throw new AssertionError("unknown view holder");
}
@@ -72,6 +77,7 @@ final class MessageDetailsAdapter extends ListAdapter<MessageDetailsAdapter.Mess
if (oldData.getClass() == newData.getClass() && oldItem.itemType == newItem.itemType) {
switch (oldItem.itemType) {
case MessageDetailsViewState.MESSAGE_HEADER:
case MessageDetailsViewState.EDIT_HISTORY:
return true;
case MessageDetailsViewState.RECIPIENT_HEADER:
return oldData == newData;
@@ -94,6 +100,7 @@ final class MessageDetailsAdapter extends ListAdapter<MessageDetailsAdapter.Mess
case MessageDetailsViewState.MESSAGE_HEADER:
return false;
case MessageDetailsViewState.RECIPIENT_HEADER:
case MessageDetailsViewState.EDIT_HISTORY:
return true;
case MessageDetailsViewState.RECIPIENT:
return ((RecipientDeliveryStatus) oldData).getDeliveryStatus() == ((RecipientDeliveryStatus) newData).getDeliveryStatus();
@@ -108,6 +115,7 @@ final class MessageDetailsAdapter extends ListAdapter<MessageDetailsAdapter.Mess
public static final int MESSAGE_HEADER = 0;
public static final int RECIPIENT_HEADER = 1;
public static final int RECIPIENT = 2;
public static final int EDIT_HISTORY = 3;
private final T data;
private int itemType;
@@ -120,5 +128,6 @@ final class MessageDetailsAdapter extends ListAdapter<MessageDetailsAdapter.Mess
interface Callbacks {
void onErrorClicked(@NonNull MessageRecord messageRecord);
void onViewEditHistoryClicked(MessageRecord record);
}
}

View File

@@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.FullScreenDialogFragment;
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
import org.thoughtcrime.securesms.conversation.colors.RecyclerViewColorizer;
import org.thoughtcrime.securesms.conversation.ui.edit.EditMessageHistoryDialog;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackController;
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4ProjectionPlayerHolder;
@@ -26,12 +27,13 @@ import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet;
import org.thoughtcrime.securesms.util.Material3OnScrollHelper;
import org.thoughtcrime.securesms.util.MessageRecordUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public final class MessageDetailsFragment extends FullScreenDialogFragment {
public final class MessageDetailsFragment extends FullScreenDialogFragment implements MessageDetailsAdapter.Callbacks {
private static final String MESSAGE_ID_EXTRA = "message_id";
private static final String RECIPIENT_EXTRA = "recipient_id";
@@ -89,7 +91,7 @@ public final class MessageDetailsFragment extends FullScreenDialogFragment {
View toolbarShadow = view.findViewById(R.id.toolbar_shadow);
colorizer = new Colorizer();
adapter = new MessageDetailsAdapter(getViewLifecycleOwner(), glideRequests, colorizer, this::onErrorClicked);
adapter = new MessageDetailsAdapter(getViewLifecycleOwner(), glideRequests, colorizer, this);
recyclerViewColorizer = new RecyclerViewColorizer(list);
list.setAdapter(adapter);
@@ -127,6 +129,10 @@ public final class MessageDetailsFragment extends FullScreenDialogFragment {
list.add(new MessageDetailsViewState<>(details.getConversationMessage(), MessageDetailsViewState.MESSAGE_HEADER));
if (MessageRecordUtil.isEditMessage(details.getConversationMessage().getMessageRecord())) {
list.add(new MessageDetailsViewState<>(details.getConversationMessage().getMessageRecord(), MessageDetailsViewState.EDIT_HISTORY));
}
if (details.getConversationMessage().getMessageRecord().isOutgoing()) {
addRecipients(list, RecipientHeader.NOT_SENT, details.getNotSent());
addRecipients(list, RecipientHeader.VIEWED, details.getViewed());
@@ -154,12 +160,22 @@ public final class MessageDetailsFragment extends FullScreenDialogFragment {
return true;
}
private void onErrorClicked(@NonNull MessageRecord messageRecord) {
@Override
public void onErrorClicked(@NonNull MessageRecord messageRecord) {
SafetyNumberBottomSheet
.forMessageRecord(requireContext(), messageRecord)
.show(getChildFragmentManager());
}
@Override
public void onViewEditHistoryClicked(MessageRecord record) {
if (record.isOutgoing()) {
EditMessageHistoryDialog.show(requireParentFragment().getChildFragmentManager(), record.getToRecipient().getId(), record.getId());
} else {
EditMessageHistoryDialog.show(requireParentFragment().getChildFragmentManager(), record.getFromRecipient().getId(), record.getId());
}
}
public interface Callback {
void onMessageDetailsFragmentDismissed();
}

View File

@@ -0,0 +1,23 @@
package org.thoughtcrime.securesms.messagedetails;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.databinding.MessageDetailsViewEditHistoryBinding;
public class ViewEditHistoryViewHolder extends RecyclerView.ViewHolder {
private final org.thoughtcrime.securesms.databinding.MessageDetailsViewEditHistoryBinding binding;
private final MessageDetailsAdapter.Callbacks callbacks;
public ViewEditHistoryViewHolder(@NonNull MessageDetailsViewEditHistoryBinding binding, @NonNull MessageDetailsAdapter.Callbacks callbacks) {
super(binding.getRoot());
this.binding = binding;
this.callbacks = callbacks;
}
public void bind(@NonNull MessageRecord record) {
binding.viewEditHistory.setOnClickListener(v -> callbacks.onViewEditHistoryClicked(record));
}
}