Let search find threads

pull/146/head
M66B 6 years ago
parent 44c258d400
commit 3351a2efbe

File diff suppressed because it is too large Load Diff

@ -411,7 +411,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
if (archive == null) if (archive == null)
throw new IllegalArgumentException(getString(R.string.title_no_primary_archive)); throw new IllegalArgumentException(getString(R.string.title_no_primary_archive));
db.message().deleteFoundMessages(); db.message().resetSearch();
return archive.id; return archive.id;
} }
@ -1162,7 +1162,6 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
args.putLong("account", intent.getLongExtra("account", -1)); args.putLong("account", intent.getLongExtra("account", -1));
args.putString("thread", intent.getStringExtra("thread")); args.putString("thread", intent.getStringExtra("thread"));
args.putLong("id", intent.getLongExtra("id", -1)); args.putLong("id", intent.getLongExtra("id", -1));
args.putBoolean("found", intent.getBooleanExtra("found", false));
FragmentMessages fragment = new FragmentMessages(); FragmentMessages fragment = new FragmentMessages();
fragment.setArguments(args); fragment.setArguments(args);

@ -323,7 +323,7 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
try { try {
db.beginTransaction(); db.beginTransaction();
for (Long mid : db.message().getMessageByFolder(id, false)) { for (Long mid : db.message().getMessageByFolder(id)) {
EntityMessage message = db.message().getMessage(mid); EntityMessage message = db.message().getMessage(mid);
EntityOperation.queue(db, message, EntityOperation.DELETE); EntityOperation.queue(db, message, EntityOperation.DELETE);
} }

@ -594,8 +594,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
new Intent(ActivityView.ACTION_VIEW_THREAD) new Intent(ActivityView.ACTION_VIEW_THREAD)
.putExtra("account", message.account) .putExtra("account", message.account)
.putExtra("thread", message.thread) .putExtra("thread", message.thread)
.putExtra("id", message.id) .putExtra("id", message.id));
.putExtra("found", message.ui_found));
} }
} }
} }
@ -1165,7 +1164,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
EntityMessage message = db.message().getMessage(id); EntityMessage message = db.message().getMessage(id);
List<EntityMessage> messages = db.message().getMessageByThread( List<EntityMessage> messages = db.message().getMessageByThread(
message.account, message.thread, threading && thread ? null : id, message.folder, message.ui_found); message.account, message.thread, threading && thread ? null : id, message.folder);
for (EntityMessage threaded : messages) for (EntityMessage threaded : messages)
EntityOperation.queue(db, threaded, EntityOperation.FLAG, flagged); EntityOperation.queue(db, threaded, EntityOperation.FLAG, flagged);

@ -134,8 +134,7 @@ public class AdapterOperation extends RecyclerView.Adapter<AdapterOperation.View
new Intent(ActivityView.ACTION_VIEW_THREAD) new Intent(ActivityView.ACTION_VIEW_THREAD)
.putExtra("account", message.account) .putExtra("account", message.account)
.putExtra("thread", message.thread) .putExtra("thread", message.thread)
.putExtra("id", message.id) .putExtra("id", message.id));
.putExtra("found", message.ui_found));
} }
}.load(context, owner, args); }.load(context, owner, args);
} }

@ -46,7 +46,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
// https://developer.android.com/topic/libraries/architecture/room.html // https://developer.android.com/topic/libraries/architecture/room.html
@Database( @Database(
version = 16, version = 17,
entities = { entities = {
EntityIdentity.class, EntityIdentity.class,
EntityAccount.class, EntityAccount.class,
@ -144,7 +144,7 @@ public abstract class DB extends RoomDatabase {
Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion); Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `message` ADD COLUMN `forwarding` INTEGER" + db.execSQL("ALTER TABLE `message` ADD COLUMN `forwarding` INTEGER" +
" REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL"); " REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL");
db.execSQL("CREATE INDEX `index_message_forwarding` ON `message` (`forwarding`)"); db.execSQL("CREATE INDEX `index_message_forwarding` ON `message` (`forwarding`)");
} }
}) })
.addMigrations(new Migration(4, 5) { .addMigrations(new Migration(4, 5) {
@ -189,7 +189,7 @@ public abstract class DB extends RoomDatabase {
public void migrate(SupportSQLiteDatabase db) { public void migrate(SupportSQLiteDatabase db) {
Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion); Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `message` ADD COLUMN `ui_browsed` INTEGER NOT NULL DEFAULT 0"); db.execSQL("ALTER TABLE `message` ADD COLUMN `ui_browsed` INTEGER NOT NULL DEFAULT 0");
db.execSQL("CREATE INDEX `index_message_ui_browsed` ON `message` (`ui_browsed`)"); db.execSQL("CREATE INDEX `index_message_ui_browsed` ON `message` (`ui_browsed`)");
} }
}) })
.addMigrations(new Migration(10, 11) { .addMigrations(new Migration(10, 11) {
@ -248,6 +248,17 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `folder` ADD COLUMN `poll` INTEGER NOT NULL DEFAULT 0"); db.execSQL("ALTER TABLE `folder` ADD COLUMN `poll` INTEGER NOT NULL DEFAULT 0");
} }
}) })
.addMigrations(new Migration(16, 17) {
@Override
public void migrate(SupportSQLiteDatabase db) {
Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("DELETE FROM `message` WHERE ui_found");
db.execSQL("DROP INDEX `index_message_folder_uid_ui_found`");
db.execSQL("DROP INDEX `index_message_msgid_folder_ui_found`");
db.execSQL("CREATE UNIQUE INDEX `index_message_folder_uid` ON `message` (`folder`, `uid`)");
db.execSQL("CREATE UNIQUE INDEX `index_message_msgid_folder` ON `message` (`msgid`, `folder`)");
}
})
.build(); .build();
} }

