keep track of previously edited ids

This commit is contained in:
Daniel Gultsch 2018-12-01 15:52:44 +01:00
parent fdbed9cf58
commit f1e1c4a78d
6 changed files with 118 additions and 18 deletions

View File

@ -0,0 +1,80 @@
package eu.siacs.conversations.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<Edited> edits) throws JSONException {
JSONArray jsonArray = new JSONArray();
for (Edited edited : edits) {
jsonArray.put(edited.toJson());
}
return jsonArray.toString();
}
public static boolean wasPreviouslyEditedRemoteMsgId(List<Edited> editeds, String remoteMsgId) {
for (Edited edited : editeds) {
if (edited.editedId != null && edited.editedId.equals(remoteMsgId)) {
return true;
}
}
return false;
}
public static boolean wasPreviouslyEditedServerMsgId(List<Edited> 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<Edited> fromJson(String input) {
ArrayList<Edited> 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;
}
}

View File

@ -3,10 +3,14 @@ package eu.siacs.conversations.entities;
import android.content.ContentValues; import android.content.ContentValues;
import android.database.Cursor; import android.database.Cursor;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.util.Log;
import org.json.JSONException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
@ -86,7 +90,7 @@ public class Message extends AbstractEntity {
protected int type; protected int type;
protected boolean carbon = false; protected boolean carbon = false;
protected boolean oob = false; protected boolean oob = false;
protected String edited = null; protected List<Edited> edits = new ArrayList<>();
protected String relativeFilePath; protected String relativeFilePath;
protected boolean read = true; protected boolean read = true;
protected String remoteMsgId = null; protected String remoteMsgId = null;
@ -160,10 +164,10 @@ public class Message extends AbstractEntity {
this.serverMsgId = serverMsgId; this.serverMsgId = serverMsgId;
this.axolotlFingerprint = fingerprint; this.axolotlFingerprint = fingerprint;
this.read = read; this.read = read;
this.edited = edited; this.edits = Edited.fromJson(edited);
this.oob = oob; this.oob = oob;
this.errorMessage = errorMessage; this.errorMessage = errorMessage;
this.readByMarkers = readByMarkers == null ? new HashSet<ReadByMarker>() : readByMarkers; this.readByMarkers = readByMarkers == null ? new HashSet<>() : readByMarkers;
this.markable = markable; this.markable = markable;
} }
@ -256,7 +260,11 @@ public class Message extends AbstractEntity {
values.put(SERVER_MSG_ID, serverMsgId); values.put(SERVER_MSG_ID, serverMsgId);
values.put(FINGERPRINT, axolotlFingerprint); values.put(FINGERPRINT, axolotlFingerprint);
values.put(READ, read ? 1 : 0); values.put(READ, read ? 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(OOB, oob ? 1 : 0);
values.put(ERROR_MESSAGE, errorMessage); values.put(ERROR_MESSAGE, errorMessage);
values.put(READ_BY_MARKERS, ReadByMarker.toJson(readByMarkers).toString()); values.put(READ_BY_MARKERS, ReadByMarker.toJson(readByMarkers).toString());
@ -413,12 +421,12 @@ public class Message extends AbstractEntity {
this.carbon = carbon; this.carbon = carbon;
} }
public void setEdited(String edited) { public void putEdited(String edited, String serverMsgId) {
this.edited = edited; this.edits.add(new Edited(edited, serverMsgId));
} }
public boolean edited() { public boolean edited() {
return this.edited != null; return this.edits.size() > 0;
} }
public void setTrueCounterpart(Jid trueCounterpart) { public void setTrueCounterpart(Jid trueCounterpart) {
@ -470,7 +478,9 @@ public class Message extends AbstractEntity {
public boolean similar(Message message) { public boolean similar(Message message) {
if (type != TYPE_PRIVATE && this.serverMsgId != null && message.getServerMsgId() != null) { if (type != TYPE_PRIVATE && 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) { } else if (this.body == null || this.counterpart == null) {
return false; return false;
} else { } else {
@ -485,7 +495,7 @@ public class Message extends AbstractEntity {
final boolean matchingCounterpart = this.counterpart.equals(message.getCounterpart()); final boolean matchingCounterpart = this.counterpart.equals(message.getCounterpart());
if (message.getRemoteMsgId() != null) { if (message.getRemoteMsgId() != null) {
final boolean hasUuid = CryptoHelper.UUID_PATTERN.matcher(message.getRemoteMsgId()).matches(); 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 true;
} }
return (message.getRemoteMsgId().equals(this.remoteMsgId) || message.getRemoteMsgId().equals(this.uuid)) return (message.getRemoteMsgId().equals(this.remoteMsgId) || message.getRemoteMsgId().equals(this.uuid))
@ -686,7 +696,11 @@ public class Message extends AbstractEntity {
} }
public String getEditedId() { 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) { public void setOob(boolean isOob) {

View File

@ -518,7 +518,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
final String uuid = replacedMessage.getUuid(); final String uuid = replacedMessage.getUuid();
replacedMessage.setUuid(UUID.randomUUID().toString()); replacedMessage.setUuid(UUID.randomUUID().toString());
replacedMessage.setBody(message.getBody()); replacedMessage.setBody(message.getBody());
replacedMessage.setEdited(replacedMessage.getRemoteMsgId()); replacedMessage.putEdited(replacedMessage.getRemoteMsgId(), replacedMessage.getServerMsgId());
replacedMessage.setRemoteMsgId(remoteMsgId); replacedMessage.setRemoteMsgId(remoteMsgId);
if (replacedMessage.getServerMsgId() == null || message.getServerMsgId() != null) { if (replacedMessage.getServerMsgId() == null || message.getServerMsgId() != null) {
replacedMessage.setServerMsgId(message.getServerMsgId()); replacedMessage.setServerMsgId(message.getServerMsgId());

View File

@ -902,11 +902,10 @@ public class DatabaseBackend extends SQLiteOpenHelper {
return db.update(Message.TABLENAME, message.getContentValues(), Message.UUID + "=?", args) == 1; return db.update(Message.TABLENAME, message.getContentValues(), Message.UUID + "=?", args) == 1;
} }
public void updateMessage(Message message, String uuid) { public boolean updateMessage(Message message, String uuid) {
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
String[] args = {uuid}; String[] args = {uuid};
db.update(Message.TABLENAME, message.getContentValues(), Message.UUID return db.update(Message.TABLENAME, message.getContentValues(), Message.UUID + "=?", args) == 1;
+ "=?", args);
} }
public void readRoster(Roster roster) { public void readRoster(Roster roster) {

View File

@ -1316,7 +1316,9 @@ public class XmppConnectionService extends Service {
if (message.edited()) { if (message.edited()) {
message.setBody(decryptedBody); message.setBody(decryptedBody);
message.setEncryption(Message.ENCRYPTION_DECRYPTED); 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(); updateConversationUi();
return; return;
} else { } else {
@ -1354,7 +1356,9 @@ public class XmppConnectionService extends Service {
if (saveInDb) { if (saveInDb) {
databaseBackend.createMessage(message); databaseBackend.createMessage(message);
} else if (message.edited()) { } else if (message.edited()) {
databaseBackend.updateMessage(message, message.getEditedId()); if (!databaseBackend.updateMessage(message, message.getEditedId())) {
Log.e(Config.LOGTAG,"error updated message in DB after edit");
}
} }
updateConversationUi(); updateConversationUi();
} }
@ -2825,7 +2829,9 @@ public class XmppConnectionService extends Service {
} }
public void updateMessage(Message message, String uuid) { 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(); updateConversationUi();
} }

View File

@ -746,7 +746,8 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
} else { } else {
message = conversation.getCorrectingMessage(); message = conversation.getCorrectingMessage();
message.setBody(body); message.setBody(body);
message.setEdited(message.getUuid()); message.putEdited(message.getUuid(), message.getServerMsgId());
message.setServerMsgId(null);
message.setUuid(UUID.randomUUID().toString()); message.setUuid(UUID.randomUUID().toString());
} }
switch (conversation.getNextEncryption()) { switch (conversation.getNextEncryption()) {