From eb34cdc3e350a50ce98959bbf05f83813a6c2e12 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Fri, 13 Sep 2019 21:38:18 +0200 Subject: keep track of previously edited ids --- .../java/de/pixart/messenger/entities/Edited.java | 80 ++++++++++++++++++++++ .../java/de/pixart/messenger/entities/Message.java | 36 ++++++---- .../de/pixart/messenger/parser/MessageParser.java | 2 +- .../messenger/persistance/DatabaseBackend.java | 3 - .../messenger/services/XmppConnectionService.java | 8 ++- .../pixart/messenger/ui/ConversationFragment.java | 6 +- 6 files changed, 114 insertions(+), 21 deletions(-) create mode 100644 src/main/java/de/pixart/messenger/entities/Edited.java (limited to 'src/main') diff --git a/src/main/java/de/pixart/messenger/entities/Edited.java b/src/main/java/de/pixart/messenger/entities/Edited.java new file mode 100644 index 000000000..a992e6c97 --- /dev/null +++ b/src/main/java/de/pixart/messenger/entities/Edited.java @@ -0,0 +1,80 @@ +package de.pixart.messenger.entities; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +public class Edited { + + private final String editedId; + private final String serverMsgId; + + public Edited(String editedId, String serverMsgId) { + this.editedId = editedId; + this.serverMsgId = serverMsgId; + } + + public static String toJson(List edits) throws JSONException { + JSONArray jsonArray = new JSONArray(); + for (Edited edited : edits) { + jsonArray.put(edited.toJson()); + } + return jsonArray.toString(); + } + + public static boolean wasPreviouslyEditedRemoteMsgId(List editeds, String remoteMsgId) { + for (Edited edited : editeds) { + if (edited.editedId != null && edited.editedId.equals(remoteMsgId)) { + return true; + } + } + return false; + } + + public static boolean wasPreviouslyEditedServerMsgId(List editeds, String serverMsgId) { + for (Edited edited : editeds) { + if (edited.serverMsgId != null && edited.serverMsgId.equals(serverMsgId)) { + return true; + } + } + return false; + } + + public static Edited fromJson(JSONObject jsonObject) throws JSONException { + String edited = jsonObject.getString("edited_id"); + String serverMsgId = jsonObject.getString("server_msg_id"); + return new Edited(edited, serverMsgId); + } + + public static List fromJson(String input) { + ArrayList list = new ArrayList<>(); + if (input == null) { + return list; + } + try { + JSONArray jsonArray = new JSONArray(input); + for (int i = 0; i < jsonArray.length(); ++i) { + list.add(fromJson(jsonArray.getJSONObject(i))); + } + + } catch (JSONException e) { + list = new ArrayList<>(); + list.add(new Edited(input, null)); + } + return list; + } + + public JSONObject toJson() throws JSONException { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("edited_id", editedId); + jsonObject.put("server_msg_id", serverMsgId); + return jsonObject; + } + + public String getEditedId() { + return editedId; + } +} \ No newline at end of file diff --git a/src/main/java/de/pixart/messenger/entities/Message.java b/src/main/java/de/pixart/messenger/entities/Message.java index 0010222d8..59047550b 100644 --- a/src/main/java/de/pixart/messenger/entities/Message.java +++ b/src/main/java/de/pixart/messenger/entities/Message.java @@ -5,22 +5,22 @@ import android.database.Cursor; import android.graphics.Color; import android.text.SpannableStringBuilder; import android.util.Log; -import android.webkit.URLUtil; + +import org.json.JSONException; import java.lang.ref.WeakReference; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; -import java.util.regex.Pattern; import de.pixart.messenger.Config; import de.pixart.messenger.crypto.axolotl.FingerprintStatus; import de.pixart.messenger.services.AvatarService; -import de.pixart.messenger.ui.util.MyLinkify; import de.pixart.messenger.utils.CryptoHelper; import de.pixart.messenger.utils.Emoticons; import de.pixart.messenger.utils.GeoHelper; @@ -98,7 +98,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable protected boolean file_deleted = false; protected boolean carbon = false; protected boolean oob = false; - protected String edited = null; + protected List edits = new ArrayList<>(); protected String relativeFilePath; protected boolean read = true; protected boolean deleted = false; @@ -180,10 +180,10 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable this.axolotlFingerprint = fingerprint; this.read = read; this.deleted = deleted; - this.edited = edited; + this.edits = Edited.fromJson(edited); this.oob = oob; this.errorMessage = errorMessage; - this.readByMarkers = readByMarkers == null ? new HashSet() : readByMarkers; + this.readByMarkers = readByMarkers == null ? new HashSet<>() : readByMarkers; this.markable = markable; this.file_deleted = file_deleted; this.bodyLanguage = bodyLanguage; @@ -270,7 +270,11 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable values.put(FINGERPRINT, axolotlFingerprint); values.put(READ, read ? 1 : 0); values.put(DELETED, deleted ? 1 : 0); - values.put(EDITED, edited); + try { + values.put(EDITED, Edited.toJson(edits)); + } catch (JSONException e) { + Log.e(Config.LOGTAG, "error persisting json for edits", e); + } values.put(OOB, oob ? 1 : 0); values.put(ERROR_MESSAGE, errorMessage); values.put(READ_BY_MARKERS, ReadByMarker.toJson(readByMarkers).toString()); @@ -443,8 +447,8 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable this.carbon = carbon; } - public void setEdited(String edited) { - this.edited = edited; + public void putEdited(String edited, String serverMsgId) { + this.edits.add(new Edited(edited, serverMsgId)); } public String getBodyLanguage() { @@ -456,7 +460,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable } public boolean edited() { - return this.edited != null; + return this.edits.size() > 0; } public void setTrueCounterpart(Jid trueCounterpart) { @@ -510,7 +514,9 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable boolean similar(Message message) { if (!isPrivateMessage() && this.serverMsgId != null && message.getServerMsgId() != null) { - return this.serverMsgId.equals(message.getServerMsgId()); + return this.serverMsgId.equals(message.getServerMsgId()) || Edited.wasPreviouslyEditedServerMsgId(edits, message.getServerMsgId()); + } else if (Edited.wasPreviouslyEditedServerMsgId(edits, message.getServerMsgId())) { + return true; } else if (this.body == null || this.counterpart == null) { return false; } else { @@ -525,7 +531,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable final boolean matchingCounterpart = this.counterpart.equals(message.getCounterpart()); if (message.getRemoteMsgId() != null) { final boolean hasUuid = CryptoHelper.UUID_PATTERN.matcher(message.getRemoteMsgId()).matches(); - if (hasUuid && this.edited != null && matchingCounterpart && this.edited.equals(message.getRemoteMsgId())) { + if (hasUuid && matchingCounterpart && Edited.wasPreviouslyEditedRemoteMsgId(edits, message.getRemoteMsgId())) { return true; } return (message.getRemoteMsgId().equals(this.remoteMsgId) || message.getRemoteMsgId().equals(this.uuid)) @@ -738,7 +744,11 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable } public String getEditedId() { - return edited; + if (edits.size() > 0) { + return edits.get(edits.size() - 1).getEditedId(); + } else { + throw new IllegalStateException("Attempting to store unedited message"); + } } public void setOob(boolean isOob) { diff --git a/src/main/java/de/pixart/messenger/parser/MessageParser.java b/src/main/java/de/pixart/messenger/parser/MessageParser.java index 8250bf3b8..cd747b2d1 100644 --- a/src/main/java/de/pixart/messenger/parser/MessageParser.java +++ b/src/main/java/de/pixart/messenger/parser/MessageParser.java @@ -671,7 +671,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece final String uuid = replacedMessage.getUuid(); replacedMessage.setUuid(UUID.randomUUID().toString()); replacedMessage.setBody(message.getBody()); - replacedMessage.setEdited(replacedMessage.getRemoteMsgId()); + replacedMessage.putEdited(replacedMessage.getRemoteMsgId(), replacedMessage.getServerMsgId()); replacedMessage.setRemoteMsgId(remoteMsgId); if (replacedMessage.getServerMsgId() == null || message.getServerMsgId() != null) { replacedMessage.setServerMsgId(message.getServerMsgId()); diff --git a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java index 549771a5f..44e78015f 100644 --- a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java +++ b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java @@ -28,14 +28,11 @@ import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.UUID; diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java index 58822c5ce..5e635fd4d 100644 --- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java +++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java @@ -1683,7 +1683,9 @@ public class XmppConnectionService extends Service { if (message.edited()) { message.setBody(decryptedBody); message.setEncryption(Message.ENCRYPTION_DECRYPTED); - databaseBackend.updateMessage(message, message.getEditedId()); + if (!databaseBackend.updateMessage(message, message.getEditedId())) { + Log.e(Config.LOGTAG, "error updated message in DB after edit"); + } updateConversationUi(); return; } else { @@ -3485,7 +3487,9 @@ public class XmppConnectionService extends Service { } public void updateMessage(Message message, String uuid) { - databaseBackend.updateMessage(message, uuid); + if (!databaseBackend.updateMessage(message, uuid)) { + Log.e(Config.LOGTAG, "error updated message in DB after edit"); + } updateConversationUi(); } diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java index 924585ea4..859ef132f 100644 --- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java +++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java @@ -873,7 +873,8 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } else { message = conversation.getCorrectingMessage(); message.setBody(body); - message.setEdited(message.getUuid()); + message.putEdited(message.getUuid(), message.getServerMsgId()); + message.setServerMsgId(null); message.setUuid(UUID.randomUUID().toString()); } switch (conversation.getNextEncryption()) { @@ -1886,7 +1887,8 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke this.conversation.setCorrectingMessage(finalMessage); Message deletedmessage = conversation.getCorrectingMessage(); deletedmessage.setBody(getString(R.string.message_deleted)); - deletedmessage.setEdited(deletedmessage.getUuid()); + deletedmessage.putEdited(deletedmessage.getUuid(), deletedmessage.getServerMsgId()); + deletedmessage.setServerMsgId(null); deletedmessage.setUuid(UUID.randomUUID().toString()); sendMessage(deletedmessage); activity.xmppConnectionService.deleteMessage(conversation, deletedmessage); -- cgit v1.2.3