keep track of previously edited ids
This commit is contained in:
parent
fdbed9cf58
commit
f1e1c4a78d
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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) {
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
Loading…
Reference in New Issue