diff --git a/app/src/main/java/eu/faircode/email/AdapterKeyword.java b/app/src/main/java/eu/faircode/email/AdapterKeyword.java index fc2a272195..cdbf21907d 100644 --- a/app/src/main/java/eu/faircode/email/AdapterKeyword.java +++ b/app/src/main/java/eu/faircode/email/AdapterKeyword.java @@ -55,7 +55,7 @@ public class AdapterKeyword extends RecyclerView.Adapter all = new ArrayList<>(); public class ViewHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener, View.OnClickListener { @@ -113,24 +113,33 @@ public class AdapterKeyword extends RecyclerView.Adapter() { @Override protected Void onExecute(Context context, Bundle args) { - long id = args.getLong("id"); + long[] ids = args.getLongArray("ids"); String name = args.getString("name"); boolean set = args.getBoolean("set"); DB db = DB.getInstance(context); - EntityMessage message = db.message().getMessage(id); - if (message == null) - return null; + try { + db.beginTransaction(); - EntityOperation.queue(context, message, EntityOperation.KEYWORD, name, set); + if (ids != null) + for (long id : ids) { + EntityMessage message = db.message().getMessage(id); + if (message != null) + EntityOperation.queue(context, message, EntityOperation.KEYWORD, name, set); + } + + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } return null; } @@ -245,12 +254,12 @@ public class AdapterKeyword extends RecyclerView.Adapter keywords) { - Log.i("Set id=" + id + " keywords=" + keywords.size()); + public void set(long[] ids, @NonNull List keywords) { + Log.i("Set ids=" + ids.length + " keywords=" + keywords.size()); DiffUtil.DiffResult diff = DiffUtil.calculateDiff(new DiffCallback(all, keywords), false); - this.id = id; + this.ids = ids; this.all = keywords; diff.dispatchUpdatesTo(new ListUpdateCallback() { diff --git a/app/src/main/java/eu/faircode/email/AdapterMessage.java b/app/src/main/java/eu/faircode/email/AdapterMessage.java index 209834870f..9a15ea6947 100644 --- a/app/src/main/java/eu/faircode/email/AdapterMessage.java +++ b/app/src/main/java/eu/faircode/email/AdapterMessage.java @@ -7516,7 +7516,7 @@ public class AdapterMessage extends RecyclerView.Adapter() { - @Override - public void onChanged(TupleKeyword.Persisted data) { - if (data == null) - data = new TupleKeyword.Persisted(); - - String global = prefs.getString("global_keywords", null); - if (global != null) { - List available = new ArrayList<>(); - if (data.available != null) - available.addAll(Arrays.asList(data.available)); - for (String kw : global.split(" ")) - if (!available.contains(kw)) - available.add(kw); - data.available = available.toArray(new String[0]); + long[] ids = args.getLongArray("ids"); + if (ids.length == 1) { + DB db = DB.getInstance(context); + db.message().liveMessageKeywords(ids[0]).observe(getViewLifecycleOwner(), new Observer() { + @Override + public void onChanged(TupleKeyword.Persisted data) { + if (data == null) + data = new TupleKeyword.Persisted(); + + pbWait.setVisibility(View.GONE); + adapter.set(ids, TupleKeyword.from(context, data)); } - - pbWait.setVisibility(View.GONE); - adapter.set(id, TupleKeyword.from(context, data)); - } - }); + }); + } else { + task.execute(context, getViewLifecycleOwner(), args, "keywords:get"); + } return new AlertDialog.Builder(context) .setIcon(R.drawable.twotone_label_important_24) @@ -114,4 +110,51 @@ public class FragmentDialogKeywordManage extends FragmentDialogBase { dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); //dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); } + + @Override + public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + task.execute(getContext(), getViewLifecycleOwner(), getArguments(), "keywords:get"); + } + + final SimpleTask task = new SimpleTask() { + @Override + protected TupleKeyword.Persisted onExecute(Context context, Bundle args) { + long[] ids = args.getLongArray("ids"); + + List selected = new ArrayList<>(); + List available = new ArrayList<>(); + + DB db = DB.getInstance(context); + if (ids != null) + for (long id : ids) { + TupleKeyword.Persisted kws = db.message().getMessageKeywords(id); + List list = (kws == null || kws.selected == null + ? Collections.emptyList() : Arrays.asList(kws.selected)); + if (id == ids[0]) // First + selected.addAll(list); + else // Check if all message have all keywords + for (String kw : new ArrayList<>(selected)) + if (!list.contains(kw)) + selected.remove(kw); + + if (kws != null && kws.available != null) + for (String kw : kws.available) + if (!available.contains(kw)) + available.add(kw); + } + + return new TupleKeyword.Persisted(selected, available); + } + + @Override + protected void onExecuted(Bundle args, TupleKeyword.Persisted data) { + pbWait.setVisibility(View.GONE); + adapter.set(args.getLongArray("ids"), TupleKeyword.from(getContext(), data)); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Log.unexpectedError(getParentFragmentManager(), ex); + } + }; } diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index 61620db9af..3ba2ba317d 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -449,6 +449,7 @@ public class FragmentMessages extends FragmentBase static final int REQUEST_CALENDAR = 29; static final int REQUEST_EDIT_SUBJECT = 30; private static final int REQUEST_ANSWER_SETTINGS = 31; + private static final int REQUEST_DESELECT = 32; static final String ACTION_STORE_RAW = BuildConfig.APPLICATION_ID + ".STORE_RAW"; static final String ACTION_VERIFYDECRYPT = BuildConfig.APPLICATION_ID + ".VERIFYDECRYPT"; @@ -5202,122 +5203,11 @@ public class FragmentMessages extends FragmentBase Bundle args = new Bundle(); args.putLongArray("ids", getSelection()); - new SimpleTask, List>>() { - @Override - protected Pair, List> onExecute(Context context, Bundle args) { - long[] ids = args.getLongArray("ids"); - - List selected = new ArrayList<>(); - List available = new ArrayList<>(); - - DB db = DB.getInstance(context); - if (ids != null) - for (long id : ids) { - TupleKeyword.Persisted kws = db.message().getMessageKeywords(id); - List list = (kws == null || kws.selected == null - ? Collections.emptyList() : Arrays.asList(kws.selected)); - if (id == ids[0]) // First - selected.addAll(list); - else // Check if all message have all keywords - for (String kw : new ArrayList<>(selected)) - if (!list.contains(kw)) - selected.remove(kw); - - if (kws != null && kws.available != null) - for (String kw : kws.available) - if (!available.contains(kw)) - available.add(kw); - } - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - String global = prefs.getString("global_keywords", null); - if (global != null) - for (String kw : global.split(" ")) - if (!available.contains(kw)) - available.add(kw); - - final Collator collator = Collator.getInstance(Locale.getDefault()); - collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc - - Collections.sort(available, collator); - - return new Pair<>(selected, available); - } - - @Override - protected void onExecuted(Bundle args, Pair, List> data) { - boolean[] checked = new boolean[data.second.size()]; - for (int i = 0; i < checked.length; i++) - if (data.first.contains(data.second.get(i))) - checked[i] = true; - - new AlertDialog.Builder(getContext()) - .setIcon(R.drawable.twotone_label_important_24) - .setTitle(R.string.title_manage_keywords) - .setMultiChoiceItems(data.second.toArray(new String[0]), checked, new DialogInterface.OnMultiChoiceClickListener() { - @Override - public void onClick(DialogInterface dialog, int which, boolean isChecked) { - args.putString("keyword", data.second.get(which)); - args.putBoolean("set", isChecked); - - new SimpleTask() { - @Override - protected Void onExecute(Context context, Bundle args) { - long[] ids = args.getLongArray("ids"); - String keyword = args.getString("keyword"); - boolean set = args.getBoolean("set"); - - DB db = DB.getInstance(context); - try { - db.beginTransaction(); - - if (ids != null) - for (long id : ids) { - EntityMessage message = db.message().getMessage(id); - if (message != null) - EntityOperation.queue(context, message, EntityOperation.KEYWORD, keyword, set); - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - - return null; - } - - @Override - protected void onException(Bundle args, Throwable ex) { - Log.unexpectedError(getParentFragmentManager(), ex); - } - }.execute(FragmentMessages.this, args, "keywords:set"); - } - }) - .setNegativeButton(R.string.title_setup_done, null) - .setNeutralButton(R.string.title_add, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - FragmentDialogKeywordAdd fragment = new FragmentDialogKeywordAdd(); - fragment.setArguments(args); - fragment.show(getParentFragmentManager(), "keywords:add"); - } - }) - .setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - if (clear && selectionTracker != null) - selectionTracker.clearSelection(); - - } - }) - .show(); - } - - @Override - protected void onException(Bundle args, Throwable ex) { - Log.unexpectedError(getParentFragmentManager(), ex); - } - }.execute(FragmentMessages.this, args, "keywords:get"); + FragmentDialogKeywordManage fragment = new FragmentDialogKeywordManage(); + fragment.setArguments(args); + if (clear) + fragment.setTargetFragment(FragmentMessages.this, REQUEST_DESELECT); + fragment.show(getParentFragmentManager(), "keyword:manage"); } private void onActionMoveSelection(Bundle args) { @@ -9558,6 +9448,10 @@ public class FragmentMessages extends FragmentBase if (resultCode == RESULT_OK) updateAnswerIcon(); break; + case REQUEST_DESELECT: + if (selectionTracker != null) + selectionTracker.clearSelection(); + break; } } catch (Throwable ex) { Log.e(ex); diff --git a/app/src/main/java/eu/faircode/email/TupleKeyword.java b/app/src/main/java/eu/faircode/email/TupleKeyword.java index 8e6f701c9a..2e2233025f 100644 --- a/app/src/main/java/eu/faircode/email/TupleKeyword.java +++ b/app/src/main/java/eu/faircode/email/TupleKeyword.java @@ -55,6 +55,16 @@ public class TupleKeyword { public static class Persisted { public String[] selected; public String[] available; + + public Persisted() { + selected = new String[0]; + available = new String[0]; + } + + public Persisted(List selected, List available) { + this.selected = selected.toArray(new String[0]); + this.available = available.toArray(new String[0]); + } } static List from(Context context, Persisted data) { @@ -78,6 +88,12 @@ public class TupleKeyword { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + String global = prefs.getString("global_keywords", null); + if (global != null) + for (String kw : global.split(" ")) + if (!all.contains(kw)) + all.add(kw); + final Collator collator = Collator.getInstance(Locale.getDefault()); collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc