rework message deletion

This commit is contained in:
Christian Schneppe 2019-11-04 21:05:49 +01:00
parent d66b0d010e
commit 1b9c48dbad
No known key found for this signature in database
GPG key ID: F30B8D686B44D87E
7 changed files with 87 additions and 67 deletions

View file

@ -141,7 +141,9 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
}
public void deleteMessage(Message message) {
this.messages.remove(message);
synchronized (this.messages) {
this.messages.remove(message);
}
}
public Message getFirstUnreadMessage() {

View file

@ -84,6 +84,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
public static final String FILE_DELETED = "file_deleted";
public static final String ME_COMMAND = "/me";
public static final String ERROR_MESSAGE_CANCELLED = "de.pixart.messenger.cancelled";
public static final String DELETED_MESSAGE_BODY = "de.pixart.messenger.message_deleted";
public boolean markable = false;
protected String conversationUuid;
@ -403,6 +404,10 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
return this.deleted;
}
public void setMessageDeleted(boolean deleted) {
this.deleted = deleted;
}
public boolean isFileDeleted() {
return this.file_deleted;
}
@ -622,6 +627,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
this.getCounterpart() != null &&
this.getCounterpart().equals(message.getCounterpart()) &&
this.edited() == message.edited() &&
!this.isMessageDeleted() == !message.isMessageDeleted() &&
(message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) &&
this.getBody().length() + message.getBody().length() <= Config.MAX_DISPLAY_MESSAGE_CHARS &&
!message.isGeoUri() &&

View file

