mirror of
https://github.com/M66B/FairEmail.git
synced 2025-02-23 14:41:08 +00:00
Added search suggestions
This commit is contained in:
parent
71706dc098
commit
24f28b05b5
4 changed files with 62 additions and 34 deletions
2
FAQ.md
2
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)
|
* ~~[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…
Reference in a new issue