diff --git a/app/src/main/java/eu/faircode/email/AdapterAnswer.java b/app/src/main/java/eu/faircode/email/AdapterAnswer.java index 81ffc1ef82..7db60d0978 100644 --- a/app/src/main/java/eu/faircode/email/AdapterAnswer.java +++ b/app/src/main/java/eu/faircode/email/AdapterAnswer.java @@ -48,10 +48,14 @@ import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.ListUpdateCallback; import androidx.recyclerview.widget.RecyclerView; +import java.text.Collator; import java.text.DateFormat; import java.text.NumberFormat; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; +import java.util.Locale; public class AdapterAnswer extends RecyclerView.Adapter { private Fragment parentFragment; @@ -63,6 +67,7 @@ public class AdapterAnswer extends RecyclerView.Adapter all = new ArrayList<>(); private List selected = new ArrayList<>(); @@ -313,8 +318,39 @@ public class AdapterAnswer extends RecyclerView.Adapter answers) { - Log.i("Set answers=" + answers.size() + " search=" + search); + public void set(String sort, @NonNull List answers) { + this.sort = sort; + Log.i("Set answers=" + answers.size() + " sort=" + sort + " search=" + search); + + final Collator collator = Collator.getInstance(Locale.getDefault()); + collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc + + Collections.sort(answers, new Comparator() { + @Override + public int compare(EntityAnswer a1, EntityAnswer a2) { + int order; + if ("last_applied".equals(sort)) + order = -Long.compare( + a1.last_applied == null ? 0 : a1.last_applied, + a2.last_applied == null ? 0 : a2.last_applied); + else if ("applied".equals(sort)) { + order = -Integer.compare( + a1.applied == null ? 0 : a1.applied, + a2.applied == null ? 0 : a2.applied); + } else { + order = collator.compare(a1.group == null ? "" : a1.group, a2.group == null ? "" : a2.group); + if (order == 0) + order = -Boolean.compare(a1.favorite, a2.favorite); + } + + if (order == 0) + return collator.compare( + a1.name == null ? "" : a1.name, + a2.name == null ? "" : a2.name); + else + return order; + } + }); all = answers; @@ -365,10 +401,16 @@ public class AdapterAnswer extends RecyclerView.Adapter> liveAnswers(); @Query("SELECT COUNT(*) FROM answer" + diff --git a/app/src/main/java/eu/faircode/email/FragmentAnswers.java b/app/src/main/java/eu/faircode/email/FragmentAnswers.java index 7e51f41c12..e509e33d02 100644 --- a/app/src/main/java/eu/faircode/email/FragmentAnswers.java +++ b/app/src/main/java/eu/faircode/email/FragmentAnswers.java @@ -106,6 +106,8 @@ public class FragmentAnswers extends FragmentBase { rvAnswer.addItemDecoration(itemDecorator); } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + DividerItemDecoration categoryDecorator = new DividerItemDecoration(getContext(), llm.getOrientation()) { @Override public void onDraw(@NonNull Canvas canvas, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { @@ -141,6 +143,10 @@ public class FragmentAnswers extends FragmentBase { if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) return null; + String sort = prefs.getString("answer_sort", "name"); + if ("last_applied".equals(sort) || "applied".equals(sort)) + return null; + EntityAnswer prev = adapter.getItemAtPosition(pos - 1); EntityAnswer account = adapter.getItemAtPosition(pos); if (pos > 0 && prev == null) @@ -212,14 +218,18 @@ public class FragmentAnswers extends FragmentBase { searching = savedInstanceState.getString("fair:searching"); adapter.search(searching); - DB db = DB.getInstance(getContext()); + final Context context = getContext(); + DB db = DB.getInstance(context); db.answer().liveAnswers().observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(List answers) { if (answers == null) answers = new ArrayList<>(); - adapter.set(answers); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + String sort = prefs.getString("answer_sort", "name"); + + adapter.set(sort, answers); pbWait.setVisibility(View.GONE); grpReady.setVisibility(View.VISIBLE); @@ -279,6 +289,16 @@ public class FragmentAnswers extends FragmentBase { } }); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + String sort = prefs.getString("answer_sort", "order"); + + if ("last_applied".equals(sort)) + menu.findItem(R.id.menu_sort_on_last_applied).setChecked(true); + else if ("applied".equals(sort)) + menu.findItem(R.id.menu_sort_on_applied).setChecked(true); + else + menu.findItem(R.id.menu_sort_on_name).setChecked(true); + Menu smenu = menu.findItem(R.id.menu_placeholders).getSubMenu(); List names = EntityAnswer.getCustomPlaceholders(getContext()); @@ -291,19 +311,38 @@ public class FragmentAnswers extends FragmentBase { @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (item.getGroupId() == Menu.FIRST) { - onDefine(item.getTitle().toString()); + onMenuDefine(item.getTitle().toString()); return true; } else { - int id = item.getItemId(); - if (id == R.id.menu_define) { - onDefine(null); + int itemId = item.getItemId(); + if (itemId == R.id.menu_sort_on_name) { + item.setChecked(true); + onMenuSort("name"); + return true; + } else if (itemId == R.id.menu_sort_on_applied) { + item.setChecked(true); + onMenuSort("applied"); + return true; + } else if (itemId == R.id.menu_sort_on_last_applied) { + item.setChecked(true); + onMenuSort("last_applied"); + return true; + } else if (itemId == R.id.menu_define) { + onMenuDefine(null); return true; } else return super.onOptionsItemSelected(item); } } - private void onDefine(String name) { + private void onMenuSort(String sort) { + final Context context = getContext(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + prefs.edit().putString("answer_sort", sort).apply(); + adapter.setSort(sort); + } + + private void onMenuDefine(String name) { final Context context = getContext(); View view = LayoutInflater.from(context).inflate(R.layout.dialog_placeholder, null); final EditText etName = view.findViewById(R.id.etName); diff --git a/app/src/main/res/menu/menu_answers.xml b/app/src/main/res/menu/menu_answers.xml index 508ffcec4c..2e5ddd3559 100644 --- a/app/src/main/res/menu/menu_answers.xml +++ b/app/src/main/res/menu/menu_answers.xml @@ -8,6 +8,26 @@ app:actionViewClass="androidx.appcompat.widget.SearchView" app:showAsAction="collapseActionView|always" /> + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3b6a318866..c7ef39f85e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1766,6 +1766,7 @@ Hidden Oldest first + Name Order Applied count Last applied