From 1b9c48dbad8ec534fabea3c5b75b2cddb9d00a46 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Mon, 4 Nov 2019 21:05:49 +0100 Subject: rework message deletion --- .../de/pixart/messenger/entities/Conversation.java | 4 +- .../java/de/pixart/messenger/entities/Message.java | 6 ++ .../messenger/services/XmppConnectionService.java | 4 +- .../pixart/messenger/ui/ConversationFragment.java | 11 +-- .../messenger/ui/adapter/ConversationAdapter.java | 7 +- .../messenger/ui/adapter/MessageAdapter.java | 110 +++++++++++---------- .../java/de/pixart/messenger/utils/UIHelper.java | 6 +- 7 files changed, 84 insertions(+), 64 deletions(-) (limited to 'src/main/java/de/pixart') diff --git a/src/main/java/de/pixart/messenger/entities/Conversation.java b/src/main/java/de/pixart/messenger/entities/Conversation.java index cc0d5525f..2233e22ac 100644 --- a/src/main/java/de/pixart/messenger/entities/Conversation.java +++ b/src/main/java/de/pixart/messenger/entities/Conversation.java @@ -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() { diff --git a/src/main/java/de/pixart/messenger/entities/Message.java b/src/main/java/de/pixart/messenger/entities/Message.java index c0e6fb8cb..dbcc05ab1 100644 --- a/src/main/java/de/pixart/messenger/entities/Message.java +++ b/src/main/java/de/pixart/messenger/entities/Message.java @@ -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() && diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java index 5de4c79b9..e8ade33de 100644 --- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java +++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java @@ -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); } diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java index 7c6aa0967..362bd4495 100644 --- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java +++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java @@ -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(); diff --git a/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java index 62bc711b2..14220345b 100644 --- a/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java +++ b/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java @@ -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 { @@ -149,7 +150,11 @@ public class ConversationAdapter extends RecyclerView.Adapter 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); } diff --git a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java index d11a2af0f..dffbd6a6f 100644 --- a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java +++ b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java @@ -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,75 +540,78 @@ public class MessageAdapter extends ArrayAdapter 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 (message.getBody().equals(DELETED_MESSAGE_BODY)) { + body = body.replace(0, DELETED_MESSAGE_BODY.length(), activity.getString(R.string.message_deleted)); + } else { + boolean hasMeCommand = message.hasMeCommand(); if (hasMeCommand) { - body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + body = body.replace(0, Message.ME_COMMAND.length(), nick); } - } 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())); + 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); } - 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); + 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 { - body.insert(privateMarkerIndex, " "); + 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); + } } - 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); + 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 (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); } } - } - 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); viewHolder.messageBody.setText(EmojiWrapper.transform(body)); viewHolder.messageBody.setTextIsSelectable(true); viewHolder.messageBody.setMovementMethod(ClickableMovementMethod.getInstance()); listSelectionManager.onUpdate(viewHolder.messageBody, message); - } else { viewHolder.messageBody.setText(""); viewHolder.messageBody.setTextIsSelectable(false); diff --git a/src/main/java/de/pixart/messenger/utils/UIHelper.java b/src/main/java/de/pixart/messenger/utils/UIHelper.java index e081ae6d6..f34952e1d 100644 --- a/src/main/java/de/pixart/messenger/utils/UIHelper.java +++ b/src/main/java/de/pixart/messenger/utils/UIHelper.java @@ -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); -- cgit v1.2.3