diff --git a/app/src/main/java/eu/faircode/email/AdapterRule.java b/app/src/main/java/eu/faircode/email/AdapterRule.java index 66e86e5d6a..823b466683 100644 --- a/app/src/main/java/eu/faircode/email/AdapterRule.java +++ b/app/src/main/java/eu/faircode/email/AdapterRule.java @@ -56,6 +56,7 @@ import org.json.JSONObject; import java.io.IOException; import java.text.NumberFormat; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import javax.mail.MessagingException; @@ -67,7 +68,9 @@ public class AdapterRule extends RecyclerView.Adapter { private LayoutInflater inflater; private int protocol = -1; - private List items = new ArrayList<>(); + private String search = null; + private List all = new ArrayList<>(); + private List selected = new ArrayList<>(); public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { private View view; @@ -189,7 +192,7 @@ public class AdapterRule extends RecyclerView.Adapter { if (pos == RecyclerView.NO_POSITION) return; - TupleRuleEx rule = items.get(pos); + TupleRuleEx rule = selected.get(pos); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); lbm.sendBroadcast( @@ -206,7 +209,7 @@ public class AdapterRule extends RecyclerView.Adapter { if (pos == RecyclerView.NO_POSITION) return false; - final TupleRuleEx rule = items.get(pos); + final TupleRuleEx rule = selected.get(pos); PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, powner, view); @@ -417,9 +420,37 @@ public class AdapterRule extends RecyclerView.Adapter { this.protocol = protocol; Log.i("Set protocol=" + protocol + " rules=" + rules.size()); - DiffUtil.DiffResult diff = DiffUtil.calculateDiff(new DiffCallback(items, rules), false); + all = rules; - items = rules; + List items; + if (TextUtils.isEmpty(search)) + items = all; + else { + items = new ArrayList<>(); + String query = search.toLowerCase().trim(); + for (TupleRuleEx rule : rules) { + if (rule.name.toLowerCase().contains(query)) + items.add(rule); + else + try { + JSONObject jcondition = new JSONObject(rule.condition); + Iterator keys = jcondition.keys(); + while (keys.hasNext()) { + String key = keys.next(); + if (jcondition.get(key).toString().toLowerCase().contains(query)) { + items.add(rule); + break; + } + } + } catch (JSONException ex) { + Log.e(ex); + } + } + } + + DiffUtil.DiffResult diff = DiffUtil.calculateDiff(new DiffCallback(selected, items), false); + + selected = items; diff.dispatchUpdatesTo(new ListUpdateCallback() { @Override @@ -445,6 +476,11 @@ public class AdapterRule extends RecyclerView.Adapter { diff.dispatchUpdatesTo(this); } + public void search(String query) { + search = query; + set(protocol, all); + } + private class DiffCallback extends DiffUtil.Callback { private List prev = new ArrayList<>(); private List next = new ArrayList<>(); @@ -481,12 +517,12 @@ public class AdapterRule extends RecyclerView.Adapter { @Override public long getItemId(int position) { - return items.get(position).id; + return selected.get(position).id; } @Override public int getItemCount() { - return items.size(); + return selected.size(); } @Override @@ -498,7 +534,7 @@ public class AdapterRule extends RecyclerView.Adapter { @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { holder.unwire(); - TupleRuleEx rule = items.get(position); + TupleRuleEx rule = selected.get(position); holder.bindTo(rule); holder.wire(); } diff --git a/app/src/main/java/eu/faircode/email/FragmentRules.java b/app/src/main/java/eu/faircode/email/FragmentRules.java index c14e1dde30..2fce10635a 100644 --- a/app/src/main/java/eu/faircode/email/FragmentRules.java +++ b/app/src/main/java/eu/faircode/email/FragmentRules.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -32,6 +33,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.widget.SearchView; import androidx.constraintlayout.widget.Group; import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentTransaction; @@ -64,6 +66,7 @@ public class FragmentRules extends FragmentBase { private Group grpReady; private FloatingActionButton fab; + private String searching = null; private AdapterRule adapter; static final int REQUEST_MOVE = 1; @@ -141,10 +144,21 @@ public class FragmentRules extends FragmentBase { return view; } + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putString("fair:searching", searching); + super.onSaveInstanceState(outState); + } + @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); + if (savedInstanceState != null) { + searching = savedInstanceState.getString("fair:searching"); + adapter.search(searching); + } + DB db = DB.getInstance(getContext()); db.rule().liveRules(folder).observe(getViewLifecycleOwner(), new Observer>() { @Override @@ -183,6 +197,32 @@ public class FragmentRules extends FragmentBase { @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.menu_rules, menu); + + MenuItem menuSearch = menu.findItem(R.id.menu_search); + SearchView searchView = (SearchView) menuSearch.getActionView(); + searchView.setQueryHint(getString(R.string.title_search)); + + if (!TextUtils.isEmpty(searching)) { + menuSearch.expandActionView(); + searchView.setQuery(searching, true); + } + + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextChange(String newText) { + searching = newText; + adapter.search(newText); + return true; + } + + @Override + public boolean onQueryTextSubmit(String query) { + searching = query; + adapter.search(query); + return true; + } + }); + super.onCreateOptionsMenu(menu, inflater); } diff --git a/app/src/main/res/menu/menu_rules.xml b/app/src/main/res/menu/menu_rules.xml index 9d1654d9b6..cc5c1db3cd 100644 --- a/app/src/main/res/menu/menu_rules.xml +++ b/app/src/main/res/menu/menu_rules.xml @@ -1,6 +1,13 @@ + +