Some order

This commit is contained in:
M66B 2019-05-06 22:34:18 +02:00
parent 1f8a472131
commit 567aeffe46
20 changed files with 278 additions and 152 deletions

11
FAQ.md
View File

@ -986,13 +986,12 @@ Note that searching through a lot of messages stored locally would only delay se
<a name="faq51"></a>
**(51) How are folders sorted?**
Folders are sorted with special, system folders on top, followed by folders set to synchronize.
Within each category the folders are sorted on name.
Folders are first sorted on account order (by default on account name)
and within an account with special, system folders on top, followed by folders set to synchronize.
Within each category the folders are sorted on (display) name.
You can set the display name by long pressing a folder in the folder list and selecting *Edit properties*.
Some providers prefix some folders with INBOX, but these folders are in fact just user folders, so they are sorted below the special, system folders.
It is not possible to make an exception for this because some other providers prefix all folders with INBOX.
Note that you can give folders a display name by long pressing on a folder name, which can be useful because the display name will be used for sorting.
The navigation (hamburger) menu item *Order folders* in the setup can be used to manually order the folders.
<br />

View File

@ -58,7 +58,6 @@ import java.text.Collator;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
@ -671,36 +670,8 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
final Collator collator = Collator.getInstance(Locale.getDefault());
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
Collections.sort(folders, new Comparator<TupleFolderEx>() {
@Override
public int compare(TupleFolderEx f1, TupleFolderEx f2) {
if (account < 0) {
int o = Integer.compare(
f1.order == null ? -1 : f1.order,
f2.order == null ? -1 : f2.order);
if (o != 0)
return o;
String name1 = f1.getDisplayName(context);
String name2 = f2.getDisplayName(context);
return collator.compare(name1, name2);
} else {
int i1 = EntityFolder.FOLDER_SORT_ORDER.indexOf(f1.type);
int i2 = EntityFolder.FOLDER_SORT_ORDER.indexOf(f2.type);
int s = Integer.compare(i1, i2);
if (s != 0)
return s;
int c = -f1.synchronize.compareTo(f2.synchronize);
if (c != 0)
return c;
String name1 = f1.getDisplayName(context);
String name2 = f2.getDisplayName(context);
return collator.compare(name1, name2);
}
}
});
if (folders.size() > 0)
Collections.sort(folders, folders.get(0).getComparator(context));
DiffUtil.DiffResult diff = DiffUtil.calculateDiff(new DiffCallback(items, folders), false);

View File

@ -2155,7 +2155,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
if (folders == null)
return null;
EntityFolder.sort(context, folders, true);
if (folders.size() > 0)
Collections.sort(folders, folders.get(0).getComparator(context));
return folders;
}
@ -2850,7 +2851,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
!EntityFolder.JUNK.equals(folder.type))
targets.add(folder);
EntityFolder.sort(context, targets, true);
if (targets.size() > 0)
Collections.sort(targets, targets.get(0).getComparator(context));
return targets;
}

View File

@ -36,6 +36,7 @@ import androidx.recyclerview.widget.RecyclerView;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@ -120,6 +121,9 @@ public class AdapterNavAccount extends RecyclerView.Adapter<AdapterNavAccount.Vi
public void set(@NonNull List<TupleAccountEx> accounts) {
Log.i("Set nav accounts=" + accounts.size());
if (accounts.size() > 0)
Collections.sort(accounts, accounts.get(0).getComparator(context));
DiffUtil.DiffResult diff = DiffUtil.calculateDiff(new DiffCallback(items, accounts), false);
items = accounts;

View File

@ -34,13 +34,10 @@ import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView;
import java.text.Collator;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
public class AdapterNavFolder extends RecyclerView.Adapter<AdapterNavFolder.ViewHolder> {
@ -93,10 +90,10 @@ public class AdapterNavFolder extends RecyclerView.Adapter<AdapterNavFolder.View
? R.drawable.baseline_folder_24
: R.drawable.baseline_folder_open_24);
if (folder.color == null)
if (folder.accountColor == null)
ivItem.clearColorFilter();
else
ivItem.setColorFilter(folder.color);
ivItem.setColorFilter(folder.accountColor);
}
int count = (EntityFolder.OUTBOX.equals(folder.type) ? folder.operations : folder.unseen);
@ -141,25 +138,8 @@ public class AdapterNavFolder extends RecyclerView.Adapter<AdapterNavFolder.View
public void set(@NonNull List<TupleFolderNav> folders) {
Log.i("Set nav folders=" + folders.size());
final Collator collator = Collator.getInstance(Locale.getDefault());
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
Collections.sort(folders, new Comparator<TupleFolderNav>() {
@Override
public int compare(TupleFolderNav f1, TupleFolderNav f2) {
int s = Boolean.compare(EntityFolder.OUTBOX.equals(f1.type), EntityFolder.OUTBOX.equals(f2.type));
if (s != 0)
return s;
int o = Integer.compare(f1.order == null ? -1 : f1.order, f2.order == null ? -1 : f2.order);
if (o != 0)
return o;
String name1 = f1.getDisplayName(context);
String name2 = f2.getDisplayName(context);
return collator.compare(name1, name2);
}
});
if (folders.size() > 0)
Collections.sort(folders, folders.get(0).getComparator(context));
DiffUtil.DiffResult diff = DiffUtil.calculateDiff(new DiffCallback(items, folders), false);
@ -222,8 +202,9 @@ public class AdapterNavFolder extends RecyclerView.Adapter<AdapterNavFolder.View
return (f1.name.equals(f2.name) &&
f1.type.equals(f2.type) &&
Objects.equals(f1.display, f2.display) &&
Objects.equals(f1.color, f2.color) &&
Objects.equals(f1.accountColor, f2.accountColor) &&
Objects.equals(f1.state, f2.state) &&
Objects.equals(f1.sync_state, f2.sync_state) &&
f1.unseen == f2.unseen &&
f1.operations == f2.operations);
}

