diff --git a/FAQ.md b/FAQ.md index 7f343c5457..1dcb713c01 100644 --- a/FAQ.md +++ b/FAQ.md @@ -44,7 +44,7 @@ For authorizing: * ~~[ManageSieve](https://tools.ietf.org/html/rfc5804)~~ (there are no maintained Java libraries with a suitable license and without dependencies and besides that, FairEmail has its own filter rules) * ~~Search for messages with/without attachments~~ (this cannot be added because IMAP doesn't support searching for attachments) * ~~Search for a folder~~ (filtering a hierarchical folder list is problematic) -* Seach history +* ~~Search suggestions~~ Anything on this list is in random order and *might* be added in the near future. diff --git a/app/src/main/java/eu/faircode/email/DaoMessage.java b/app/src/main/java/eu/faircode/email/DaoMessage.java index 8b1c8aa87a..e4ccd0a1fa 100644 --- a/app/src/main/java/eu/faircode/email/DaoMessage.java +++ b/app/src/main/java/eu/faircode/email/DaoMessage.java @@ -19,6 +19,8 @@ package eu.faircode.email; Copyright 2018-2019 by Marcel Bokhorst (M66B) */ +import android.database.Cursor; + import androidx.lifecycle.LiveData; import androidx.paging.DataSource; import androidx.room.Dao; @@ -305,10 +307,15 @@ public interface DaoMessage { @Query("SELECT * FROM message WHERE NOT ui_snoozed IS NULL") List getSnoozed(); - @Query("SELECT id, `from`, avatar FROM message" + - " WHERE folder = :folder" + - " AND received >= :before") - List getAvatars(long folder, long before); + @Query("SELECT id AS _id, subject AS suggestion FROM message" + + " WHERE subject LIKE :query" + + " GROUP BY subject" + + " UNION" + + " SELECT id AS _id, sender AS suggestion FROM message" + + " WHERE sender LIKE :query" + + " GROUP BY sender" + + " ORDER BY sender, subject") + Cursor getSuggestions(String query); @Insert long insertMessage(EntityMessage message); diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index d10ef55490..93fe2eb03e 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -30,6 +30,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.IntentSender; import android.content.SharedPreferences; +import android.database.Cursor; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.PorterDuff; @@ -80,6 +81,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.PopupMenu; import androidx.appcompat.widget.SearchView; import androidx.constraintlayout.widget.Group; +import androidx.cursoradapter.widget.SimpleCursorAdapter; import androidx.documentfile.provider.DocumentFile; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; @@ -2242,7 +2244,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. inflater.inflate(R.menu.menu_messages, menu); final MenuItem menuSearch = menu.findItem(R.id.menu_search); - SearchView searchView = (SearchView) menuSearch.getActionView(); + final SearchView searchView = (SearchView) menuSearch.getActionView(); searchView.setQueryHint(getString(R.string.title_search)); if (!TextUtils.isEmpty(searching)) { @@ -2254,6 +2256,39 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. @Override public boolean onQueryTextChange(String newText) { searching = newText; + + Bundle args = new Bundle(); + args.putString("query", newText); + + new SimpleTask() { + @Override + protected Cursor onExecute(Context context, Bundle args) { + String query = args.getString("query"); + + DB db = DB.getInstance(context); + return db.message().getSuggestions("%" + query + "%"); + } + + @Override + protected void onExecuted(Bundle args, Cursor cursor) { + Log.i("Suggestions=" + cursor.getCount()); + SimpleCursorAdapter adapter = new SimpleCursorAdapter( + getContext(), + android.R.layout.simple_list_item_1, + cursor, + new String[]{"suggestion"}, + new int[]{android.R.id.text1}, + 0); + searchView.setSuggestionsAdapter(adapter); + adapter.notifyDataSetChanged(); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Helper.unexpectedError(getFragmentManager(), ex); + } + }.execute(FragmentMessages.this, args, "messages:suggestions"); + return true; } @@ -2268,6 +2303,20 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. } }); + searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() { + @Override + public boolean onSuggestionSelect(int position) { + return false; + } + + @Override + public boolean onSuggestionClick(int position) { + Cursor cursor = (Cursor) searchView.getSuggestionsAdapter().getItem(position); + searchView.setQuery(cursor.getString(1), true); + return false; + } + }); + menu.findItem(R.id.menu_folders).setActionView(R.layout.action_button); ImageButton ib = (ImageButton) menu.findItem(R.id.menu_folders).getActionView(); ib.setOnClickListener(new View.OnClickListener() { diff --git a/app/src/main/java/eu/faircode/email/TupleMessageLookup.java b/app/src/main/java/eu/faircode/email/TupleMessageLookup.java deleted file mode 100644 index 9018a1b326..0000000000 --- a/app/src/main/java/eu/faircode/email/TupleMessageLookup.java +++ /dev/null @@ -1,28 +0,0 @@ -package eu.faircode.email; - -/* - This file is part of FairEmail. - - FairEmail is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - FairEmail is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with FairEmail. If not, see . - - Copyright 2018-2019 by Marcel Bokhorst (M66B) -*/ - -import javax.mail.Address; - -public class TupleMessageLookup { - public long id; - public Address[] from; - public String avatar; -}