diff --git a/app/src/main/java/eu/faircode/email/AdapterMessage.java b/app/src/main/java/eu/faircode/email/AdapterMessage.java index 76e228051b..9657dd181f 100644 --- a/app/src/main/java/eu/faircode/email/AdapterMessage.java +++ b/app/src/main/java/eu/faircode/email/AdapterMessage.java @@ -1269,9 +1269,9 @@ public class AdapterMessage extends RecyclerView.Adapter= Build.VERSION_CODES.O); int maxRecipients = (compact ? MAX_RECIPIENTS_COMPACT : MAX_RECIPIENTS_NORMAL); Spanned submitter = formatAddresses(message.submitter, true); - Spanned from = formatAddresses(message.senders, true); + Spanned from = formatAddresses(message.addresses[0], true); grpAddresses.setVisibility(View.VISIBLE); @@ -7841,7 +7841,7 @@ public class AdapterMessage extends RecyclerView.Adapter result = new ArrayList<>(); try { JSONArray jroot = new JSONArray(json); - for (int i = 0; i < jroot.length(); i++) { - Object item = jroot.get(i); - if (jroot.get(i) instanceof JSONArray) - for (int j = 0; j < ((JSONArray) item).length(); j++) - result.add(InternetAddressJson.from((JSONObject) ((JSONArray) item).get(j))); - else - result.add(InternetAddressJson.from((JSONObject) item)); - } + for (int i = 0; i < jroot.length(); i++) + result.addAll(getAddresses(jroot.get(i))); } catch (Throwable ex) { // Compose can store invalid addresses Log.w(ex); @@ -3131,6 +3125,46 @@ public abstract class DB extends RoomDatabase { return result.toArray(new Address[0]); } + @TypeConverter + public static Address[][] decodeAddressesArray(String json) { + if (json == null) + return new Address[][]{new Address[0], new Address[0]}; + + List
senders = new ArrayList<>(); + List
recipients = new ArrayList<>(); + try { + JSONArray jroot = new JSONArray(json); + senders.addAll(getAddresses(jroot.get(0))); + recipients.addAll(getAddresses(jroot.get(1))); + } catch (Throwable ex) { + Log.w(ex); + } + return new Address[][]{ + senders.toArray(new Address[0]), + recipients.toArray(new Address[0]) + }; + } + + private static List
getAddresses(Object item) { + List
result = new ArrayList<>(); + if (item instanceof JSONArray) + for (int j = 0; j < ((JSONArray) item).length(); j++) + try { + result.add(InternetAddressJson.from((JSONObject) ((JSONArray) item).get(j))); + } catch (Throwable ex) { + // Compose can store invalid addresses + Log.w(ex); + } + else + try { + result.add(InternetAddressJson.from((JSONObject) item)); + } catch (Throwable ex) { + // Compose can store invalid addresses + Log.w(ex); + } + return result; + } + @TypeConverter public static EntityLog.Type toLogType(int ordinal) { return EntityLog.Type.values()[ordinal]; diff --git a/app/src/main/java/eu/faircode/email/DaoMessage.java b/app/src/main/java/eu/faircode/email/DaoMessage.java index ff7ebfff1b..defa6ad4cb 100644 --- a/app/src/main/java/eu/faircode/email/DaoMessage.java +++ b/app/src/main/java/eu/faircode/email/DaoMessage.java @@ -51,8 +51,7 @@ public interface DaoMessage { ", account.notify AS accountNotify, account.summary AS accountSummary, account.leave_deleted AS accountLeaveDeleted, account.auto_seen AS accountAutoSeen" + ", folder.name AS folderName, folder.color AS folderColor, folder.display AS folderDisplay, folder.type AS folderType, NULL AS folderInheritedType, folder.unified AS folderUnified, folder.read_only AS folderReadOnly" + ", IFNULL(identity.display, identity.name) AS identityName, identity.email AS identityEmail, identity.color AS identityColor, identity.synchronize AS identitySynchronize" + - ", '[' || (SELECT group_concat(`from`, ',') FROM (SELECT DISTINCT `from` FROM message m0 WHERE m0.account = message.account AND m0.thread = message.thread ORDER BY m0.received DESC LIMIT 3)) || ']' AS senders" + - ", '[' || (SELECT group_concat(`to`, ',') FROM (SELECT DISTINCT `to` FROM message m0 WHERE m0.account = message.account AND m0.thread = message.thread ORDER BY m0.received DESC LIMIT 3)) || ']' AS recipients" + + ", (SELECT '[' || group_concat(`from`, ',') || ',' || group_concat(`to`, ',') || ']' FROM (SELECT DISTINCT `from`, `to` FROM message m0 WHERE m0.account = message.account AND m0.thread = message.thread ORDER BY m0.received DESC LIMIT 3)) AS addresses" + ", COUNT(message.id) AS count" + ", SUM(1 - message.ui_seen) AS unseen" + ", SUM(1 - message.ui_flagged) AS unflagged" + @@ -77,7 +76,7 @@ public interface DaoMessage { " THEN message.received ELSE 0 END) AS dummy" + " FROM message" + - " JOIN message AS mm ON mm.thread = message.thread" + + " JOIN message AS mm ON mm.account = message.account AND mm.thread = message.thread" + " AND (NOT :found OR mm.ui_found) AND (NOT mm.ui_hide OR :debug)" + " JOIN folder AS ff ON ff.id = mm.folder" + " AND (:found OR (:type IS NULL AND ff.unified) OR (:type IS NOT NULL AND ff.type = :type))" + @@ -129,8 +128,7 @@ public interface DaoMessage { ", account.notify AS accountNotify, account.summary AS accountSummary, account.leave_deleted AS accountLeaveDeleted, account.auto_seen AS accountAutoSeen" + ", folder.name AS folderName, folder.color AS folderColor, folder.display AS folderDisplay, folder.type AS folderType, f.inherited_type AS folderInheritedType, folder.unified AS folderUnified, folder.read_only AS folderReadOnly" + ", IFNULL(identity.display, identity.name) AS identityName, identity.email AS identityEmail, identity.color AS identityColor, identity.synchronize AS identitySynchronize" + - ", '[' || (SELECT group_concat(`from`, ',') FROM (SELECT DISTINCT `from` FROM message m0 WHERE m0.account = message.account AND m0.thread = message.thread ORDER BY m0.received DESC LIMIT 3)) || ']' AS senders" + - ", '[' || (SELECT group_concat(`to`, ',') FROM (SELECT DISTINCT `to` FROM message m0 WHERE m0.account = message.account AND m0.thread = message.thread ORDER BY m0.received DESC LIMIT 3)) || ']' AS recipients" + + ", (SELECT '[' || group_concat(`from`, ',') || ',' || group_concat(`to`, ',') || ']' FROM (SELECT DISTINCT `from`, `to` FROM message m0 WHERE m0.account = message.account AND m0.thread = message.thread ORDER BY m0.received DESC LIMIT 3)) AS addresses" + ", COUNT(message.id) AS count" + ", SUM(1 - message.ui_seen) AS unseen" + ", SUM(1 - message.ui_flagged) AS unflagged" + @@ -154,7 +152,7 @@ public interface DaoMessage { " THEN message.received ELSE 0 END) AS dummy" + " FROM message" + - " JOIN message AS mm ON mm.thread = message.thread" + + " JOIN message AS mm ON mm.account = message.account AND mm.thread = message.thread" + " AND (NOT :found OR mm.ui_found) AND (NOT mm.ui_hide OR :debug)" + " AND message.folder = :folder" + @@ -200,8 +198,7 @@ public interface DaoMessage { ", account.notify AS accountNotify, account.summary AS accountSummary, account.leave_deleted AS accountLeaveDeleted, account.auto_seen AS accountAutoSeen" + ", folder.name AS folderName, folder.color AS folderColor, folder.display AS folderDisplay, folder.type AS folderType, NULL AS folderInheritedType, folder.unified AS folderUnified, folder.read_only AS folderReadOnly" + ", IFNULL(identity.display, identity.name) AS identityName, identity.email AS identityEmail, identity.color AS identityColor, identity.synchronize AS identitySynchronize" + - ", message.`from` AS senders" + - ", message.`to` AS recipients" + + ", ('[' || message.`from` || ',' || message.`to` || ']') AS addresses" + ", 1 AS count" + ", CASE WHEN message.ui_seen THEN 0 ELSE 1 END AS unseen" + ", CASE WHEN message.ui_flagged THEN 0 ELSE 1 END AS unflagged" + @@ -506,8 +503,7 @@ public interface DaoMessage { ", account.notify AS accountNotify, account.summary AS accountSummary, account.leave_deleted AS accountLeaveDeleted, account.auto_seen AS accountAutoSeen" + ", folder.name AS folderName, folder.color AS folderColor, folder.display AS folderDisplay, folder.type AS folderType, NULL AS folderInheritedType, folder.unified AS folderUnified, folder.read_only AS folderReadOnly" + ", IFNULL(identity.display, identity.name) AS identityName, identity.email AS identityEmail, identity.color AS identityColor, identity.synchronize AS identitySynchronize" + - ", message.`from` AS senders" + - ", message.`to` AS recipients" + + ", ('[' || message.`from` || ',' || message.`to` || ']') AS addresses" + ", 1 AS count" + ", CASE WHEN message.ui_seen THEN 0 ELSE 1 END AS unseen" + ", CASE WHEN message.ui_flagged THEN 0 ELSE 1 END AS unflagged" + @@ -537,8 +533,7 @@ public interface DaoMessage { ", account.notify AS accountNotify, account.summary AS accountSummary, account.leave_deleted AS accountLeaveDeleted, account.auto_seen AS accountAutoSeen" + ", folder.name AS folderName, folder.color AS folderColor, folder.display AS folderDisplay, folder.type AS folderType, NULL AS folderInheritedType, folder.unified AS folderUnified, folder.read_only AS folderReadOnly" + ", IFNULL(identity.display, identity.name) AS identityName, identity.email AS identityEmail, identity.color AS identityColor, identity.synchronize AS identitySynchronize" + - ", message.`from` AS senders" + - ", message.`to` AS recipients" + + ", ('[' || message.`from` || ',' || message.`to` || ']') AS addresses" + ", 1 AS count" + ", 1 AS unseen" + ", 0 AS unflagged" + diff --git a/app/src/main/java/eu/faircode/email/TupleMessageEx.java b/app/src/main/java/eu/faircode/email/TupleMessageEx.java index 5f033de044..040180e7d0 100644 --- a/app/src/main/java/eu/faircode/email/TupleMessageEx.java +++ b/app/src/main/java/eu/faircode/email/TupleMessageEx.java @@ -53,8 +53,7 @@ public class TupleMessageEx extends EntityMessage { public String identityEmail; public Integer identityColor; public Boolean identitySynchronize; - public Address[] senders; - public Address[] recipients; + public Address[][] addresses; public int count; public int unseen; public int unflagged; @@ -160,8 +159,8 @@ public class TupleMessageEx extends EntityMessage { Objects.equals(this.identityEmail, other.identityEmail) && Objects.equals(this.identityColor, other.identityColor) && Objects.equals(this.identitySynchronize, other.identitySynchronize) && - MessageHelper.equal(this.senders, other.senders) && - MessageHelper.equal(this.recipients, other.recipients) && + MessageHelper.equal(this.addresses[0], other.addresses[0]) && + MessageHelper.equal(this.addresses[1], other.addresses[1]) && this.count == other.count && this.unseen == other.unseen && this.unflagged == other.unflagged &&