View File

@ -31,12 +31,9 @@ import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
public class AdapterOrder extends RecyclerView.Adapter<AdapterOrder.ViewHolder> {
@ -76,21 +73,8 @@ public class AdapterOrder extends RecyclerView.Adapter<AdapterOrder.ViewHolder>
public void set(@NonNull List<EntityOrder> items) {
Log.i("Set sort items=" + items.size());
final Collator collator = Collator.getInstance(Locale.getDefault());
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
Collections.sort(items, new Comparator<EntityOrder>() {
@Override
public int compare(EntityOrder s1, EntityOrder s2) {
int o = Integer.compare(s1.order == null ? -1 : s1.order, s2.order == null ? -1 : s2.order);
if (o != 0)
return o;
String name1 = s1.getSortKey(context);
String name2 = s2.getSortKey(context);
return collator.compare(name1, name2);
}
});
if (items.size() > 0)
Collections.sort(items, items.get(0).getComparator(context));
DiffUtil.DiffResult diff = DiffUtil.calculateDiff(new DiffCallback(this.items, items), false);

View File

@ -52,14 +52,14 @@ public interface DaoFolder {
EntityFolder getBrowsableFolder(long folder, boolean search);
@Query("SELECT folder.*" +
", account.name AS accountName" +
", account.`order` AS accountOrder, account.name AS accountName" +
" FROM folder" +
" JOIN account ON account.id = folder.account" +
" WHERE account.`synchronize`")
LiveData<List<TupleFolderSort>> liveSort();
@Query("SELECT folder.*" +
", account.name AS accountName, account.color AS accountColor, account.state AS accountState" +
", account.`order` AS accountOrder, account.name AS accountName, account.color AS accountColor, account.state AS accountState" +
", COUNT(message.id) AS messages" +
", SUM(CASE WHEN message.content = 1 THEN 1 ELSE 0 END) AS content" +
", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" +
@ -76,7 +76,7 @@ public interface DaoFolder {
LiveData<List<TupleFolderEx>> liveFolders(Long account, Long parent);
@Query("SELECT folder.*" +
", account.name AS accountName, account.color AS accountColor, account.state AS accountState" +
", account.`order` AS accountOrder, account.name AS accountName, account.color AS accountColor, account.state AS accountState" +
", COUNT(message.id) AS messages" +
", SUM(CASE WHEN message.content = 1 THEN 1 ELSE 0 END) AS content" +
", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" +
@ -90,7 +90,7 @@ public interface DaoFolder {
LiveData<List<TupleFolderEx>> liveUnified();
@Query("SELECT folder.*" +
", account.color" +
", account.`order` AS accountOrder, account.name AS accountName, account.color AS accountColor" +
", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" +
", (SELECT COUNT(*) FROM operation WHERE operation.folder = folder.id) AS operations" +
" FROM folder" +
@ -114,7 +114,7 @@ public interface DaoFolder {
LiveData<Integer> liveSynchronizing();
@Query("SELECT folder.*" +
", account.name AS accountName, account.color AS accountColor, account.state AS accountState" +
", account.`order` AS accountOrder, account.name AS accountName, account.color AS accountColor, account.state AS accountState" +
", COUNT(message.id) AS messages" +
", SUM(CASE WHEN message.content = 1 THEN 1 ELSE 0 END) AS content" +
", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" +

View File

@ -34,6 +34,9 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.io.Serializable;
import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;
import java.util.Objects;
@Entity(
@ -123,11 +126,6 @@ public class EntityAccount extends EntityOrder implements Serializable {
return id;
}
@Override
String getSortKey(Context context) {
return name;
}
@Override
String[] getSortTitle(Context context) {
return new String[]{name, null};
@ -238,6 +236,30 @@ public class EntityAccount extends EntityOrder implements Serializable {
return false;
}
@Override
Comparator getComparator(final Context context) {
final Collator collator = Collator.getInstance(Locale.getDefault());
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
return new Comparator() {
@Override
public int compare(Object o1, Object o2) {
EntityAccount a1 = (EntityAccount) o1;
EntityAccount a2 = (EntityAccount) o2;
int o = Integer.compare(
a1.order == null ? -1 : a1.order,
a2.order == null ? -1 : a2.order);
if (o != 0)
return o;
String name1 = (a1.name == null ? "" : a1.name);
String name2 = (a2.name == null ? "" : a2.name);
return collator.compare(name1, name2);
}
};
}
@NonNull
@Override
public String toString() {

View File

@ -234,11 +234,6 @@ public class EntityFolder extends EntityOrder implements Serializable {
return id;
}
@Override
String getSortKey(Context context) {
return getDisplayName(context);
}
@Override
String[] getSortTitle(Context context) {
return new String[]{getDisplayName(context), null};
@ -388,29 +383,37 @@ public class EntityFolder extends EntityOrder implements Serializable {
return folder;
}
static void sort(final Context context, List<EntityFolder> folders, final boolean menu) {
@Override
Comparator getComparator(final Context context) {
final Collator collator = Collator.getInstance(Locale.getDefault());
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
Collections.sort(folders, new Comparator<EntityFolder>() {
return new Comparator() {
@Override
public int compare(EntityFolder f1, EntityFolder f2) {
public int compare(Object o1, Object o2) {
EntityFolder f1 = (EntityFolder) o1;
EntityFolder f2 = (EntityFolder) o2;
int o = Integer.compare(
f1.order == null ? -1 : f1.order,
f2.order == null ? -1 : f2.order);
if (o != 0)
return o;
int i1 = EntityFolder.FOLDER_SORT_ORDER.indexOf(f1.type);
int i2 = EntityFolder.FOLDER_SORT_ORDER.indexOf(f2.type);
int s = Integer.compare(i1, i2);
if (s != 0)
return s;
if (!menu) {
int c = -f1.synchronize.compareTo(f2.synchronize);
if (c != 0)
return c;
}
int c = -f1.synchronize.compareTo(f2.synchronize);
if (c != 0)
return c;
String name1 = f1.getDisplayName(context);
String name2 = f2.getDisplayName(context);
return collator.compare(name1, name2);
}
});
};
}
}

View File

@ -21,12 +21,14 @@ package eu.faircode.email;
import android.content.Context;
import java.util.Comparator;
public abstract class EntityOrder {
public Integer order;
abstract Long getSortId();
abstract String getSortKey(Context context);
abstract String[] getSortTitle(Context context);
abstract Comparator getComparator(Context context);
}

View File

@ -75,6 +75,7 @@ import com.sun.mail.imap.protocol.IMAPProtocol;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@ -676,8 +677,9 @@ public class FragmentAccount extends FragmentBase {
for (EntityFolder folder : result.folders)
folder.display = folder.getDisplayName(getContext());
EntityFolder.sort(getContext(), result.folders, true);
if (result.folders.size() > 0)
Collections.sort(result.folders, result.folders.get(0).getComparator(context));
}
return result;
@ -1207,7 +1209,9 @@ public class FragmentAccount extends FragmentBase {
if (folders != null) {
for (EntityFolder folder : folders)
folder.display = folder.getDisplayName(getContext());
EntityFolder.sort(getContext(), folders, true);
if (folders.size() > 0)
Collections.sort(folders, folders.get(0).getComparator(context));
}
return folders;

View File

@ -101,6 +101,7 @@ import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
import static android.text.format.DateUtils.FORMAT_SHOW_WEEKDAY;
@ -1236,7 +1237,10 @@ public class FragmentMessages extends FragmentBase {
!EntityFolder.JUNK.equals(target.type) &&
(fids.size() != 1 || !fids.contains(target.id)))
targets.add(target);
EntityFolder.sort(context, targets, true);
if (targets.size() > 0)
Collections.sort(targets, targets.get(0).getComparator(context));
result.targets.put(account, targets);
}
@ -2892,7 +2896,7 @@ public class FragmentMessages extends FragmentBase {
if (snackbar.isShown())
snackbar.dismiss();
new Thread(new Runnable() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
DB db = DB.getInstance(context);
@ -2912,7 +2916,9 @@ public class FragmentMessages extends FragmentBase {
db.endTransaction();
}
}
}).start();
});
thread.setPriority(THREAD_PRIORITY_BACKGROUND);
thread.start();
}
}, UNDO_TIMEOUT);
}

View File

@ -47,6 +47,7 @@ public class FragmentOrder extends FragmentBase {
private ContentLoadingProgressBar pbWait;
private Group grpReady;
private boolean dirty = false;
private AdapterOrder adapter;
@Override
@ -133,45 +134,47 @@ public class FragmentOrder extends FragmentBase {
public void onPause() {
super.onPause();
List<EntityOrder> items = adapter.getItems();
if (dirty) {
List<EntityOrder> items = adapter.getItems();
List<Long> order = new ArrayList<>();
for (int i = 0; i < items.size(); i++)
order.add(items.get(i).getSortId());
List<Long> order = new ArrayList<>();
for (int i = 0; i < items.size(); i++)
order.add(items.get(i).getSortId());
Bundle args = new Bundle();
args.putString("class", clazz);
args.putLongArray("order", Helper.toLongArray(order));
Bundle args = new Bundle();
args.putString("class", clazz);
args.putLongArray("order", Helper.toLongArray(order));
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
final String clazz = args.getString("class");
final long[] order = args.getLongArray("order");
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
final String clazz = args.getString("class");
final long[] order = args.getLongArray("order");
final DB db = DB.getInstance(context);
db.runInTransaction(new Runnable() {
@Override
public void run() {
for (int i = 0; i < order.length; i++)
if (EntityAccount.class.getName().equals(clazz))
db.account().setAccountOrder(order[i], i);
else if (TupleFolderSort.class.getName().equals(clazz))
db.folder().setFolderOrder(order[i], i);
else
throw new IllegalArgumentException("Unknown class=" + clazz);
}
});
final DB db = DB.getInstance(context);
db.runInTransaction(new Runnable() {
@Override
public void run() {
for (int i = 0; i < order.length; i++)
if (EntityAccount.class.getName().equals(clazz))
db.account().setAccountOrder(order[i], i);
else if (TupleFolderSort.class.getName().equals(clazz))
db.folder().setFolderOrder(order[i], i);
else
throw new IllegalArgumentException("Unknown class=" + clazz);
}
});
return null;
}
return null;
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
}
}.execute(getContext(), getViewLifecycleOwner(), args, "order:set");
}
}.execute(getContext(), getViewLifecycleOwner(), args, "order:set");
}
}
@Override
@ -212,6 +215,11 @@ public class FragmentOrder extends FragmentBase {
return null;
}
@Override
protected void onExecuted(Bundle args, Void data) {
dirty = false;
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
@ -236,6 +244,7 @@ public class FragmentOrder extends FragmentBase {
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder source, @NonNull RecyclerView.ViewHolder target) {
dirty = true;
((AdapterOrder) rvOrder.getAdapter()).onMove(source.getAdapterPosition(), target.getAdapterPosition());
return true;
}

View File

@ -54,6 +54,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static android.app.Activity.RESULT_OK;
@ -302,7 +303,9 @@ public class FragmentRule extends FragmentBase {
for (EntityFolder folder : data.folders)
folder.display = folder.getDisplayName(context);
EntityFolder.sort(context, data.folders, true);
if (data.folders.size() > 0)
Collections.sort(data.folders, data.folders.get(0).getComparator(context));
data.identities = db.identity().getIdentities(aid);
data.answers = db.answer().getAnswers(false);

View File

@ -59,6 +59,8 @@ import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
public class ServiceSend extends LifecycleService {
private int lastUnsent = 0;
@ -244,6 +246,7 @@ public class ServiceSend extends LifecycleService {
}
}
});
thread.setPriority(THREAD_PRIORITY_BACKGROUND);
thread.start();
}
};
@ -446,6 +449,7 @@ public class ServiceSend extends LifecycleService {
}
}
});
thread.setPriority(THREAD_PRIORITY_BACKGROUND);
thread.start();
}
}

