Added search suggestions

pull/157/head
M66B 6 years ago
parent 71706dc098
commit 24f28b05b5

@ -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) * ~~[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 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) * ~~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. Anything on this list is in random order and *might* be added in the near future.

@ -19,6 +19,8 @@ package eu.faircode.email;
Copyright 2018-2019 by Marcel Bokhorst (M66B) Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/ */
import android.database.Cursor;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.paging.DataSource; import androidx.paging.DataSource;
import androidx.room.Dao; import androidx.room.Dao;
@ -305,10 +307,15 @@ public interface DaoMessage {
@Query("SELECT * FROM message WHERE NOT ui_snoozed IS NULL") @Query("SELECT * FROM message WHERE NOT ui_snoozed IS NULL")
List<EntityMessage> getSnoozed(); List<EntityMessage> getSnoozed();
@Query("SELECT id, `from`, avatar FROM message" + @Query("SELECT id AS _id, subject AS suggestion FROM message" +
" WHERE folder = :folder" + " WHERE subject LIKE :query" +
" AND received >= :before") " GROUP BY subject" +
List<TupleMessageLookup> getAvatars(long folder, long before); " 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 @Insert
long insertMessage(EntityMessage message); long insertMessage(EntityMessage message);

@ -30,6 +30,7 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.IntentSender; import android.content.IntentSender;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
@ -80,6 +81,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu; import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView;
import androidx.constraintlayout.widget.Group; import androidx.constraintlayout.widget.Group;
import androidx.cursoradapter.widget.SimpleCursorAdapter;
import androidx.documentfile.provider.DocumentFile; import androidx.documentfile.provider.DocumentFile;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
@ -2242,7 +2244,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
inflater.inflate(R.menu.menu_messages, menu); inflater.inflate(R.menu.menu_messages, menu);
final MenuItem menuSearch = menu.findItem(R.id.menu_search); 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)); searchView.setQueryHint(getString(R.string.title_search));
if (!TextUtils.isEmpty(searching)) { if (!TextUtils.isEmpty(searching)) {
@ -2254,6 +2256,39 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
searching = newText; searching = newText;
Bundle args = new Bundle();
args.putString("query", newText);
new SimpleTask<Cursor>() {
@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; 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); menu.findItem(R.id.menu_folders).setActionView(R.layout.action_button);
ImageButton ib = (ImageButton) menu.findItem(R.id.menu_folders).getActionView(); ImageButton ib = (ImageButton) menu.findItem(R.id.menu_folders).getActionView();
ib.setOnClickListener(new View.OnClickListener() { ib.setOnClickListener(new View.OnClickListener() {

@ -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 <http://www.gnu.org/licenses/>.
Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/
import javax.mail.Address;
public class TupleMessageLookup {
public long id;
public Address[] from;
public String avatar;
}
Loading…
Cancel
Save