diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitDebugLogActivity.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitDebugLogActivity.java
index b8dcc3e480..87de54ae48 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitDebugLogActivity.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitDebugLogActivity.java
@@ -61,11 +61,14 @@ public class SubmitDebugLogActivity extends BaseActivity {
private MenuItem searchMenuItem;
private MenuItem saveMenuItem;
- private ImageButton caseSensitiveButton;
- private TextView searchPosition;
- private ImageButton searchUpButton;
- private ImageButton searchDownButton;
+ private ImageButton filterButton;
+ private ImageButton caseSensitiveButton;
+ private TextView searchPosition;
+ private ImageButton searchUpButton;
+ private ImageButton searchDownButton;
+ private boolean isCaseSensitive;
+ private boolean isFiltered;
private boolean isWebViewLoaded;
private boolean hasPresentedLines;
@@ -101,6 +104,7 @@ public class SubmitDebugLogActivity extends BaseActivity {
this.saveMenuItem = menu.findItem(R.id.menu_save);
this.searchNav = findViewById(R.id.debug_log_search_nav);
+ this.filterButton = findViewById(R.id.debug_log_filter);
this.caseSensitiveButton = findViewById(R.id.case_sensitive_button);
this.searchPosition = findViewById(R.id.debug_log_search_position);
this.searchUpButton = findViewById(R.id.debug_log_search_up);
@@ -116,17 +120,34 @@ public class SubmitDebugLogActivity extends BaseActivity {
DebugLogsViewer.getSearchPosition(logWebView, position -> searchPosition.setText(position));
});
- boolean[] isCaseSensitive = {false};
-
caseSensitiveButton.setOnClickListener(v -> {
DebugLogsViewer.onToggleCaseSensitive(logWebView);
DebugLogsViewer.getSearchPosition(logWebView, position -> searchPosition.setText(position));
- isCaseSensitive[0] = !isCaseSensitive[0];
+ isCaseSensitive = !isCaseSensitive;
- int backgroundColor = isCaseSensitive[0] ? R.drawable.circle_tint_darker : R.drawable.circle_touch_highlight_background;
+ int backgroundColor = isCaseSensitive ? R.drawable.circle_tint_darker : R.drawable.circle_touch_highlight_background;
caseSensitiveButton.setBackground(getResources().getDrawable(backgroundColor));
});
+ filterButton.setOnClickListener(v -> {
+ isFiltered = !isFiltered;
+ if (isFiltered) {
+ DebugLogsViewer.onFilter(logWebView);
+ searchPosition.setVisibility(View.GONE);
+ searchUpButton.setVisibility(View.GONE);
+ searchDownButton.setVisibility(View.GONE);
+ filterButton.setBackground(getResources().getDrawable(R.drawable.circle_tint_darker));
+ } else {
+ DebugLogsViewer.onFilterClose(logWebView);
+ searchPosition.setVisibility(View.VISIBLE);
+ searchUpButton.setVisibility(View.VISIBLE);
+ searchDownButton.setVisibility(View.VISIBLE);
+ DebugLogsViewer.getSearchPosition(logWebView, position -> searchPosition.setText(position));
+ DebugLogsViewer.scrollToTop(logWebView);
+ filterButton.setBackground(getResources().getDrawable(R.drawable.circle_touch_highlight_background));
+ }
+ });
+
SearchView searchView = (SearchView) searchMenuItem.getActionView();
SearchView.OnQueryTextListener queryListener = new SearchView.OnQueryTextListener() {
@Override
@@ -136,8 +157,13 @@ public class SubmitDebugLogActivity extends BaseActivity {
@Override
public boolean onQueryTextChange(String query) {
- DebugLogsViewer.onSearch(logWebView, query);
- DebugLogsViewer.getSearchPosition(logWebView, position -> searchPosition.setText(position));
+ DebugLogsViewer.onSearchInput(logWebView, query);
+ if (isFiltered) {
+ DebugLogsViewer.onFilter(logWebView);
+ } else {
+ DebugLogsViewer.onSearch(logWebView);
+ DebugLogsViewer.getSearchPosition(logWebView, position -> searchPosition.setText(position));
+ }
return true;
}
};
@@ -156,6 +182,7 @@ public class SubmitDebugLogActivity extends BaseActivity {
searchNav.setVisibility(View.GONE);
submitButton.setVisibility(View.VISIBLE);
DebugLogsViewer.onSearchClose(logWebView);
+ DebugLogsViewer.onFilterClose(logWebView);
DebugLogsViewer.getSearchPosition(logWebView, position -> searchPosition.setText(position));
searchView.setOnQueryTextListener(null);
return true;
diff --git a/app/src/main/res/layout/submit_debug_log_activity.xml b/app/src/main/res/layout/submit_debug_log_activity.xml
index 2e692fb3e0..1c1157a711 100644
--- a/app/src/main/res/layout/submit_debug_log_activity.xml
+++ b/app/src/main/res/layout/submit_debug_log_activity.xml
@@ -98,16 +98,33 @@
app:layout_constraintBottom_toBottomOf="parent"
tools:visibility="visible">
+
+
diff --git a/debuglogs-viewer/lib/src/main/assets/debuglogs-viewer.js b/debuglogs-viewer/lib/src/main/assets/debuglogs-viewer.js
index 5887192e5b..1eaf9b7f99 100644
--- a/debuglogs-viewer/lib/src/main/assets/debuglogs-viewer.js
+++ b/debuglogs-viewer/lib/src/main/assets/debuglogs-viewer.js
@@ -52,11 +52,13 @@ editor.session.on("changeScrollLeft", showScrollBar);
const Range = ace.require("ace/range").Range;
const session = editor.getSession();
+let logLines = ""; // Original logLines
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;
+let isFiltered = false;
// Clear all search markers and match info
function clearMarkers() {
@@ -139,10 +141,34 @@ function onSearchClose() {
function onToggleCaseSensitive() {
isCaseSensitive = !isCaseSensitive;
- highlightAllMatches(input);
+ (isFiltered) ? onFilter() : highlightAllMatches(input);
}
function onSearchInput(value) {
input = value;
+}
+
+function onSearch() {
highlightAllMatches(input);
}
+
+function onFilter() {
+ isFiltered = true;
+ editor.getSelection().clearSelection();
+ clearMarkers();
+ const filtered = logLines
+ .split("\n")
+ .filter((line) => {
+ const newLine = isCaseSensitive ? line : line.toLowerCase();
+ return newLine.includes(isCaseSensitive ? input : input.toLowerCase());
+ })
+ .join("\n");
+
+ editor.setValue(filtered, -1);
+}
+
+function onFilterClose() {
+ isFiltered = false;
+ editor.setValue(logLines, -1);
+ highlightAllMatches(input);
+}
\ No newline at end of file
diff --git a/debuglogs-viewer/lib/src/main/java/org/signal/debuglogsviewer/DebugLogsViewer.kt b/debuglogs-viewer/lib/src/main/java/org/signal/debuglogsviewer/DebugLogsViewer.kt
index 388cbe2766..2168cf43a6 100644
--- a/debuglogs-viewer/lib/src/main/java/org/signal/debuglogsviewer/DebugLogsViewer.kt
+++ b/debuglogs-viewer/lib/src/main/java/org/signal/debuglogsviewer/DebugLogsViewer.kt
@@ -47,7 +47,7 @@ object DebugLogsViewer {
fun presentLines(webview: WebView, lines: String) {
// Set the debug log lines
val escaped = JSONObject.quote(lines)
- webview.evaluateJavascript("editor.insert($escaped);", null)
+ webview.evaluateJavascript("editor.insert($escaped); logLines=$escaped;", null)
}
@JvmStatic
@@ -61,10 +61,25 @@ object DebugLogsViewer {
}
@JvmStatic
- fun onSearch(webview: WebView, query: String) {
+ fun onSearchInput(webview: WebView, query: String) {
webview.evaluateJavascript("onSearchInput('$query')", null)
}
+ @JvmStatic
+ fun onSearch(webview: WebView) {
+ webview.evaluateJavascript("onSearch()", null)
+ }
+
+ @JvmStatic
+ fun onFilter(webview: WebView) {
+ webview.evaluateJavascript("onFilter()", null)
+ }
+
+ @JvmStatic
+ fun onFilterClose(webview: WebView) {
+ webview.evaluateJavascript("onFilterClose()", null)
+ }
+
@JvmStatic
fun onSearchUp(webview: WebView) {
webview.evaluateJavascript("onSearchUp();", null)
@@ -90,10 +105,6 @@ object DebugLogsViewer {
webview.evaluateJavascript("onSearchClose();", null)
}
- @JvmStatic
- fun onFilter(webview: WebView) {
- }
-
@JvmStatic
fun onEdit(webview: WebView) {
readOnly = !readOnly