@ -53,7 +53,7 @@ public interface DaoFolder {
", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" + ", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" +
" FROM folder" + " FROM folder" +
" LEFT JOIN account ON account.id = folder.account" + " LEFT JOIN account ON account.id = folder.account" +
" LEFT JOIN message ON message.folder = folder.id AND NOT message.ui_hide AND NOT message.ui_found" + " LEFT JOIN message ON message.folder = folder.id AND NOT message.ui_hide" +
" WHERE CASE WHEN :account IS NULL" + " WHERE CASE WHEN :account IS NULL" +
" THEN folder.unified AND account.synchronize" + " THEN folder.unified AND account.synchronize" +
" ELSE folder.account = :account OR folder.account IS NULL" + " ELSE folder.account = :account OR folder.account IS NULL" +
@ -72,7 +72,7 @@ public interface DaoFolder {
", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" + ", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" +
" FROM folder" + " FROM folder" +
" JOIN account ON account.id = folder.account" + " JOIN account ON account.id = folder.account" +
" JOIN message ON message.folder = folder.id AND NOT message.ui_hide AND NOT message.ui_found" + " JOIN message ON message.folder = folder.id AND NOT message.ui_hide" +
" WHERE account.`synchronize`" + " WHERE account.`synchronize`" +
" AND folder.unified" + " AND folder.unified" +
" GROUP BY folder.id") " GROUP BY folder.id")
@ -90,7 +90,7 @@ public interface DaoFolder {
", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" + ", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" +
" FROM folder" + " FROM folder" +
" LEFT JOIN account ON account.id = folder.account" + " LEFT JOIN account ON account.id = folder.account" +
" LEFT JOIN message ON message.folder = folder.id AND NOT message.ui_hide AND NOT message.ui_found" + " LEFT JOIN message ON message.folder = folder.id AND NOT message.ui_hide" +
" WHERE folder.id = :id") " WHERE folder.id = :id")
LiveData<TupleFolderEx> liveFolderEx(long id); LiveData<TupleFolderEx> liveFolderEx(long id);

