Added sort on sender name

Requires SDK 34 = Android 14
pull/217/head
M66B 9 months ago
parent d3b6b81208
commit e4d6244e0d

@ -168,6 +168,8 @@ public abstract class DB extends RoomDatabase {
try {
// https://www.sqlite.org/json1.html
// The JSON functions and operators are built into SQLite by default, as of SQLite version 3.38.0 (2022-02-22)
// SDK 14 / Android 14 has 3.39.2
// https://stackoverflow.com/questions/2421189/version-of-sqlite-used-in-android
String version = getSqliteVersion();
if (version == null)
return false;

@ -1119,15 +1119,7 @@ public interface DaoMessage {
" OR (NOT :found AND :type IS NULL AND folder.unified)" +
" OR (NOT :found AND folder.type = :type)" +
" THEN message.received ELSE 0 END) AS dummy" +
" FROM (SELECT * FROM message" +
" WHERE message.thread IN" +
" (SELECT DISTINCT mm.thread FROM folder ff" +
" JOIN message mm ON mm.folder = ff.id" +
" WHERE ((:found AND mm.ui_found)" +
" OR (NOT :found AND :type IS NULL AND ff.unified)" +
" OR (NOT :found AND :type IS NOT NULL AND ff.type = :type))" +
" AND (NOT mm.ui_hide OR :debug))" +
" ORDER BY received DESC) AS message" + // group_concat
" FROM message" +
" JOIN account_view AS account ON account.id = message.account" +
" LEFT JOIN identity_view AS identity ON identity.id = message.identity" +
" JOIN folder_view AS folder ON folder.id = message.folder" +
@ -1141,8 +1133,9 @@ public interface DaoMessage {
" OR (NOT :found AND :type IS NULL AND folder.unified)" +
" OR (NOT :found AND :type IS NOT NULL AND folder.type = :type)) > 0)" + // thread can be the same in different accounts
" AND SUM(NOT message.ui_hide OR :debug) > 0" +
" AND (NOT :filter_seen OR SUM(1 - message.ui_seen) > 0)" +
" AND (NOT :filter_unflagged OR COUNT(message.id) - SUM(1 - message.ui_flagged) > 0)" +
" AND (NOT (:filter_seen AND NOT :filter_unflagged) OR SUM(1 - message.ui_seen) > 0)" +
" AND (NOT (:filter_unflagged AND NOT :filter_seen) OR COUNT(message.id) - SUM(1 - message.ui_flagged) > 0)" +
" AND (NOT (:filter_seen AND :filter_unflagged) OR SUM(1 - message.ui_seen) > 0 OR COUNT(message.id) - SUM(1 - message.ui_flagged) > 0)" +
" AND (NOT :filter_unknown OR SUM(message.avatar IS NOT NULL AND message.sender <> identity.email) > 0)" +
" AND (NOT :filter_snoozed OR message.ui_snoozed IS NULL OR " + is_drafts + ")" +
" AND (NOT :filter_deleted OR NOT message.ui_deleted)" +
@ -1154,6 +1147,7 @@ public interface DaoMessage {
" WHEN 'starred' = :sort1 THEN COUNT(message.id) - SUM(1 - message.ui_flagged) = 0" +
" WHEN 'priority' = :sort1 THEN -IFNULL(message.priority, 1)" +
" WHEN 'sender' = :sort1 THEN LOWER(message.sender)" +
" WHEN 'sender_name' = :sort1 THEN LOWER(COALESCE(json_extract(message.`from`, '$[0].personal'), json_extract(message.`from`, '$[0].address')))" +
" WHEN 'subject' = :sort1 THEN LOWER(message.subject)" +
" WHEN 'size' = :sort1 THEN -SUM(message.total)" +
" WHEN 'attachments' = :sort1 THEN -SUM(message.attachments)" +
@ -1167,7 +1161,7 @@ public interface DaoMessage {
" ELSE 0" +
" END" +
", CASE WHEN :ascending THEN message.received ELSE -message.received END")
DataSource.Factory<Integer, TupleMessageEx> pagedUnifiedLegacy(
DataSource.Factory<Integer, TupleMessageEx> pagedUnifiedJson(
String type, String category,
boolean threading, boolean group_category,
String sort1, String sort2, boolean ascending,
@ -1205,13 +1199,7 @@ public interface DaoMessage {
" (:found AND folder.type <> '" + EntityFolder.ARCHIVE + "')" +
" OR (NOT :found AND folder.id = :folder)" +
" THEN message.received ELSE 0 END) AS dummy" +
" FROM (SELECT * FROM message" +
" WHERE message.thread IN" +
" (SELECT DISTINCT mm.thread FROM message mm" +
" WHERE mm.folder = :folder" +
" AND (NOT mm.ui_hide OR :debug)" +
" AND (NOT :found OR mm.ui_found))" +
" ORDER BY received DESC) AS message" + // group_concat
" FROM message" +
" JOIN account_view AS account ON account.id = message.account" +
" LEFT JOIN identity_view AS identity ON identity.id = message.identity" +
" JOIN folder_view AS folder ON folder.id = message.folder" +
@ -1224,8 +1212,9 @@ public interface DaoMessage {
" HAVING (SUM((:found AND message.ui_found)" +
" OR (NOT :found AND message.folder = :folder)) > 0)" +
" AND SUM(NOT message.ui_hide OR :debug) > 0" +
" AND (NOT :filter_seen OR SUM(1 - message.ui_seen) > 0 OR " + is_outbox + ")" +
" AND (NOT :filter_unflagged OR COUNT(message.id) - SUM(1 - message.ui_flagged) > 0 OR " + is_outbox + ")" +
" AND (NOT (:filter_seen AND NOT :filter_unflagged) OR SUM(1 - message.ui_seen) > 0 OR " + is_outbox + ")" +
" AND (NOT (:filter_unflagged AND NOT :filter_seen) OR COUNT(message.id) - SUM(1 - message.ui_flagged) > 0 OR " + is_outbox + ")" +
" AND (NOT (:filter_seen AND :filter_unflagged) OR SUM(1 - message.ui_seen) > 0 OR COUNT(message.id) - SUM(1 - message.ui_flagged) > 0 OR " + is_outbox + ")" +
" AND (NOT :filter_unknown OR SUM(message.avatar IS NOT NULL AND message.sender <> identity.email) > 0" +
" OR " + is_outbox + " OR " + is_drafts + " OR " + is_sent + ")" +
" AND (NOT :filter_snoozed OR message.ui_snoozed IS NULL OR " + is_outbox + " OR " + is_drafts + ")" +
@ -1237,6 +1226,7 @@ public interface DaoMessage {
" WHEN 'starred' = :sort1 THEN COUNT(message.id) - SUM(1 - message.ui_flagged) = 0" +
" WHEN 'priority' = :sort1 THEN -IFNULL(message.priority, 1)" +
" WHEN 'sender' = :sort1 THEN LOWER(message.sender)" +
" WHEN 'sender_name' = :sort1 THEN LOWER(COALESCE(json_extract(message.`from`, '$[0].personal'), json_extract(message.`from`, '$[0].address')))" +
" WHEN 'subject' = :sort1 THEN LOWER(message.subject)" +
" WHEN 'size' = :sort1 THEN -SUM(message.total)" +
" WHEN 'attachments' = :sort1 THEN -SUM(message.attachments)" +
@ -1250,7 +1240,7 @@ public interface DaoMessage {
" ELSE 0" +
" END" +
", CASE WHEN :ascending THEN message.received ELSE -message.received END")
DataSource.Factory<Integer, TupleMessageEx> pagedFolderLegacy(
DataSource.Factory<Integer, TupleMessageEx> pagedFolderJson(
long folder, boolean threading,
String sort1, String sort2, boolean ascending,
boolean filter_seen, boolean filter_unflagged, boolean filter_unknown, boolean filter_snoozed, boolean filter_deleted, String filter_language,

@ -6429,10 +6429,14 @@ public class FragmentMessages extends FragmentBase
menu.findItem(R.id.menu_sort_on_unread_starred).setVisible(false);
menu.findItem(R.id.menu_sort_on_starred_unread).setVisible(false);
menu.findItem(R.id.menu_sort_on_sender).setVisible(false);
menu.findItem(R.id.menu_sort_on_sender_name).setVisible(false);
menu.findItem(R.id.menu_sort_on_subject).setVisible(false);
menu.findItem(R.id.menu_sort_on_size).setVisible(false);
menu.findItem(R.id.menu_sort_on_attachments).setVisible(false);
menu.findItem(R.id.menu_sort_on_snoozed).setVisible(false);
} else {
if (!DB.hasJson())
menu.findItem(R.id.menu_sort_on_sender_name).setVisible(false);
}
boolean unselected = (selectionTracker == null || !selectionTracker.hasSelection());
@ -6453,6 +6457,8 @@ public class FragmentMessages extends FragmentBase
menu.findItem(R.id.menu_sort_on_priority).setChecked(true);
else if ("sender".equals(sort))
menu.findItem(R.id.menu_sort_on_sender).setChecked(true);
else if ("sender_name".equals(sort))
menu.findItem(R.id.menu_sort_on_sender_name).setChecked(true);
else if ("subject".equals(sort))
menu.findItem(R.id.menu_sort_on_subject).setChecked(true);
else if ("size".equals(sort))
@ -6609,6 +6615,10 @@ public class FragmentMessages extends FragmentBase
item.setChecked(true);
onMenuSort("sender");
return true;
} else if (itemId == R.id.menu_sort_on_sender_name) {
item.setChecked(true);
onMenuSort("sender_name");
return true;
} else if (itemId == R.id.menu_sort_on_subject) {
item.setChecked(true);
onMenuSort("subject");

@ -183,7 +183,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
private TextView tvSqliteCache;
private SeekBar sbSqliteCache;
private ImageButton ibSqliteCache;
private SwitchCompat swLegacyQueries;
private SwitchCompat swCacheLists;
private SwitchCompat swOauthTabs;
private TextView tvStartDelay;
@ -299,7 +298,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
"test1", "test2", "test3", "test4", "test5",
"emergency_file", "work_manager", "task_description", // "external_storage",
"sqlite_integrity_check", "wal", "sqlite_checkpoints", "sqlite_analyze", "sqlite_auto_vacuum", "sqlite_sync_extra", "sqlite_cache",
"legacy_queries",
"cache_lists", "oauth_tabs",
"start_delay", "range_size", "chunk_size", "thread_range", "restart_interval",
"autoscroll_editor", "undo_manager",
@ -453,7 +451,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
tvSqliteCache = view.findViewById(R.id.tvSqliteCache);
sbSqliteCache = view.findViewById(R.id.sbSqliteCache);
ibSqliteCache = view.findViewById(R.id.ibSqliteCache);
swLegacyQueries = view.findViewById(R.id.swLegacyQueries);
swCacheLists = view.findViewById(R.id.swCacheLists);
swOauthTabs = view.findViewById(R.id.swOauthTabs);
tvStartDelay = view.findViewById(R.id.tvStartDelay);
@ -1301,15 +1298,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
}
});
swLegacyQueries.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton v, boolean checked) {
prefs.edit().putBoolean("legacy_queries", checked).apply();
ViewModelMessages model = new ViewModelProvider(getActivity()).get(ViewModelMessages.class);
model.clear();
}
});
swCacheLists.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton v, boolean checked) {
@ -2549,7 +2537,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
Helper.humanReadableByteCount(cache_size * 1024L)));
sbSqliteCache.setProgress(sqlite_cache);
swLegacyQueries.setChecked(prefs.getBoolean("legacy_queries", false));
swCacheLists.setChecked(prefs.getBoolean("cache_lists", true));
swOauthTabs.setChecked(prefs.getBoolean("oauth_tabs", true));

@ -89,7 +89,6 @@ public class ViewModelMessages extends ViewModel {
BoundaryCallbackMessages.SearchCriteria criteria, boolean server) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean legacy = prefs.getBoolean("legacy_queries", false);
boolean cache_lists = prefs.getBoolean("cache_lists", true);
Args args = new Args(context,
@ -125,8 +124,8 @@ public class ViewModelMessages extends ViewModel {
.setPageSize(LOCAL_PAGE_SIZE)
.setMaxSize(MAX_CACHED_ITEMS)
.build();
if (legacy)
pager = db.message().pagedUnifiedLegacy(
if ("sender_name".equals(args.sort1))
pager = db.message().pagedUnifiedJson(
args.type,
args.category,
args.threading,
@ -165,8 +164,8 @@ public class ViewModelMessages extends ViewModel {
.setPrefetchDistance(REMOTE_PAGE_SIZE)
.setMaxSize(MAX_CACHED_ITEMS)
.build();
if (legacy)
pager = db.message().pagedFolderLegacy(
if ("sender_name".equals(args.sort1))
pager = db.message().pagedFolderJson(
args.folder, args.threading,
args.sort1, args.sort2, args.ascending,
args.filter_seen,
@ -214,8 +213,8 @@ public class ViewModelMessages extends ViewModel {
.setMaxSize(MAX_CACHED_ITEMS)
.build();
if (args.folder < 0) {
if (legacy)
pager = db.message().pagedUnifiedLegacy(
if ("sender_name".equals(args.sort1))
pager = db.message().pagedUnifiedJson(
null, null,
args.threading, false,
criteria == null || criteria.touched == null ? "time" : "touched", "", false,
@ -234,8 +233,8 @@ public class ViewModelMessages extends ViewModel {
args.debug);
builder = new LivePagedListBuilder<>(pager, configSearch);
} else {
if (legacy)
pager = db.message().pagedFolderLegacy(
if ("sender_name".equals(args.sort1))
pager = db.message().pagedFolderJson(
args.folder, args.threading,
criteria == null || criteria.touched == null ? "time" : "touched", "", false,
false, false, false, false, false,
@ -607,11 +606,16 @@ public class ViewModelMessages extends ViewModel {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
this.group_category = prefs.getBoolean("group_category", false);
String sort = prefs.getString(FragmentMessages.getSort(context, viewType, type), "time");
String[] sorts = sort.split("\\+");
this.sort1 = sorts[0];
this.sort2 = (sorts.length > 1 ? sorts[1] : "");
this.ascending = prefs.getBoolean(FragmentMessages.getSortOrder(context, viewType, type), outbox);
if ("sender_name".equals(this.sort1) && !DB.hasJson())
this.sort1 = "sender";
this.filter_seen = prefs.getBoolean(FragmentMessages.getFilter(context, "seen", viewType, type), false);
this.filter_unflagged = prefs.getBoolean(FragmentMessages.getFilter(context, "unflagged", viewType, type), false);
this.filter_unknown = prefs.getBoolean(FragmentMessages.getFilter(context, "unknown", viewType, type), false);

@ -1178,17 +1178,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ibSqliteCache" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLegacyQueries"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_legacy_queries"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvSqliteCacheHint"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swCacheLists"
android:layout_width="0dp"
@ -1197,7 +1186,7 @@
android:text="@string/title_advanced_cache_lists"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLegacyQueries"
app:layout_constraintTop_toBottomOf="@id/tvSqliteCacheHint"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat

@ -70,6 +70,9 @@
<item
android:id="@+id/menu_sort_on_sender"
android:title="@string/title_sort_on_sender" />
<item
android:id="@+id/menu_sort_on_sender_name"
android:title="@string/title_sort_on_sender_name" />
<item
android:id="@+id/menu_sort_on_subject"
android:title="@string/title_sort_on_subject" />

@ -2008,6 +2008,7 @@
<string name="title_sort_on_starred_unread">Starred, unread</string>
<string name="title_sort_on_priority">Priority</string>
<string name="title_sort_on_sender">Sender</string>
<string name="title_sort_on_sender_name">Sender name</string>
<string name="title_sort_on_subject">Subject</string>
<string name="title_sort_on_size">Size</string>
<string name="title_sort_on_attachments">Attachments</string>

Loading…
Cancel
Save