View File

@ -1152,7 +1152,7 @@ public class ServiceSynchronize extends LifecycleService {
if (started) {
EntityLog.log(ServiceSynchronize.this, "Checking account states");
new Thread(new Runnable() {
Thread check = new Thread(new Runnable() {
@Override
public void run() {
try {
@ -1183,7 +1183,9 @@ public class ServiceSynchronize extends LifecycleService {
Log.e(ex);
}
}
}).start();
});
check.setPriority(THREAD_PRIORITY_BACKGROUND);
check.start();
} else
queue_reload(true, false, "connect " + network);
} catch (Throwable ex) {
@ -1268,6 +1270,7 @@ public class ServiceSynchronize extends LifecycleService {
}
}
});
thread.setPriority(THREAD_PRIORITY_BACKGROUND);
thread.start();
}
}

View File

@ -19,10 +19,16 @@ package eu.faircode.email;
Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/
import android.content.Context;
import java.io.Serializable;
import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;
import java.util.Objects;
public class TupleFolderEx extends EntityFolder implements Serializable {
public Integer accountOrder;
public String accountName;
public Integer accountColor;
public String accountState;
@ -46,4 +52,40 @@ public class TupleFolderEx extends EntityFolder implements Serializable {
} else
return false;
}
@Override
Comparator getComparator(final Context context) {
final Collator collator = Collator.getInstance(Locale.getDefault());
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
final Comparator base = super.getComparator(context);
return new Comparator() {
@Override
public int compare(Object o1, Object o2) {
TupleFolderEx f1 = (TupleFolderEx) o1;
TupleFolderEx f2 = (TupleFolderEx) o2;
// Outbox
if (f1.accountName == null && f2.accountName == null)
return 0;
else if (f1.accountName == null)
return 1;
else if (f2.accountName == null)
return -1;
int o = Integer.compare(
f1.accountOrder == null ? -1 : f1.accountOrder,
f2.accountOrder == null ? -1 : f2.accountOrder);
if (o != 0)
return o;
int a = collator.compare(f1.accountName, f2.accountName);
if (a != 0)
return a;
return base.compare(o1, o2);
}
};
}
}

