mirror of
https://github.com/M66B/FairEmail.git
synced 2026-01-04 03:43:55 +01:00
Simplify searching
This commit is contained in:
@@ -500,49 +500,10 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
|
|||||||
intent.removeExtra(Intent.EXTRA_PROCESS_TEXT);
|
intent.removeExtra(Intent.EXTRA_PROCESS_TEXT);
|
||||||
setIntent(intent);
|
setIntent(intent);
|
||||||
|
|
||||||
if (Helper.isPro(ActivityView.this)) {
|
FragmentMessages.search(
|
||||||
Bundle args = new Bundle();
|
ActivityView.this, ActivityView.this,
|
||||||
args.putString("search", search);
|
getSupportFragmentManager(),
|
||||||
|
-1, search);
|
||||||
new SimpleTask<Long>() {
|
|
||||||
@Override
|
|
||||||
protected Long onExecute(Context context, Bundle args) {
|
|
||||||
DB db = DB.getInstance(context);
|
|
||||||
|
|
||||||
db.message().resetSearch();
|
|
||||||
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
|
||||||
if (prefs.getBoolean("search_local", false))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
EntityFolder archive = db.folder().getPrimaryArchive();
|
|
||||||
return (archive == null ? null : archive.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onExecuted(Bundle args, Long archive) {
|
|
||||||
Bundle sargs = new Bundle();
|
|
||||||
sargs.putLong("folder", archive == null ? -1 : archive);
|
|
||||||
sargs.putString("search", args.getString("search"));
|
|
||||||
|
|
||||||
FragmentMessages fragment = new FragmentMessages();
|
|
||||||
fragment.setArguments(sargs);
|
|
||||||
|
|
||||||
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
|
|
||||||
fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("search");
|
|
||||||
fragmentTransaction.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onException(Bundle args, Throwable ex) {
|
|
||||||
Helper.unexpectedError(ActivityView.this, ActivityView.this, ex);
|
|
||||||
}
|
|
||||||
}.execute(ActivityView.this, args, "search:account:archive");
|
|
||||||
} else {
|
|
||||||
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
|
|
||||||
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
|
|
||||||
fragmentTransaction.commit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ import javax.mail.search.SubjectTerm;
|
|||||||
|
|
||||||
public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMessageEx> {
|
public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMessageEx> {
|
||||||
private Context context;
|
private Context context;
|
||||||
private Long fid;
|
private Long folder;
|
||||||
private String searching;
|
private String searching;
|
||||||
private int pageSize;
|
private int pageSize;
|
||||||
private IBoundaryCallbackMessages intf;
|
private IBoundaryCallbackMessages intf;
|
||||||
@@ -100,7 +100,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
|
|||||||
IBoundaryCallbackMessages intf) {
|
IBoundaryCallbackMessages intf) {
|
||||||
|
|
||||||
this.context = context.getApplicationContext();
|
this.context = context.getApplicationContext();
|
||||||
this.fid = (folder < 0 ? null : folder);
|
this.folder = (folder < 0 ? null : folder);
|
||||||
this.searching = searching;
|
this.searching = searching;
|
||||||
this.pageSize = pageSize;
|
this.pageSize = pageSize;
|
||||||
this.intf = intf;
|
this.intf = intf;
|
||||||
@@ -179,28 +179,32 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
|
|||||||
return loading;
|
return loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
int load() throws MessagingException, IOException, AuthenticatorException, OperationCanceledException {
|
private int load() throws MessagingException, IOException, AuthenticatorException, OperationCanceledException {
|
||||||
if (error)
|
if (error)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DB db = DB.getInstance(context);
|
DB db = DB.getInstance(context);
|
||||||
|
|
||||||
int local = 0;
|
// Search local
|
||||||
if (searching != null)
|
int local_count = 0;
|
||||||
try {
|
try {
|
||||||
db.beginTransaction();
|
db.beginTransaction();
|
||||||
|
|
||||||
if (messages == null) {
|
if (messages == null) {
|
||||||
messages = db.message().getMessageIdsByFolder(fid);
|
messages = db.message().getMessageIdsByFolder(folder);
|
||||||
Log.i("Boundary search folder=" + fid + " messages=" + messages.size());
|
Log.i("Boundary search folder=" + folder + " messages=" + messages.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = local_index; i < messages.size() && local < pageSize; i++) {
|
for (int i = local_index; i < messages.size() && local_count < pageSize; i++) {
|
||||||
local_index = i + 1;
|
local_index = i + 1;
|
||||||
|
|
||||||
boolean match = false;
|
EntityMessage message = db.message().getMessage(messages.get(i));
|
||||||
|
|
||||||
|
boolean match = false;
|
||||||
|
if (searching == null)
|
||||||
|
match = true;
|
||||||
|
else {
|
||||||
String find = searching.toLowerCase();
|
String find = searching.toLowerCase();
|
||||||
EntityMessage message = db.message().getMessage(messages.get(i));
|
|
||||||
String body = null;
|
String body = null;
|
||||||
if (message.content)
|
if (message.content)
|
||||||
try {
|
try {
|
||||||
@@ -222,33 +226,41 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
|
|||||||
|
|
||||||
if (!match && message.content)
|
if (!match && message.content)
|
||||||
match = body.toLowerCase().contains(find);
|
match = body.toLowerCase().contains(find);
|
||||||
|
|
||||||
if (match) {
|
|
||||||
local++;
|
|
||||||
db.message().setMessageFound(message.account, message.thread);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
db.setTransactionSuccessful();
|
if (match) {
|
||||||
|
local_count++;
|
||||||
if (local == pageSize)
|
db.message().setMessageFound(message.account, message.thread);
|
||||||
return local;
|
}
|
||||||
} finally {
|
|
||||||
db.endTransaction();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fid == null)
|
db.setTransactionSuccessful();
|
||||||
return local;
|
|
||||||
|
|
||||||
final EntityFolder folder = db.folder().getBrowsableFolder(fid, searching != null);
|
if (local_count == pageSize)
|
||||||
if (folder == null)
|
return local_count;
|
||||||
return local;
|
} finally {
|
||||||
EntityAccount account = db.account().getAccount(folder.account);
|
db.endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search remote
|
||||||
|
long bid;
|
||||||
|
if (folder == null) {
|
||||||
|
EntityFolder archive = db.folder().getPrimaryArchive();
|
||||||
|
if (archive == null)
|
||||||
|
return local_count;
|
||||||
|
else
|
||||||
|
bid = archive.id;
|
||||||
|
} else
|
||||||
|
bid = folder;
|
||||||
|
|
||||||
|
final EntityFolder browsable = db.folder().getBrowsableFolder(bid, searching != null);
|
||||||
|
if (browsable == null)
|
||||||
|
return local_count;
|
||||||
|
EntityAccount account = db.account().getAccount(browsable.account);
|
||||||
if (account == null)
|
if (account == null)
|
||||||
return local;
|
return local_count;
|
||||||
|
|
||||||
if (imessages == null) {
|
|
||||||
|
|
||||||
|
if (imessages == null)
|
||||||
try {
|
try {
|
||||||
// Check connectivity
|
// Check connectivity
|
||||||
if (!Helper.getNetworkState(context).isSuitable())
|
if (!Helper.getNetworkState(context).isSuitable())
|
||||||
@@ -271,8 +283,8 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
|
|||||||
istore = (IMAPStore) isession.getStore(protocol);
|
istore = (IMAPStore) isession.getStore(protocol);
|
||||||
Helper.connect(context, istore, account);
|
Helper.connect(context, istore, account);
|
||||||
|
|
||||||
Log.i("Boundary opening folder=" + folder.name);
|
Log.i("Boundary opening folder=" + browsable.name);
|
||||||
ifolder = (IMAPFolder) istore.getFolder(folder.name);
|
ifolder = (IMAPFolder) istore.getFolder(browsable.name);
|
||||||
ifolder.open(Folder.READ_WRITE);
|
ifolder.open(Folder.READ_WRITE);
|
||||||
|
|
||||||
Log.i("Boundary searching=" + searching);
|
Log.i("Boundary searching=" + searching);
|
||||||
@@ -284,7 +296,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
|
|||||||
public Object doCommand(IMAPProtocol protocol) {
|
public Object doCommand(IMAPProtocol protocol) {
|
||||||
// Yahoo! does not support keyword search, but uses the flags $Forwarded $Junk $NotJunk
|
// Yahoo! does not support keyword search, but uses the flags $Forwarded $Junk $NotJunk
|
||||||
boolean keywords = false;
|
boolean keywords = false;
|
||||||
for (String keyword : folder.keywords)
|
for (String keyword : browsable.keywords)
|
||||||
if (!keyword.startsWith("$")) {
|
if (!keyword.startsWith("$")) {
|
||||||
keywords = true;
|
keywords = true;
|
||||||
break;
|
break;
|
||||||
@@ -388,14 +400,13 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
|
|||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int remote = 0;
|
int remote_count = 0;
|
||||||
while (remote_index >= 0 && remote < pageSize) {
|
while (remote_index >= 0 && remote_count < pageSize) {
|
||||||
Log.i("Boundary index=" + remote_index);
|
Log.i("Boundary index=" + remote_index);
|
||||||
int from = Math.max(0, remote_index - (pageSize - remote) + 1);
|
int from = Math.max(0, remote_index - (pageSize - remote_count) + 1);
|
||||||
Message[] isub = Arrays.copyOfRange(imessages, from, remote_index + 1);
|
Message[] isub = Arrays.copyOfRange(imessages, from, remote_index + 1);
|
||||||
remote_index -= (pageSize - remote);
|
remote_index -= (pageSize - remote_count);
|
||||||
|
|
||||||
FetchProfile fp = new FetchProfile();
|
FetchProfile fp = new FetchProfile();
|
||||||
fp.add(FetchProfile.Item.ENVELOPE);
|
fp.add(FetchProfile.Item.ENVELOPE);
|
||||||
@@ -414,29 +425,29 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
|
|||||||
try {
|
try {
|
||||||
long uid = ifolder.getUID(isub[j]);
|
long uid = ifolder.getUID(isub[j]);
|
||||||
Log.i("Boundary sync uid=" + uid);
|
Log.i("Boundary sync uid=" + uid);
|
||||||
EntityMessage message = db.message().getMessageByUid(folder.id, uid);
|
EntityMessage message = db.message().getMessageByUid(browsable.id, uid);
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
message = Core.synchronizeMessage(context,
|
message = Core.synchronizeMessage(context,
|
||||||
account, folder,
|
account, browsable,
|
||||||
ifolder, (IMAPMessage) isub[j],
|
ifolder, (IMAPMessage) isub[j],
|
||||||
true,
|
true,
|
||||||
new ArrayList<EntityRule>());
|
new ArrayList<EntityRule>());
|
||||||
remote++;
|
remote_count++;
|
||||||
}
|
}
|
||||||
db.message().setMessageFound(message.account, message.thread);
|
db.message().setMessageFound(message.account, message.thread);
|
||||||
} catch (MessageRemovedException ex) {
|
} catch (MessageRemovedException ex) {
|
||||||
Log.w(folder.name + " boundary", ex);
|
Log.w(browsable.name + " boundary", ex);
|
||||||
} catch (FolderClosedException ex) {
|
} catch (FolderClosedException ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
if (ex.getCause() instanceof MessagingException) {
|
if (ex.getCause() instanceof MessagingException) {
|
||||||
Log.w(folder.name + " boundary", ex);
|
Log.w(browsable.name + " boundary", ex);
|
||||||
db.folder().setFolderError(folder.id, Helper.formatThrowable(ex, true));
|
db.folder().setFolderError(browsable.id, Helper.formatThrowable(ex, true));
|
||||||
} else
|
} else
|
||||||
throw ex;
|
throw ex;
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
Log.e(folder.name + " boundary", ex);
|
Log.e(browsable.name + " boundary", ex);
|
||||||
db.folder().setFolderError(folder.id, Helper.formatThrowable(ex, true));
|
db.folder().setFolderError(browsable.id, Helper.formatThrowable(ex, true));
|
||||||
} finally {
|
} finally {
|
||||||
((IMAPMessage) isub[j]).invalidateHeaders();
|
((IMAPMessage) isub[j]).invalidateHeaders();
|
||||||
}
|
}
|
||||||
@@ -448,6 +459,6 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log.i("Boundary done");
|
Log.i("Boundary done");
|
||||||
return local + remote;
|
return local_count + remote_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,6 @@ import java.text.SimpleDateFormat;
|
|||||||
public class FragmentOptionsMisc extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class FragmentOptionsMisc extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
private SwitchCompat swBadge;
|
private SwitchCompat swBadge;
|
||||||
private SwitchCompat swSubscriptions;
|
private SwitchCompat swSubscriptions;
|
||||||
private SwitchCompat swSearchLocal;
|
|
||||||
private SwitchCompat swEnglish;
|
private SwitchCompat swEnglish;
|
||||||
private SwitchCompat swAuthentication;
|
private SwitchCompat swAuthentication;
|
||||||
private SwitchCompat swParanoid;
|
private SwitchCompat swParanoid;
|
||||||
@@ -60,7 +59,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
|
|||||||
private Group grpSearchLocal;
|
private Group grpSearchLocal;
|
||||||
|
|
||||||
private final static String[] RESET_OPTIONS = new String[]{
|
private final static String[] RESET_OPTIONS = new String[]{
|
||||||
"badge", "subscriptions", "search_local", "english", "authentication", "paranoid", "updates", "crash_reports", "debug"
|
"badge", "subscriptions", "english", "authentication", "paranoid", "updates", "crash_reports", "debug"
|
||||||
};
|
};
|
||||||
|
|
||||||
private final static String[] RESET_QUESTIONS = new String[]{
|
private final static String[] RESET_QUESTIONS = new String[]{
|
||||||
@@ -79,7 +78,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
|
|||||||
|
|
||||||
swBadge = view.findViewById(R.id.swBadge);
|
swBadge = view.findViewById(R.id.swBadge);
|
||||||
swSubscriptions = view.findViewById(R.id.swSubscriptions);
|
swSubscriptions = view.findViewById(R.id.swSubscriptions);
|
||||||
swSearchLocal = view.findViewById(R.id.swSearchLocal);
|
|
||||||
swEnglish = view.findViewById(R.id.swEnglish);
|
swEnglish = view.findViewById(R.id.swEnglish);
|
||||||
swAuthentication = view.findViewById(R.id.swAuthentication);
|
swAuthentication = view.findViewById(R.id.swAuthentication);
|
||||||
swParanoid = view.findViewById(R.id.swParanoid);
|
swParanoid = view.findViewById(R.id.swParanoid);
|
||||||
@@ -113,13 +111,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
swSearchLocal.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
|
|
||||||
prefs.edit().putBoolean("search_local", checked).apply();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
swEnglish.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
swEnglish.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
|
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
|
||||||
@@ -234,7 +225,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
|
|||||||
|
|
||||||
swBadge.setChecked(prefs.getBoolean("badge", true));
|
swBadge.setChecked(prefs.getBoolean("badge", true));
|
||||||
swSubscriptions.setChecked(prefs.getBoolean("subscriptions", false));
|
swSubscriptions.setChecked(prefs.getBoolean("subscriptions", false));
|
||||||
swSearchLocal.setChecked(prefs.getBoolean("search_local", false));
|
|
||||||
swEnglish.setChecked(prefs.getBoolean("english", false));
|
swEnglish.setChecked(prefs.getBoolean("english", false));
|
||||||
swAuthentication.setChecked(prefs.getBoolean("authentication", false));
|
swAuthentication.setChecked(prefs.getBoolean("authentication", false));
|
||||||
swParanoid.setChecked(prefs.getBoolean("paranoid", true));
|
swParanoid.setChecked(prefs.getBoolean("paranoid", true));
|
||||||
|
|||||||
@@ -73,28 +73,6 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tvSubscriptionsHint" />
|
app:layout_constraintTop_toBottomOf="@id/tvSubscriptionsHint" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
|
||||||
android:id="@+id/swSearchLocal"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:text="@string/title_advanced_search_local"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/tvNotifyPreviewPro"
|
|
||||||
app:switchPadding="12dp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tvSearchLocalHint"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="48dp"
|
|
||||||
android:text="@string/title_advanced_search_local_hint"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
|
||||||
android:textStyle="italic"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/swSearchLocal" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
<androidx.appcompat.widget.SwitchCompat
|
||||||
android:id="@+id/swEnglish"
|
android:id="@+id/swEnglish"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -102,7 +80,7 @@
|
|||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:text="@string/title_advanced_english"
|
android:text="@string/title_advanced_english"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tvSearchLocalHint"
|
app:layout_constraintTop_toBottomOf="@id/tvNotifyPreviewPro"
|
||||||
app:switchPadding="12dp" />
|
app:switchPadding="12dp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
@@ -219,7 +219,6 @@
|
|||||||
|
|
||||||
<string name="title_advanced_badge">Show launcher icon with number of new messages</string>
|
<string name="title_advanced_badge">Show launcher icon with number of new messages</string>
|
||||||
<string name="title_advanced_subscriptions">Manage folder subscriptions</string>
|
<string name="title_advanced_subscriptions">Manage folder subscriptions</string>
|
||||||
<string name="title_advanced_search_local">External search on device</string>
|
|
||||||
<string name="title_advanced_english">Force English language</string>
|
<string name="title_advanced_english">Force English language</string>
|
||||||
<string name="title_advanced_authentication">Show a warning when the receiving server could not authenticate the message</string>
|
<string name="title_advanced_authentication">Show a warning when the receiving server could not authenticate the message</string>
|
||||||
<string name="title_advanced_paranoid">Extra privacy features</string>
|
<string name="title_advanced_paranoid">Extra privacy features</string>
|
||||||
@@ -247,7 +246,6 @@
|
|||||||
<string name="title_advanced_sender_hint">Most providers do not allow modified sender addresses</string>
|
<string name="title_advanced_sender_hint">Most providers do not allow modified sender addresses</string>
|
||||||
|
|
||||||
<string name="title_advanced_badge_hint">Only available on supported launchers</string>
|
<string name="title_advanced_badge_hint">Only available on supported launchers</string>
|
||||||
<string name="title_advanced_search_local_hint">Instead of searching in the primary archive folder on the server</string>
|
|
||||||
<string name="title_advanced_english_hint">This will restart the app</string>
|
<string name="title_advanced_english_hint">This will restart the app</string>
|
||||||
<string name="title_advanced_paranoid_hint">See the FAQ for details</string>
|
<string name="title_advanced_paranoid_hint">See the FAQ for details</string>
|
||||||
<string name="title_advanced_debug_hint">Enable extra logging and show debug information at various places</string>
|
<string name="title_advanced_debug_hint">Enable extra logging and show debug information at various places</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user