@ -57,7 +57,6 @@ public interface DaoMessage {
" JOIN folder ON folder.id = message.folder" + " JOIN folder ON folder.id = message.folder" +
" WHERE account.`synchronize`" + " WHERE account.`synchronize`" +
" AND (NOT message.ui_hide OR :debug)" + " AND (NOT message.ui_hide OR :debug)" +
" AND NOT ui_found" +
" GROUP BY account.id, CASE WHEN message.thread IS NULL OR NOT :threading THEN message.id ELSE message.thread END" + " GROUP BY account.id, CASE WHEN message.thread IS NULL OR NOT :threading THEN message.id ELSE message.thread END" +
" HAVING SUM(unified) > 0" + " HAVING SUM(unified) > 0" +
" ORDER BY CASE" + " ORDER BY CASE" +
@ -90,7 +89,7 @@ public interface DaoMessage {
" JOIN folder f ON f.id = :folder" + " JOIN folder f ON f.id = :folder" +
" WHERE (message.account = f.account OR folder.type = '" + EntityFolder.OUTBOX + "')" + " WHERE (message.account = f.account OR folder.type = '" + EntityFolder.OUTBOX + "')" +
" AND (NOT message.ui_hide OR :debug)" + " AND (NOT message.ui_hide OR :debug)" +
" AND ui_found = :found" + " AND (NOT :found OR ui_found = :found)" +
" GROUP BY CASE WHEN message.thread IS NULL OR NOT :threading THEN message.id ELSE message.thread END" + " GROUP BY CASE WHEN message.thread IS NULL OR NOT :threading THEN message.id ELSE message.thread END" +
" HAVING SUM(CASE WHEN folder.id = :folder THEN 1 ELSE 0 END) > 0" + " HAVING SUM(CASE WHEN folder.id = :folder THEN 1 ELSE 0 END) > 0" +
" ORDER BY CASE" + " ORDER BY CASE" +
@ -126,14 +125,13 @@ public interface DaoMessage {
" WHERE message.account = :account" + " WHERE message.account = :account" +
" AND message.thread = :thread" + " AND message.thread = :thread" +
" AND (:id IS NULL OR message.id = :id)" + " AND (:id IS NULL OR message.id = :id)" +
" AND ui_found = :found" +
" AND (NOT message.ui_hide OR :debug)" + " AND (NOT message.ui_hide OR :debug)" +
" ORDER BY CASE" + " ORDER BY CASE" +
" WHEN 'unread' = :sort THEN NOT message.ui_seen" + " WHEN 'unread' = :sort THEN NOT message.ui_seen" +
" WHEN 'starred' = :sort THEN message.ui_flagged" + " WHEN 'starred' = :sort THEN message.ui_flagged" +
" ELSE 0" + " ELSE 0" +
" END DESC, message.received DESC") " END DESC, message.received DESC")
DataSource.Factory<Integer, TupleMessageEx> pagedThread(long account, String thread, Long id, boolean found, String sort, boolean debug); DataSource.Factory<Integer, TupleMessageEx> pagedThread(long account, String thread, Long id, String sort, boolean debug);
@Query("SELECT COUNT(id)" + @Query("SELECT COUNT(id)" +
" FROM message" + " FROM message" +
@ -148,38 +146,33 @@ public interface DaoMessage {
@Query("SELECT *" + @Query("SELECT *" +
" FROM message" + " FROM message" +
" WHERE folder = :folder" + " WHERE folder = :folder" +
" AND uid = :uid" + " AND uid = :uid")
" AND ui_found = :found") EntityMessage getMessageByUid(long folder, long uid);
EntityMessage getMessageByUid(long folder, long uid, boolean found);
@Query("SELECT id" + @Query("SELECT id" +
" FROM message" + " FROM message" +
" WHERE folder = :folder" + " WHERE folder = :folder" +
" AND ui_found = :found" +
" ORDER BY message.received DESC") " ORDER BY message.received DESC")
List<Long> getMessageByFolder(long folder, boolean found); List<Long> getMessageByFolder(long folder);
@Query("SELECT *" + @Query("SELECT *" +
" FROM message" + " FROM message" +
" WHERE account = :account" + " WHERE account = :account" +
" AND thread = :thread" + " AND thread = :thread" +
" AND (:id IS NULL OR message.id = :id)" + " AND (:id IS NULL OR message.id = :id)" +
" AND (:folder IS NULL OR message.folder = :folder)" + " AND (:folder IS NULL OR message.folder = :folder)")
" AND ui_found = :found") List<EntityMessage> getMessageByThread(long account, String thread, Long id, Long folder);
List<EntityMessage> getMessageByThread(long account, String thread, Long id, Long folder, boolean found);
@Query("SELECT message.* FROM message" + @Query("SELECT message.* FROM message" +
" JOIN folder ON folder.id = message.folder" + " JOIN folder ON folder.id = message.folder" +
" WHERE message.account = :account" + " WHERE message.account = :account" +
" AND message.msgid = :msgid" + " AND message.msgid = :msgid")
" AND ui_found = :found") List<EntityMessage> getMessageByMsgId(long account, String msgid);
List<EntityMessage> getMessageByMsgId(long account, String msgid, boolean found);
@Query("SELECT * FROM message" + @Query("SELECT * FROM message" +
" WHERE folder = :folder" + " WHERE folder = :folder" +
" AND ui_seen" + " AND ui_seen")
" AND ui_found = :found") List<EntityMessage> getMessageSeen(long folder);
List<EntityMessage> getMessageSeen(long folder, boolean found);
@Query("SELECT id FROM message" + @Query("SELECT id FROM message" +
" WHERE content" + " WHERE content" +
@ -218,7 +211,6 @@ public interface DaoMessage {
" AND (account.created IS NULL OR message.received > account.created)" + " AND (account.created IS NULL OR message.received > account.created)" +
" AND NOT message.ui_seen" + " AND NOT message.ui_seen" +
" AND NOT message.ui_hide" + " AND NOT message.ui_hide" +
" AND NOT message.ui_found" +
" AND NOT message.ui_ignored" + " AND NOT message.ui_ignored" +
" ORDER BY message.received") " ORDER BY message.received")
LiveData<List<TupleMessageEx>> liveUnseenUnified(); LiveData<List<TupleMessageEx>> liveUnseenUnified();
@ -230,7 +222,6 @@ public interface DaoMessage {
" AND folder.unified" + " AND folder.unified" +
" AND NOT message.ui_seen" + " AND NOT message.ui_seen" +
" AND NOT message.ui_hide" + " AND NOT message.ui_hide" +
" AND NOT message.ui_found" +
" AND NOT message.ui_ignored" + " AND NOT message.ui_ignored" +
" ORDER BY message.received") " ORDER BY message.received")
int getUnseenUnified(); int getUnseenUnified();
@ -238,8 +229,7 @@ public interface DaoMessage {
@Query("SELECT uid FROM message" + @Query("SELECT uid FROM message" +
" WHERE folder = :folder" + " WHERE folder = :folder" +
" AND received >= :received" + " AND received >= :received" +
" AND NOT uid IS NULL" + " AND NOT uid IS NULL")
" AND NOT ui_found" /* keep found messages */)
List<Long> getUids(long folder, long received); List<Long> getUids(long folder, long received);
@Insert @Insert
@ -298,6 +288,14 @@ public interface DaoMessage {
" AND folder IN (SELECT id FROM folder WHERE type = '" + EntityFolder.INBOX + "')") " AND folder IN (SELECT id FROM folder WHERE type = '" + EntityFolder.INBOX + "')")
int ignoreAll(); int ignoreAll();
@Query("UPDATE message SET ui_found = 1" +
" WHERE account = :account" +
" AND thread = :thread")
int setMessageFound(long account, String thread);
@Query("UPDATE message SET ui_found = 0")
int resetSearch();
@Query("DELETE FROM message WHERE id = :id") @Query("DELETE FROM message WHERE id = :id")
int deleteMessage(long id); int deleteMessage(long id);
@ -323,7 +321,4 @@ public interface DaoMessage {
" AND (NOT ui_browsed OR :browsed)" + " AND (NOT ui_browsed OR :browsed)" +
" AND NOT ui_flagged") " AND NOT ui_flagged")
int deleteMessagesBefore(long folder, long received, boolean browsed); int deleteMessagesBefore(long folder, long received, boolean browsed);
@Query("DELETE FROM message WHERE ui_found")
int deleteFoundMessages();
} }

@ -69,8 +69,8 @@ import static androidx.room.ForeignKey.SET_NULL;
@Index(value = {"identity"}), @Index(value = {"identity"}),
@Index(value = {"replying"}), @Index(value = {"replying"}),
@Index(value = {"forwarding"}), @Index(value = {"forwarding"}),
@Index(value = {"folder", "uid", "ui_found"}, unique = true), @Index(value = {"folder", "uid"}, unique = true),
@Index(value = {"msgid", "folder", "ui_found"}, unique = true), @Index(value = {"msgid", "folder"}, unique = true),
@Index(value = {"thread"}), @Index(value = {"thread"}),
@Index(value = {"received"}), @Index(value = {"received"}),
@Index(value = {"ui_seen"}), @Index(value = {"ui_seen"}),

@ -84,17 +84,17 @@ public class EntityOperation {
queue(db, message.folder, message.id, name, jargs); queue(db, message.folder, message.id, name, jargs);
if (SEEN.equals(name)) { if (SEEN.equals(name)) {
for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid, message.ui_found)) { for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid)) {
db.message().setMessageUiSeen(similar.id, (boolean) value); db.message().setMessageUiSeen(similar.id, (boolean) value);
db.message().setMessageUiIgnored(similar.id, true); db.message().setMessageUiIgnored(similar.id, true);
} }
} else if (FLAG.equals(name)) } else if (FLAG.equals(name))
for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid, message.ui_found)) for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid))
db.message().setMessageUiFlagged(similar.id, (boolean) value); db.message().setMessageUiFlagged(similar.id, (boolean) value);
else if (ANSWERED.equals(name)) else if (ANSWERED.equals(name))
for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid, message.ui_found)) for (EntityMessage similar : db.message().getMessageByMsgId(message.account, message.msgid))
db.message().setMessageUiAnswered(similar.id, (boolean) value); db.message().setMessageUiAnswered(similar.id, (boolean) value);
else if (MOVE.equals(name)) else if (MOVE.equals(name))