View File

@ -19,11 +19,53 @@ package eu.faircode.email;
Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/
import android.content.Context;
import java.io.Serializable;
import java.util.Objects;
import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;
public class TupleFolderNav extends EntityFolder implements Serializable {
public Integer color; // account
public Integer accountOrder;
public String accountName;
public Integer accountColor;
public int unseen;
public int operations;
@Override
Comparator getComparator(final Context context) {
final Collator collator = Collator.getInstance(Locale.getDefault());
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
final Comparator base = super.getComparator(context);
return new Comparator() {
@Override
public int compare(Object o1, Object o2) {
TupleFolderNav f1 = (TupleFolderNav) o1;
TupleFolderNav f2 = (TupleFolderNav) o2;
// Outbox
if (f1.accountName == null && f2.accountName == null)
return 0;
else if (f1.accountName == null)
return 1;
else if (f2.accountName == null)
return -1;
int o = Integer.compare(
f1.accountOrder == null ? -1 : f1.accountOrder,
f2.accountOrder == null ? -1 : f2.accountOrder);
if (o != 0)
return o;
int a = collator.compare(f1.accountName, f2.accountName);
if (a != 0)
return a;
return base.compare(o1, o2);
}
};
}
}

View File

@ -21,11 +21,52 @@ package eu.faircode.email;
import android.content.Context;
import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;
public class TupleFolderSort extends EntityFolder {
public Integer accountOrder;
public String accountName;
@Override
String[] getSortTitle(Context context) {
return new String[]{getDisplayName(context), accountName};
}
@Override
Comparator getComparator(final Context context) {
final Collator collator = Collator.getInstance(Locale.getDefault());
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
final Comparator base = super.getComparator(context);
return new Comparator() {
@Override
public int compare(Object o1, Object o2) {
TupleFolderSort f1 = (TupleFolderSort) o1;
TupleFolderSort f2 = (TupleFolderSort) o2;
// Outbox
if (f1.accountName == null && f2.accountName == null)
return 0;
else if (f1.accountName == null)
return 1;
else if (f2.accountName == null)
return -1;
int o = Integer.compare(
f1.accountOrder == null ? -1 : f1.accountOrder,
f2.accountOrder == null ? -1 : f2.accountOrder);
if (o != 0)
return o;
int a = collator.compare(f1.accountName, f2.accountName);
if (a != 0)
return a;
return base.compare(o1, o2);
}
};
}
}

View File

@ -27,16 +27,20 @@ import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
public class Widget extends AppWidgetProvider {
@Override
public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, final int[] appWidgetIds) {
new Thread(new Runnable() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
DB db = DB.getInstance(context);
update(appWidgetIds, appWidgetManager, context, db.message().getUnseenUnified());
}
}).start();
});
thread.setPriority(THREAD_PRIORITY_BACKGROUND);
thread.start();
}
static void update(Context context, int count) {