@ -4697,12 +4697,12 @@ public class XmppConnectionService extends Service {
updateConversationUi();
}
public void deleteMessage(final Conversation conversation, Message message) {
public void deleteMessage(final Conversation conversation, final Message message) {
conversation.deleteMessage(message);
message.setMessageDeleted(true);
Runnable runnable = () -> {
databaseBackend.deleteMessageInConversation(message);
databaseBackend.updateConversation(conversation);
};
mDatabaseWriterExecutor.execute(runnable);
}

View file

@ -123,6 +123,7 @@ import de.pixart.messenger.xmpp.chatstate.ChatState;
import de.pixart.messenger.xmpp.jingle.JingleConnection;
import rocks.xmpp.addr.Jid;
import static de.pixart.messenger.entities.Message.DELETED_MESSAGE_BODY;
import static de.pixart.messenger.ui.SettingsActivity.WARN_UNENCRYPTED_CHAT;
import static de.pixart.messenger.ui.XmppActivity.EXTRA_ACCOUNT;
import static de.pixart.messenger.ui.XmppActivity.REQUEST_INVITE_TO_CONVERSATION;
@ -1876,11 +1877,10 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
}
private void deleteMessage(Message message) {
Message relevantForCorrection = message;
while (message.mergeable(message.next())) {
message = message.next();
}
final Conversation conversation = (Conversation) message.getConversation();
Message relevantForCorrection = message;
while (relevantForCorrection.mergeable(relevantForCorrection.next())) {
relevantForCorrection = relevantForCorrection.next();
}
@ -1888,8 +1888,8 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
builder.setNegativeButton(R.string.cancel, null);
builder.setTitle(R.string.delete_message_dialog);
builder.setMessage(R.string.delete_message_dialog_msg);
Message finalRelevantForCorrection = relevantForCorrection;
Message finalMessage = message;
final Message finalRelevantForCorrection = relevantForCorrection;
final Message finalMessage = message;
builder.setPositiveButton(R.string.confirm, (dialog, which) -> {
if (finalRelevantForCorrection.getType() == Message.TYPE_TEXT
&& !finalMessage.isGeoUri()
@ -1898,13 +1898,12 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
&& (((Conversation) finalMessage.getConversation()).getMucOptions().nonanonymous() || finalMessage.getConversation().getMode() == Conversation.MODE_SINGLE)) {
this.conversation.setCorrectingMessage(finalMessage);
Message deletedmessage = conversation.getCorrectingMessage();
deletedmessage.setBody(getString(R.string.message_deleted));
deletedmessage.setBody(DELETED_MESSAGE_BODY);
deletedmessage.putEdited(deletedmessage.getUuid(), deletedmessage.getServerMsgId());
deletedmessage.setServerMsgId(null);
deletedmessage.setUuid(UUID.randomUUID().toString());
sendMessage(deletedmessage);
activity.xmppConnectionService.deleteMessage(conversation, deletedmessage);
refresh();
}
activity.xmppConnectionService.deleteMessage(conversation, finalMessage);
activity.onConversationsListItemUpdated();

View file

@ -29,6 +29,7 @@ import de.pixart.messenger.utils.UIHelper;
import de.pixart.messenger.xmpp.chatstate.ChatState;
import rocks.xmpp.addr.Jid;
import static de.pixart.messenger.entities.Message.DELETED_MESSAGE_BODY;
import static de.pixart.messenger.ui.util.MyLinkify.replaceYoutube;
public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapter.ConversationViewHolder> {
@ -149,7 +150,11 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
}
final Pair<CharSequence, Boolean> preview = UIHelper.getMessagePreview(activity, message, viewHolder.binding.conversationLastmsg.getCurrentTextColor());
if (showPreviewText) {
viewHolder.binding.conversationLastmsg.setText(EmojiWrapper.transform(UIHelper.shorten(replaceYoutube(activity.getApplicationContext(), preview.first.toString()))));
if (message.getBody().equals(DELETED_MESSAGE_BODY)) {
viewHolder.binding.conversationLastmsg.setText(EmojiWrapper.transform(UIHelper.shorten(activity.getString(R.string.message_deleted))));
} else {
viewHolder.binding.conversationLastmsg.setText(EmojiWrapper.transform(UIHelper.shorten(replaceYoutube(activity.getApplicationContext(), preview.first.toString()))));
}
} else {
viewHolder.binding.conversationLastmsgImg.setContentDescription(preview.first);
}

View file

@ -87,6 +87,7 @@ import pl.droidsonroids.gif.GifImageView;
import rocks.xmpp.addr.Jid;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static de.pixart.messenger.entities.Message.DELETED_MESSAGE_BODY;
import static de.pixart.messenger.ui.SettingsActivity.PLAY_GIF_INSIDE;
import static de.pixart.messenger.ui.SettingsActivity.SHOW_LINKS_INSIDE;
import static de.pixart.messenger.ui.SettingsActivity.SHOW_MAPS_INSIDE;
@ -539,67 +540,71 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
if (message.getBody() != null) {
final String nick = UIHelper.getMessageDisplayName(message);
SpannableStringBuilder body = new SpannableStringBuilder(replaceYoutube(activity.getApplicationContext(), message.getMergedBody().toString()));
boolean hasMeCommand = message.hasMeCommand();
if (hasMeCommand) {
body = body.replace(0, Message.ME_COMMAND.length(), nick);
}
if (body.length() > Config.MAX_DISPLAY_MESSAGE_CHARS) {
body = new SpannableStringBuilder(body, 0, Config.MAX_DISPLAY_MESSAGE_CHARS);
body.append("\u2026");
}
Message.MergeSeparator[] mergeSeparators = body.getSpans(0, body.length(), Message.MergeSeparator.class);
for (Message.MergeSeparator mergeSeparator : mergeSeparators) {
int start = body.getSpanStart(mergeSeparator);
int end = body.getSpanEnd(mergeSeparator);
body.setSpan(new DividerSpan(true), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
boolean startsWithQuote = handleTextQuotes(body, darkBackground);
if (!message.isPrivateMessage()) {
if (hasMeCommand) {
body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (message.getBody().equals(DELETED_MESSAGE_BODY)) {
body = body.replace(0, DELETED_MESSAGE_BODY.length(), activity.getString(R.string.message_deleted));
} else {
String privateMarker;
if (message.getStatus() <= Message.STATUS_RECEIVED) {
privateMarker = activity.getString(R.string.private_message);
} else {
Jid cp = message.getCounterpart();
privateMarker = activity.getString(R.string.private_message_to, Strings.nullToEmpty(cp == null ? null : cp.getResource()));
}
body.insert(0, privateMarker);
int privateMarkerIndex = privateMarker.length();
if (startsWithQuote) {
body.insert(privateMarkerIndex, "\n\n");
body.setSpan(new DividerSpan(false), privateMarkerIndex, privateMarkerIndex + 2,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
body.insert(privateMarkerIndex, " ");
}
body.setSpan(new ForegroundColorSpan(getMessageTextColor(darkBackground, false)), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
body.setSpan(new StyleSpan(Typeface.BOLD), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
boolean hasMeCommand = message.hasMeCommand();
if (hasMeCommand) {
body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarkerIndex + 1, privateMarkerIndex + 1 + nick.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
body = body.replace(0, Message.ME_COMMAND.length(), nick);
}
}
if (message.getConversation().getMode() == Conversation.MODE_MULTI && message.getStatus() == Message.STATUS_RECEIVED) {
if (message.getConversation() instanceof Conversation) {
final Conversation conversation = (Conversation) message.getConversation();
Pattern pattern = NotificationService.generateNickHighlightPattern(conversation.getMucOptions().getActualNick());
Matcher matcher = pattern.matcher(body);
while (matcher.find()) {
body.setSpan(new StyleSpan(Typeface.BOLD), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
if (body.length() > Config.MAX_DISPLAY_MESSAGE_CHARS) {
body = new SpannableStringBuilder(body, 0, Config.MAX_DISPLAY_MESSAGE_CHARS);
body.append("\u2026");
}
Message.MergeSeparator[] mergeSeparators = body.getSpans(0, body.length(), Message.MergeSeparator.class);
for (Message.MergeSeparator mergeSeparator : mergeSeparators) {
int start = body.getSpanStart(mergeSeparator);
int end = body.getSpanEnd(mergeSeparator);
body.setSpan(new DividerSpan(true), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
boolean startsWithQuote = handleTextQuotes(body, darkBackground);
if (!message.isPrivateMessage()) {
if (hasMeCommand) {
body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
} else {
String privateMarker;
if (message.getStatus() <= Message.STATUS_RECEIVED) {
privateMarker = activity.getString(R.string.private_message);
} else {
Jid cp = message.getCounterpart();
privateMarker = activity.getString(R.string.private_message_to, Strings.nullToEmpty(cp == null ? null : cp.getResource()));
}
body.insert(0, privateMarker);
int privateMarkerIndex = privateMarker.length();
if (startsWithQuote) {
body.insert(privateMarkerIndex, "\n\n");
body.setSpan(new DividerSpan(false), privateMarkerIndex, privateMarkerIndex + 2,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
body.insert(privateMarkerIndex, " ");
}
body.setSpan(new ForegroundColorSpan(getMessageTextColor(darkBackground, false)), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
body.setSpan(new StyleSpan(Typeface.BOLD), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
if (hasMeCommand) {
body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarkerIndex + 1, privateMarkerIndex + 1 + nick.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
Matcher matcher = Emoticons.getEmojiPattern(body).matcher(body);
while (matcher.find()) {
if (matcher.start() < matcher.end()) {
body.setSpan(new RelativeSizeSpan(1.5f), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
if (message.getConversation().getMode() == Conversation.MODE_MULTI && message.getStatus() == Message.STATUS_RECEIVED) {
if (message.getConversation() instanceof Conversation) {
final Conversation conversation = (Conversation) message.getConversation();
Pattern pattern = NotificationService.generateNickHighlightPattern(conversation.getMucOptions().getActualNick());
Matcher matcher = pattern.matcher(body);
while (matcher.find()) {
body.setSpan(new StyleSpan(Typeface.BOLD), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
Matcher matcher = Emoticons.getEmojiPattern(body).matcher(body);
while (matcher.find()) {
if (matcher.start() < matcher.end()) {
body.setSpan(new RelativeSizeSpan(1.5f), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
StylingHelper.format(body, viewHolder.messageBody.getCurrentTextColor());
if (highlightedTerm != null) {
StylingHelper.highlight(activity, body, highlightedTerm, StylingHelper.isDarkText(viewHolder.messageBody));
}
}
StylingHelper.format(body, viewHolder.messageBody.getCurrentTextColor());
if (highlightedTerm != null) {
StylingHelper.highlight(activity, body, highlightedTerm, StylingHelper.isDarkText(viewHolder.messageBody));
}
MyLinkify.addLinks(body, true);
viewHolder.messageBody.setAutoLinkMask(0);
@ -607,7 +612,6 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
viewHolder.messageBody.setTextIsSelectable(true);
viewHolder.messageBody.setMovementMethod(ClickableMovementMethod.getInstance());
listSelectionManager.onUpdate(viewHolder.messageBody, message);
} else {
viewHolder.messageBody.setText("");
viewHolder.messageBody.setTextIsSelectable(false);

View file

@ -31,6 +31,8 @@ import de.pixart.messenger.entities.Transferable;
import de.pixart.messenger.services.ExportBackupService;
import rocks.xmpp.addr.Jid;
import static de.pixart.messenger.entities.Message.DELETED_MESSAGE_BODY;
public class UIHelper {
private static int[] UNSAFE_COLORS = {
@ -297,7 +299,9 @@ public class UIHelper {
return new Pair<>(getFileDescriptionString(context, message), true);
} else {
final String body = MessageUtils.filterLtrRtl(message.getBody());
if (body.startsWith(Message.ME_COMMAND)) {
if (message.getBody().equals(DELETED_MESSAGE_BODY)) {
return new Pair<>(context.getString(R.string.message_deleted), false);
} else if (body.startsWith(Message.ME_COMMAND)) {
return new Pair<>(body.replaceAll("^" + Message.ME_COMMAND, UIHelper.getMessageDisplayName(message)), false);
} else if (message.isGeoUri()) {
return new Pair<>(context.getString(R.string.location), true);