@ -94,7 +94,6 @@ public class FragmentMessages extends FragmentEx {
private boolean outgoing = false; private boolean outgoing = false;
private String thread = null; private String thread = null;
private long id = -1; private long id = -1;
private boolean found = false;
private String search = null; private String search = null;
private boolean threading = true; private boolean threading = true;
@ -136,7 +135,6 @@ public class FragmentMessages extends FragmentEx {
outgoing = args.getBoolean("outgoing", false); outgoing = args.getBoolean("outgoing", false);
thread = args.getString("thread"); thread = args.getString("thread");
id = args.getLong("id", -1); id = args.getLong("id", -1);
found = args.getBoolean("found", false);
search = args.getString("search"); search = args.getString("search");
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
@ -548,7 +546,7 @@ public class FragmentMessages extends FragmentEx {
result.target = target; result.target = target;
List<EntityMessage> messages = db.message().getMessageByThread( List<EntityMessage> messages = db.message().getMessageByThread(
message.account, message.thread, threading && thread ? null : id, message.folder, message.ui_found); message.account, message.thread, threading && thread ? null : id, message.folder);
for (EntityMessage threaded : messages) { for (EntityMessage threaded : messages) {
result.ids.add(threaded.id); result.ids.add(threaded.id);
db.message().setMessageUiHide(threaded.id, true); db.message().setMessageUiHide(threaded.id, true);
@ -606,7 +604,6 @@ public class FragmentMessages extends FragmentEx {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putLong("account", account); args.putLong("account", account);
args.putString("thread", thread); args.putString("thread", thread);
args.putBoolean("found", found);
args.putString("folderType", folderType); args.putString("folderType", folderType);
new SimpleTask<MessageTarget>() { new SimpleTask<MessageTarget>() {
@ -614,7 +611,6 @@ public class FragmentMessages extends FragmentEx {
protected MessageTarget onLoad(Context context, Bundle args) { protected MessageTarget onLoad(Context context, Bundle args) {
long account = args.getLong("account"); long account = args.getLong("account");
String thread = args.getString("thread"); String thread = args.getString("thread");
boolean found = args.getBoolean("found");
String folderType = args.getString("folderType"); String folderType = args.getString("folderType");
MessageTarget result = new MessageTarget(); MessageTarget result = new MessageTarget();
@ -626,7 +622,7 @@ public class FragmentMessages extends FragmentEx {
result.target = db.folder().getFolderByType(account, folderType); result.target = db.folder().getFolderByType(account, folderType);
List<EntityMessage> messages = db.message().getMessageByThread( List<EntityMessage> messages = db.message().getMessageByThread(
account, thread, threading ? null : id, null, found); account, thread, threading ? null : id, null);
for (EntityMessage threaded : messages) for (EntityMessage threaded : messages)
if (!result.target.id.equals(threaded.folder)) { if (!result.target.id.equals(threaded.folder)) {
result.ids.add(threaded.id); result.ids.add(threaded.id);
@ -659,8 +655,7 @@ public class FragmentMessages extends FragmentEx {
new Intent(ActivityView.ACTION_VIEW_THREAD) new Intent(ActivityView.ACTION_VIEW_THREAD)
.putExtra("account", target.account) .putExtra("account", target.account)
.putExtra("thread", target.thread) .putExtra("thread", target.thread)
.putExtra("id", target.id) .putExtra("id", target.id));
.putExtra("found", target.found));
} }
}); });
@ -851,7 +846,7 @@ public class FragmentMessages extends FragmentEx {
EntityMessage message = db.message().getMessage(id); EntityMessage message = db.message().getMessage(id);
if (message.ui_seen != seen) { if (message.ui_seen != seen) {
List<EntityMessage> messages = db.message().getMessageByThread( List<EntityMessage> messages = db.message().getMessageByThread(
message.account, message.thread, threading ? null : id, message.folder, message.ui_found); message.account, message.thread, threading ? null : id, message.folder);
for (EntityMessage threaded : messages) for (EntityMessage threaded : messages)
EntityOperation.queue(db, threaded, EntityOperation.SEEN, seen); EntityOperation.queue(db, threaded, EntityOperation.SEEN, seen);
} }
@ -893,7 +888,7 @@ public class FragmentMessages extends FragmentEx {
EntityMessage message = db.message().getMessage(id); EntityMessage message = db.message().getMessage(id);
if (message.ui_flagged != flagged) { if (message.ui_flagged != flagged) {
List<EntityMessage> messages = db.message().getMessageByThread( List<EntityMessage> messages = db.message().getMessageByThread(
message.account, message.thread, threading ? null : id, message.folder, message.ui_found); message.account, message.thread, threading ? null : id, message.folder);
for (EntityMessage threaded : messages) for (EntityMessage threaded : messages)
EntityOperation.queue(db, threaded, EntityOperation.FLAG, flagged); EntityOperation.queue(db, threaded, EntityOperation.FLAG, flagged);
} }
@ -950,7 +945,7 @@ public class FragmentMessages extends FragmentEx {
for (long id : ids) { for (long id : ids) {
EntityMessage message = db.message().getMessage(id); EntityMessage message = db.message().getMessage(id);
List<EntityMessage> messages = db.message().getMessageByThread( List<EntityMessage> messages = db.message().getMessageByThread(
message.account, message.thread, threading ? null : id, message.folder, message.ui_found); message.account, message.thread, threading ? null : id, message.folder);
for (EntityMessage threaded : messages) { for (EntityMessage threaded : messages) {
if (threaded.uid == null && !TextUtils.isEmpty(threaded.error)) // outbox if (threaded.uid == null && !TextUtils.isEmpty(threaded.error)) // outbox
db.message().deleteMessage(threaded.id); db.message().deleteMessage(threaded.id);
@ -1003,7 +998,7 @@ public class FragmentMessages extends FragmentEx {
for (long id : ids) { for (long id : ids) {
EntityMessage message = db.message().getMessage(id); EntityMessage message = db.message().getMessage(id);
List<EntityMessage> messages = db.message().getMessageByThread( List<EntityMessage> messages = db.message().getMessageByThread(
message.account, message.thread, threading ? null : id, message.folder, message.ui_found); message.account, message.thread, threading ? null : id, message.folder);
for (EntityMessage threaded : messages) { for (EntityMessage threaded : messages) {
result.ids.add(threaded.id); result.ids.add(threaded.id);
db.message().setMessageUiHide(threaded.id, true); db.message().setMessageUiHide(threaded.id, true);
@ -1092,7 +1087,7 @@ public class FragmentMessages extends FragmentEx {
for (long id : ids) { for (long id : ids) {
EntityMessage message = db.message().getMessage(id); EntityMessage message = db.message().getMessage(id);
List<EntityMessage> messages = db.message().getMessageByThread( List<EntityMessage> messages = db.message().getMessageByThread(
message.account, message.thread, threading ? null : id, message.folder, message.ui_found); message.account, message.thread, threading ? null : id, message.folder);
for (EntityMessage threaded : messages) { for (EntityMessage threaded : messages) {
result.ids.add(threaded.id); result.ids.add(threaded.id);
db.message().setMessageUiHide(threaded.id, true); db.message().setMessageUiHide(threaded.id, true);
@ -1363,7 +1358,7 @@ public class FragmentMessages extends FragmentEx {
new SimpleTask<Void>() { new SimpleTask<Void>() {
@Override @Override
protected Void onLoad(Context context, Bundle args) { protected Void onLoad(Context context, Bundle args) {
DB.getInstance(context).message().deleteFoundMessages(); DB.getInstance(context).message().resetSearch();
return null; return null;
} }
@ -1485,7 +1480,7 @@ public class FragmentMessages extends FragmentEx {
try { try {
db.beginTransaction(); db.beginTransaction();
for (EntityMessage message : db.message().getMessageSeen(outbox, false)) { for (EntityMessage message : db.message().getMessageSeen(outbox)) {
EntityIdentity identity = db.identity().getIdentity(message.identity); EntityIdentity identity = db.identity().getIdentity(message.identity);
EntityFolder sent = db.folder().getFolderByType(identity.account, EntityFolder.SENT); EntityFolder sent = db.folder().getFolderByType(identity.account, EntityFolder.SENT);
if (sent != null) { if (sent != null) {
@ -1574,7 +1569,7 @@ public class FragmentMessages extends FragmentEx {
case THREAD: case THREAD:
messages = new LivePagedListBuilder<>( messages = new LivePagedListBuilder<>(
db.message().pagedThread(account, thread, threading ? null : id, found, sort, debug), LOCAL_PAGE_SIZE).build(); db.message().pagedThread(account, thread, threading ? null : id, sort, debug), LOCAL_PAGE_SIZE).build();
break; break;
} }
} else { } else {

@ -926,13 +926,12 @@ public class ServiceSynchronize extends LifecycleService {
for (Message imessage : e.getMessages()) for (Message imessage : e.getMessages())
try { try {
long id; EntityMessage message;
try { try {
db.beginTransaction(); db.beginTransaction();
id = synchronizeMessage( message = synchronizeMessage(
ServiceSynchronize.this, ServiceSynchronize.this,
folder, ifolder, (IMAPMessage) imessage, folder, ifolder, (IMAPMessage) imessage, false, false);
false, false, false);
db.setTransactionSuccessful(); db.setTransactionSuccessful();
} finally { } finally {
db.endTransaction(); db.endTransaction();
@ -940,7 +939,9 @@ public class ServiceSynchronize extends LifecycleService {
try { try {
db.beginTransaction(); db.beginTransaction();
downloadMessage(ServiceSynchronize.this, folder, ifolder, (IMAPMessage) imessage, id); downloadMessage(
ServiceSynchronize.this,
folder, ifolder, (IMAPMessage) imessage, message.id);
db.setTransactionSuccessful(); db.setTransactionSuccessful();
} finally { } finally {
db.endTransaction(); db.endTransaction();
@ -1006,13 +1007,12 @@ public class ServiceSynchronize extends LifecycleService {
fp.add(IMAPFolder.FetchProfileItem.FLAGS); fp.add(IMAPFolder.FetchProfileItem.FLAGS);
ifolder.fetch(new Message[]{e.getMessage()}, fp); ifolder.fetch(new Message[]{e.getMessage()}, fp);
long id; EntityMessage message;
try { try {
db.beginTransaction(); db.beginTransaction();
id = synchronizeMessage( message = synchronizeMessage(
ServiceSynchronize.this, ServiceSynchronize.this,
folder, ifolder, (IMAPMessage) e.getMessage(), folder, ifolder, (IMAPMessage) e.getMessage(), false, false);
false, false, false);
db.setTransactionSuccessful(); db.setTransactionSuccessful();
} finally { } finally {
db.endTransaction(); db.endTransaction();
@ -1020,7 +1020,7 @@ public class ServiceSynchronize extends LifecycleService {
try { try {
db.beginTransaction(); db.beginTransaction();
downloadMessage(ServiceSynchronize.this, folder, ifolder, (IMAPMessage) e.getMessage(), id); downloadMessage(ServiceSynchronize.this, folder, ifolder, (IMAPMessage) e.getMessage(), message.id);
db.setTransactionSuccessful(); db.setTransactionSuccessful();
} finally { } finally {
db.endTransaction(); db.endTransaction();
@ -1948,7 +1948,7 @@ public class ServiceSynchronize extends LifecycleService {
List<Message> full = new ArrayList<>(); List<Message> full = new ArrayList<>();
for (Message imessage : isub) { for (Message imessage : isub) {
long uid = ifolder.getUID(imessage); long uid = ifolder.getUID(imessage);
EntityMessage message = db.message().getMessageByUid(folder.id, uid, false); EntityMessage message = db.message().getMessageByUid(folder.id, uid);
if (message == null) if (message == null)
full.add(imessage); full.add(imessage);
} }
@ -1962,10 +1962,10 @@ public class ServiceSynchronize extends LifecycleService {
for (int j = isub.length - 1; j >= 0 && state.running(); j--) for (int j = isub.length - 1; j >= 0 && state.running(); j--)
try { try {
db.beginTransaction(); db.beginTransaction();
ids[from + j] = synchronizeMessage( EntityMessage message = synchronizeMessage(
this, this,
folder, ifolder, (IMAPMessage) isub[j], folder, ifolder, (IMAPMessage) isub[j], false, true);
false, false, true); ids[from + j] = message.id;
db.setTransactionSuccessful(); db.setTransactionSuccessful();
Thread.sleep(20); Thread.sleep(20);
} catch (MessageRemovedException ex) { } catch (MessageRemovedException ex) {
@ -2036,10 +2036,10 @@ public class ServiceSynchronize extends LifecycleService {
} }
} }
static Long synchronizeMessage( static EntityMessage synchronizeMessage(
Context context, Context context,
EntityFolder folder, IMAPFolder ifolder, IMAPMessage imessage, EntityFolder folder, IMAPFolder ifolder, IMAPMessage imessage,
boolean found, boolean browsed, boolean full) throws MessagingException, IOException { boolean browsed, boolean full) throws MessagingException, IOException {
long uid = ifolder.getUID(imessage); long uid = ifolder.getUID(imessage);
if (imessage.isExpunged()) { if (imessage.isExpunged()) {
@ -2060,7 +2060,7 @@ public class ServiceSynchronize extends LifecycleService {
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
// Find message by uid (fast, no headers required) // Find message by uid (fast, no headers required)
EntityMessage message = db.message().getMessageByUid(folder.id, uid, found); EntityMessage message = db.message().getMessageByUid(folder.id, uid);
// Find message by Message-ID (slow, headers required) // Find message by Message-ID (slow, headers required)
// - messages in inbox have same id as message sent to self // - messages in inbox have same id as message sent to self
@ -2069,7 +2069,7 @@ public class ServiceSynchronize extends LifecycleService {
// Will fetch headers within database transaction // Will fetch headers within database transaction
String msgid = helper.getMessageID(); String msgid = helper.getMessageID();
Log.i(Helper.TAG, "Searching for " + msgid); Log.i(Helper.TAG, "Searching for " + msgid);
for (EntityMessage dup : db.message().getMessageByMsgId(folder.account, msgid, found)) { for (EntityMessage dup : db.message().getMessageByMsgId(folder.account, msgid)) {
EntityFolder dfolder = db.folder().getFolder(dup.folder); EntityFolder dfolder = db.folder().getFolder(dup.folder);
boolean outbox = EntityFolder.OUTBOX.equals(dfolder.type); boolean outbox = EntityFolder.OUTBOX.equals(dfolder.type);
Log.i(Helper.TAG, folder.name + " found as id=" + dup.id + "/" + dup.uid + Log.i(Helper.TAG, folder.name + " found as id=" + dup.id + "/" + dup.uid +
@ -2162,7 +2162,7 @@ public class ServiceSynchronize extends LifecycleService {
message.ui_answered = answered; message.ui_answered = answered;
message.ui_flagged = flagged; message.ui_flagged = flagged;
message.ui_hide = false; message.ui_hide = false;
message.ui_found = found; message.ui_found = false;
message.ui_ignored = false; message.ui_ignored = false;
message.ui_browsed = browsed; message.ui_browsed = browsed;
message.getAvatar(context); message.getAvatar(context);
@ -2243,7 +2243,7 @@ public class ServiceSynchronize extends LifecycleService {
db.folder().setFolderKeywords(folder.id, DB.Converters.fromStringArray(fkeywords.toArray(new String[0]))); db.folder().setFolderKeywords(folder.id, DB.Converters.fromStringArray(fkeywords.toArray(new String[0])));
} }
return message.id; return message;
} }
private static void downloadMessage(Context context, EntityFolder folder, IMAPFolder ifolder, IMAPMessage imessage, long id) throws MessagingException, IOException { private static void downloadMessage(Context context, EntityFolder folder, IMAPFolder ifolder, IMAPMessage imessage, long id) throws MessagingException, IOException {

@ -90,7 +90,7 @@ public class ViewModelBrowse extends ViewModel {
db.beginTransaction(); db.beginTransaction();
if (state.messages == null) if (state.messages == null)
state.messages = db.message().getMessageByFolder(state.fid, false); state.messages = db.message().getMessageByFolder(state.fid);
int matched = 0; int matched = 0;
for (int i = state.local; i < state.messages.size() && matched < state.pageSize; i++) { for (int i = state.local; i < state.messages.size() && matched < state.pageSize; i++) {
@ -115,17 +115,8 @@ public class ViewModelBrowse extends ViewModel {
if (!match && message.content) if (!match && message.content)
match = body.toLowerCase().contains(find); match = body.toLowerCase().contains(find);
if (match) { if (match)
EntityMessage exists = db.message().getMessageByUid(state.fid, message.uid, state.search != null); db.message().setMessageFound(message.account, message.thread);
if (exists == null) {
matched++;
message.id = null;
message.ui_found = true;
message.id = db.message().insertMessage(message);
if (message.content)
message.write(state.context, body);
}
}
} }
db.setTransactionSuccessful(); db.setTransactionSuccessful();
@ -202,14 +193,14 @@ public class ViewModelBrowse extends ViewModel {
try { try {
long uid = state.ifolder.getUID(isub[j]); long uid = state.ifolder.getUID(isub[j]);
Log.i(Helper.TAG, "Boundary sync uid=" + uid); Log.i(Helper.TAG, "Boundary sync uid=" + uid);
EntityMessage message = db.message().getMessageByUid(state.fid, uid, state.search != null); EntityMessage message = db.message().getMessageByUid(state.fid, uid);
if (message == null) { if (message == null) {
ServiceSynchronize.synchronizeMessage( message = ServiceSynchronize.synchronizeMessage(
state.context, state.context,
folder, state.ifolder, (IMAPMessage) isub[j], folder, state.ifolder, (IMAPMessage) isub[j], true, false);
state.search != null, state.search == null, false);
count++; count++;
} }
db.message().setMessageFound(message.account, message.thread);
} catch (MessageRemovedException ex) { } catch (MessageRemovedException ex) {
Log.w(Helper.TAG, "Boundary " + ex + "\n" + Log.getStackTraceString(ex)); Log.w(Helper.TAG, "Boundary " + ex + "\n" + Log.getStackTraceString(ex));
} catch (FolderClosedException ex) { } catch (FolderClosedException ex) {

Loading…
Cancel
Save