mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-25 05:27:42 +00:00
Add search functionality to debug log screen.
This commit is contained in:
committed by
Cody Henthorne
parent
962375e422
commit
5e0aa830bf
@@ -9,6 +9,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
#container { position: absolute; top: 0; bottom: 0; left: 0; right: 0; height: 100%; width: 100%; }
|
||||
.searchMatches { position: absolute; background-color: rgba(182, 190, 250, 0.4); }
|
||||
|
||||
/* Scrollbar Setup */
|
||||
.ace_scrollbar::-webkit-scrollbar { width: 0; height: 0; }
|
||||
|
||||
@@ -47,3 +47,102 @@ function showScrollBar() {
|
||||
|
||||
editor.session.on("changeScrollTop", showScrollBar);
|
||||
editor.session.on("changeScrollLeft", showScrollBar);
|
||||
|
||||
// Generate highlight markers for all search matches
|
||||
const Range = ace.require("ace/range").Range;
|
||||
const session = editor.getSession();
|
||||
|
||||
let input = ""; // Search query input
|
||||
let markers = []; // IDs of highlighted search markers
|
||||
let matchRanges = []; // Ranges of all search matches
|
||||
let matchCount = 0; // Total number of matches
|
||||
let isCaseSensitive = false;
|
||||
|
||||
// Clear all search markers and match info
|
||||
function clearMarkers() {
|
||||
markers.forEach((id) => session.removeMarker(id));
|
||||
markers = [];
|
||||
matchRanges = [];
|
||||
matchCount = 0;
|
||||
}
|
||||
|
||||
// Highlight all instances of the search term
|
||||
function highlightAllMatches(term) {
|
||||
clearMarkers();
|
||||
if (!term) {
|
||||
return;
|
||||
}
|
||||
|
||||
const searchTerm = isCaseSensitive ? term : term.toLowerCase();
|
||||
session
|
||||
.getDocument()
|
||||
.getAllLines()
|
||||
.forEach((line, row) => {
|
||||
let start = 0;
|
||||
const caseLine = isCaseSensitive ? line : line.toLowerCase();
|
||||
while (true) {
|
||||
const index = caseLine.indexOf(searchTerm, start);
|
||||
if (index === -1) {
|
||||
break;
|
||||
}
|
||||
const range = new Range(row, index, row, index + term.length);
|
||||
markers.push(session.addMarker(range, "searchMatches", "text", false));
|
||||
matchRanges.push(range);
|
||||
start = index + term.length;
|
||||
}
|
||||
});
|
||||
matchCount = markers.length;
|
||||
}
|
||||
|
||||
// Return index of current match
|
||||
function getCurrentMatchIndex() {
|
||||
const current = editor.getSelection().getRange();
|
||||
return matchRanges.findIndex(
|
||||
(r) =>
|
||||
r.start.row === current.start.row &&
|
||||
r.start.column === current.start.column &&
|
||||
r.end.row === current.end.row &&
|
||||
r.end.column === current.end.column,
|
||||
);
|
||||
}
|
||||
|
||||
function getSearchPosition() {
|
||||
if (input == "") {
|
||||
return "";
|
||||
}
|
||||
return matchCount == 0 ? "No match" : `${getCurrentMatchIndex() + 1} of ${matchCount}`;
|
||||
}
|
||||
|
||||
function onSearchUp() {
|
||||
editor.find(input, {
|
||||
backwards: true,
|
||||
wrap: true,
|
||||
skipCurrent: true,
|
||||
caseSensitive: isCaseSensitive,
|
||||
});
|
||||
}
|
||||
|
||||
function onSearchDown() {
|
||||
editor.find(input, {
|
||||
backwards: false,
|
||||
wrap: true,
|
||||
skipCurrent: true,
|
||||
caseSensitive: isCaseSensitive,
|
||||
});
|
||||
}
|
||||
|
||||
function onSearchClose() {
|
||||
editor.getSelection().clearSelection();
|
||||
input = "";
|
||||
clearMarkers();
|
||||
}
|
||||
|
||||
function onToggleCaseSensitive() {
|
||||
isCaseSensitive = !isCaseSensitive;
|
||||
highlightAllMatches(input);
|
||||
}
|
||||
|
||||
function onSearchInput(value) {
|
||||
input = value;
|
||||
highlightAllMatches(input);
|
||||
}
|
||||
|
||||
@@ -9,10 +9,12 @@ import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.webkit.ValueCallback
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import kotlinx.coroutines.Runnable
|
||||
import org.json.JSONObject
|
||||
import java.util.function.Consumer
|
||||
|
||||
var readOnly = true
|
||||
|
||||
@@ -59,13 +61,37 @@ object DebugLogsViewer {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onFind(webview: WebView) {
|
||||
webview.evaluateJavascript("document.getElementById('searchBar').style.display = 'block';", null)
|
||||
fun onSearch(webview: WebView, query: String) {
|
||||
webview.evaluateJavascript("onSearchInput('$query')", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onSearchUp(webview: WebView) {
|
||||
webview.evaluateJavascript("onSearchUp();", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onSearchDown(webview: WebView) {
|
||||
webview.evaluateJavascript("onSearchDown();", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getSearchPosition(webView: WebView, callback: Consumer<String?>) {
|
||||
webView.evaluateJavascript("getSearchPosition();", ValueCallback { value: String? -> callback.accept(value?.trim('"') ?: "") })
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onToggleCaseSensitive(webview: WebView) {
|
||||
webview.evaluateJavascript("onToggleCaseSensitive();", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onSearchClose(webview: WebView) {
|
||||
webview.evaluateJavascript("onSearchClose();", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onFilter(webview: WebView) {
|
||||
webview.evaluateJavascript("document.getElementById('filterLevel').style.display = 'block';", null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
Reference in New Issue
Block a user