Highlight found text

pull/194/merge
M66B 4 years ago
parent 99acb26b69
commit d29ab53dec

@ -1866,6 +1866,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
args.putInt("lpos", intent.getIntExtra("lpos", -1)); args.putInt("lpos", intent.getIntExtra("lpos", -1));
args.putBoolean("filter_archive", intent.getBooleanExtra("filter_archive", true)); args.putBoolean("filter_archive", intent.getBooleanExtra("filter_archive", true));
args.putBoolean("found", found); args.putBoolean("found", found);
args.putString("searched", intent.getStringExtra("searched"));
args.putBoolean("pinned", intent.getBooleanExtra("pinned", false)); args.putBoolean("pinned", intent.getBooleanExtra("pinned", false));
args.putString("msgid", intent.getStringExtra("msgid")); args.putString("msgid", intent.getStringExtra("msgid"));

@ -203,6 +203,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
private Fragment parentFragment; private Fragment parentFragment;
private String type; private String type;
private boolean found; private boolean found;
private String searched;
private ViewType viewType; private ViewType viewType;
private boolean compact; private boolean compact;
private int zoom; private int zoom;
@ -2540,6 +2541,9 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
HtmlHelper.cleanup(document); HtmlHelper.cleanup(document);
HtmlHelper.removeRelativeLinks(document); HtmlHelper.removeRelativeLinks(document);
if (!TextUtils.isEmpty(searched))
HtmlHelper.highlightSearched(context, document, searched);
// Check for inline encryption // Check for inline encryption
boolean iencrypted = HtmlHelper.contains(document, new String[]{ boolean iencrypted = HtmlHelper.contains(document, new String[]{
Helper.PGP_BEGIN_MESSAGE, Helper.PGP_BEGIN_MESSAGE,
@ -3529,7 +3533,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
.putExtra("id", message.id) .putExtra("id", message.id)
.putExtra("lpos", getAdapterPosition()) .putExtra("lpos", getAdapterPosition())
.putExtra("filter_archive", !EntityFolder.ARCHIVE.equals(message.folderType)) .putExtra("filter_archive", !EntityFolder.ARCHIVE.equals(message.folderType))
.putExtra("found", viewType == ViewType.SEARCH); .putExtra("found", viewType == ViewType.SEARCH)
.putExtra("searched", searched);
boolean doubletap = prefs.getBoolean("doubletap", true); boolean doubletap = prefs.getBoolean("doubletap", true);
@ -5894,13 +5899,14 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
} }
AdapterMessage(Fragment parentFragment, AdapterMessage(Fragment parentFragment,
String type, boolean found, ViewType viewType, String type, boolean found, String searched, ViewType viewType,
boolean compact, int zoom, String sort, boolean ascending, boolean compact, int zoom, String sort, boolean ascending,
boolean filter_duplicates, boolean filter_trash, boolean filter_duplicates, boolean filter_trash,
final IProperties properties) { final IProperties properties) {
this.parentFragment = parentFragment; this.parentFragment = parentFragment;
this.type = type; this.type = type;
this.found = found; this.found = found;
this.searched = searched;
this.viewType = viewType; this.viewType = viewType;
this.compact = compact; this.compact = compact;
this.zoom = zoom; this.zoom = zoom;

@ -290,6 +290,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
private int lpos; private int lpos;
private boolean filter_archive; private boolean filter_archive;
private boolean found; private boolean found;
private String searched;
private boolean pinned; private boolean pinned;
private String msgid; private String msgid;
private BoundaryCallbackMessages.SearchCriteria criteria = null; private BoundaryCallbackMessages.SearchCriteria criteria = null;
@ -413,9 +414,12 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
lpos = args.getInt("lpos", RecyclerView.NO_POSITION); lpos = args.getInt("lpos", RecyclerView.NO_POSITION);
filter_archive = args.getBoolean("filter_archive", true); filter_archive = args.getBoolean("filter_archive", true);
found = args.getBoolean("found", false); found = args.getBoolean("found", false);
searched = args.getString("searched");
pinned = args.getBoolean("pinned", false); pinned = args.getBoolean("pinned", false);
msgid = args.getString("msgid"); msgid = args.getString("msgid");
criteria = (BoundaryCallbackMessages.SearchCriteria) args.getSerializable("criteria"); criteria = (BoundaryCallbackMessages.SearchCriteria) args.getSerializable("criteria");
if (criteria != null)
searched = criteria.query;
pane = args.getBoolean("pane", false); pane = args.getBoolean("pane", false);
primary = args.getLong("primary", -1); primary = args.getLong("primary", -1);
connected = args.getBoolean("connected", false); connected = args.getBoolean("connected", false);
@ -849,7 +853,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
filter_trash = false; filter_trash = false;
adapter = new AdapterMessage( adapter = new AdapterMessage(
this, type, found, viewType, this, type, found, searched, viewType,
compact, zoom, sort, ascending, compact, zoom, sort, ascending,
filter_duplicates, filter_trash, filter_duplicates, filter_trash,
iProperties); iProperties);
@ -5921,6 +5925,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
else else
nargs.putInt("lpos", forward ^ reversed ? lpos + 1 : lpos - 1); nargs.putInt("lpos", forward ^ reversed ? lpos + 1 : lpos - 1);
nargs.putBoolean("found", found); nargs.putBoolean("found", found);
nargs.putString("searched", searched);
nargs.putBoolean("pane", pane); nargs.putBoolean("pane", pane);
nargs.putLong("primary", primary); nargs.putLong("primary", primary);
nargs.putBoolean("connected", connected); nargs.putBoolean("connected", connected);

@ -36,6 +36,7 @@ import android.os.Build;
import android.text.Html; import android.text.Html;
import android.text.Layout; import android.text.Layout;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.Spanned; import android.text.Spanned;
import android.text.TextDirectionHeuristics; import android.text.TextDirectionHeuristics;
@ -2400,6 +2401,56 @@ public class HtmlHelper {
return ssb; return ssb;
} }
static Document highlightSearched(Context context, Document document, String searched) {
String find = searched.toLowerCase();
int color = Helper.resolveColor(context, R.attr.colorHighlight);
NodeTraversor.traverse(new NodeVisitor() {
@Override
public void head(Node node, int depth) {
if (node instanceof TextNode) {
TextNode tnode = (TextNode) node;
String text = tnode.getWholeText();
int start = text.toLowerCase().indexOf(find);
if (start < 0)
return;
int prev = 0;
Element holder = document.createElement("span");
while (start >= 0) {
if (start > prev)
holder.appendText(text.substring(prev, start));
Element span = document.createElement("span");
span.attr("style", mergeStyles(
span.attr("style"),
"font-size:larger; background-color:" + encodeWebColor(color)
));
span.text(text.substring(start, start + find.length()));
holder.appendChild(span);
prev = start + find.length();
start = text.toLowerCase().indexOf(find, prev);
}
if (prev < text.length())
holder.appendText(text.substring(prev));
tnode.before(holder);
tnode.text("");
}
}
@Override
public void tail(Node node, int depth) {
}
}, document);
return document;
}
static void cleanup(Document d) { static void cleanup(Document d) {
// https://www.chromestatus.com/feature/5756335865987072 // https://www.chromestatus.com/feature/5756335865987072
// Some messages contain 100 thousands of Apple spaces // Some messages contain 100 thousands of Apple spaces

Loading…
Cancel
Save