Add filter by log level feature in debug log screen.

This commit is contained in:
lisa-signal
2025-08-08 13:04:13 -04:00
committed by Greyson Parrelli
parent e93f889115
commit c0f826808b
8 changed files with 284 additions and 114 deletions

View File

@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.logsubmit;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.content.res.ColorStateList;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.text.SpannableString; import android.text.SpannableString;
@@ -20,6 +21,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ShareCompat; import androidx.core.app.ShareCompat;
import androidx.core.content.ContextCompat;
import androidx.core.text.util.LinkifyCompat; import androidx.core.text.util.LinkifyCompat;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@@ -49,15 +51,12 @@ public class SubmitDebugLogActivity extends BaseActivity {
private SubmitDebugLogViewModel viewModel; private SubmitDebugLogViewModel viewModel;
private View warningBanner; private View warningBanner;
private View editBanner;
private CircularProgressMaterialButton submitButton; private CircularProgressMaterialButton submitButton;
private ConversationSearchBottomBar searchNav; private ConversationSearchBottomBar searchNav;
private View scrollToBottomButton; private View scrollToBottomButton;
private View scrollToTopButton; private View scrollToTopButton;
private ProgressCard progressCard; private ProgressCard progressCard;
private MenuItem editMenuItem;
private MenuItem doneMenuItem;
private MenuItem searchMenuItem; private MenuItem searchMenuItem;
private MenuItem saveMenuItem; private MenuItem saveMenuItem;
@@ -67,8 +66,21 @@ public class SubmitDebugLogActivity extends BaseActivity {
private ImageButton searchUpButton; private ImageButton searchUpButton;
private ImageButton searchDownButton; private ImageButton searchDownButton;
private TextView uncaughtButton;
private TextView verboseButton;
private TextView debugButton;
private TextView infoButton;
private TextView warningButton;
private TextView errorButton;
private boolean isCaseSensitive; private boolean isCaseSensitive;
private boolean isFiltered; private boolean isFiltered;
private boolean isUncaught;
private boolean isVerbose;
private boolean isDebug;
private boolean isInfo;
private boolean isWarning;
private boolean isError;
private boolean isWebViewLoaded; private boolean isWebViewLoaded;
private boolean hasPresentedLines; private boolean hasPresentedLines;
@@ -98,8 +110,6 @@ public class SubmitDebugLogActivity extends BaseActivity {
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.submit_debug_log_normal, menu); getMenuInflater().inflate(R.menu.submit_debug_log_normal, menu);
this.editMenuItem = menu.findItem(R.id.menu_edit_log);
this.doneMenuItem = menu.findItem(R.id.menu_done_editing_log);
this.searchMenuItem = menu.findItem(R.id.menu_search); this.searchMenuItem = menu.findItem(R.id.menu_search);
this.saveMenuItem = menu.findItem(R.id.menu_save); this.saveMenuItem = menu.findItem(R.id.menu_save);
@@ -110,6 +120,13 @@ public class SubmitDebugLogActivity extends BaseActivity {
this.searchUpButton = findViewById(R.id.debug_log_search_up); this.searchUpButton = findViewById(R.id.debug_log_search_up);
this.searchDownButton = findViewById(R.id.debug_log_search_down); this.searchDownButton = findViewById(R.id.debug_log_search_down);
this.uncaughtButton = findViewById(R.id.debug_log_signalUncaughtException);
this.verboseButton = findViewById(R.id.debug_log_verbose);
this.debugButton = findViewById(R.id.debug_log_debug);
this.infoButton = findViewById(R.id.debug_log_info);
this.warningButton = findViewById(R.id.debug_log_warning);
this.errorButton = findViewById(R.id.debug_log_error);
searchUpButton.setOnClickListener(v -> { searchUpButton.setOnClickListener(v -> {
DebugLogsViewer.onSearchUp(logWebView); DebugLogsViewer.onSearchUp(logWebView);
DebugLogsViewer.getSearchPosition(logWebView, position -> searchPosition.setText(position)); DebugLogsViewer.getSearchPosition(logWebView, position -> searchPosition.setText(position));
@@ -179,6 +196,7 @@ public class SubmitDebugLogActivity extends BaseActivity {
@Override @Override
public boolean onMenuItemActionCollapse(MenuItem item) { public boolean onMenuItemActionCollapse(MenuItem item) {
onFilterLevelClose();
searchNav.setVisibility(View.GONE); searchNav.setVisibility(View.GONE);
submitButton.setVisibility(View.VISIBLE); submitButton.setVisibility(View.VISIBLE);
DebugLogsViewer.onSearchClose(logWebView); DebugLogsViewer.onSearchClose(logWebView);
@@ -189,6 +207,37 @@ public class SubmitDebugLogActivity extends BaseActivity {
} }
}); });
verboseButton.setOnClickListener(v -> {
isVerbose = !isVerbose;
onFilterLevel(v, isVerbose);
});
debugButton.setOnClickListener(v -> {
isDebug = !isDebug;
onFilterLevel(v, isDebug);
});
infoButton.setOnClickListener(v -> {
isInfo = !isInfo;
onFilterLevel(v, isInfo);
});
warningButton.setOnClickListener(v -> {
isWarning = !isWarning;
onFilterLevel(v, isWarning);
});
errorButton.setOnClickListener(v -> {
isError = !isError;
onFilterLevel(v, isError);
});
uncaughtButton.setOnClickListener(v -> {
isUncaught = !isUncaught;
onFilterLevel(v, isUncaught);
});
if (viewModel.getMode().getValue() != null) { if (viewModel.getMode().getValue() != null) {
presentMode(viewModel.getMode().getValue()); presentMode(viewModel.getMode().getValue());
} }
@@ -196,6 +245,38 @@ public class SubmitDebugLogActivity extends BaseActivity {
return true; return true;
} }
private void onFilterLevel(View view, boolean isChecked) {
view.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(this, (isChecked) ? R.color.transparent_black_25 : R.color.signal_background_secondary)));
List<String> selectedLevels = new ArrayList<>();
if (isVerbose) selectedLevels.add("\" V \"");
if (isDebug) selectedLevels.add("\" D \"");
if (isInfo) selectedLevels.add("\" I \"");
if (isWarning) selectedLevels.add("\" W \"");
if (isError) selectedLevels.add("\" E \"");
if (isUncaught) selectedLevels.add("\" SignalUncaughtException:\"");
DebugLogsViewer.onFilterLevel(logWebView, "[" + String.join(",", selectedLevels) + "]");
DebugLogsViewer.getSearchPosition(logWebView, position -> searchPosition.setText(position));
}
private void onFilterLevelClose() {
isVerbose = false;
isDebug = false;
isInfo = false;
isWarning = false;
isError = false;
isUncaught = false;
verboseButton.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(this, R.color.signal_background_secondary)));
debugButton.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(this, R.color.signal_background_secondary)));
infoButton.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(this, R.color.signal_background_secondary)));
warningButton.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(this, R.color.signal_background_secondary)));
errorButton.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(this, R.color.signal_background_secondary)));
uncaughtButton.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(this, R.color.signal_background_secondary)));
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item); super.onOptionsItemSelected(item);
@@ -203,10 +284,6 @@ public class SubmitDebugLogActivity extends BaseActivity {
if (item.getItemId() == android.R.id.home) { if (item.getItemId() == android.R.id.home) {
finish(); finish();
return true; return true;
} else if (item.getItemId() == R.id.menu_edit_log) {
viewModel.onEditButtonPressed();
} else if (item.getItemId() == R.id.menu_done_editing_log) {
viewModel.onDoneEditingButtonPressed();
} else if (item.getItemId() == R.id.menu_save) { } else if (item.getItemId() == R.id.menu_save) {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE); intent.addCategory(Intent.CATEGORY_OPENABLE);
@@ -242,7 +319,6 @@ public class SubmitDebugLogActivity extends BaseActivity {
private void initView() { private void initView() {
this.logWebView = findViewById(R.id.debug_log_lines); this.logWebView = findViewById(R.id.debug_log_lines);
this.warningBanner = findViewById(R.id.debug_log_warning_banner); this.warningBanner = findViewById(R.id.debug_log_warning_banner);
this.editBanner = findViewById(R.id.debug_log_edit_banner);
this.submitButton = findViewById(R.id.debug_log_submit_button); this.submitButton = findViewById(R.id.debug_log_submit_button);
this.scrollToBottomButton = findViewById(R.id.debug_log_scroll_to_bottom); this.scrollToBottomButton = findViewById(R.id.debug_log_scroll_to_bottom);
this.scrollToTopButton = findViewById(R.id.debug_log_scroll_to_top); this.scrollToTopButton = findViewById(R.id.debug_log_scroll_to_top);
@@ -279,50 +355,44 @@ public class SubmitDebugLogActivity extends BaseActivity {
hasPresentedLines = true; hasPresentedLines = true;
} }
int chunkSize = 1000;
int count = 0;
StringBuilder lineBuilder = new StringBuilder(); StringBuilder lineBuilder = new StringBuilder();
for (LogLine line : lines) { for (LogLine line : lines) {
if (line == null) continue; if (line == null) continue;
lineBuilder.append(String.format("%s\n", line.getText())); lineBuilder.append(String.format("%s\n", line.getText()));
count++;
if (count >= chunkSize) {
DebugLogsViewer.presentLines(logWebView, lineBuilder.toString());
lineBuilder.setLength(0);
count = 0;
}
} }
if (lineBuilder.length() > 0) {
DebugLogsViewer.presentLines(logWebView, lineBuilder.toString()); DebugLogsViewer.presentLines(logWebView, lineBuilder.toString());
} }
}
private void presentMode(@NonNull SubmitDebugLogViewModel.Mode mode) { private void presentMode(@NonNull SubmitDebugLogViewModel.Mode mode) {
if (editMenuItem == null || doneMenuItem == null || searchMenuItem == null || saveMenuItem == null) { if (searchMenuItem == null || saveMenuItem == null) {
return; return;
} }
switch (mode) { switch (mode) {
case NORMAL: case NORMAL:
editBanner.setVisibility(View.GONE);
searchNav.setVisibility(View.GONE); searchNav.setVisibility(View.GONE);
// TODO [lisa][debug-log-editing]
// setEditing(false);
saveMenuItem.setVisible(true); saveMenuItem.setVisible(true);
// TODO [greyson][log] Not yet implemented
// editMenuItem.setVisible(true);
// doneMenuItem.setVisible(false);
searchMenuItem.setVisible(true); searchMenuItem.setVisible(true);
break; break;
case SUBMITTING: case SUBMITTING:
editBanner.setVisibility(View.GONE);
// setEditing(false);
editMenuItem.setVisible(false);
doneMenuItem.setVisible(false);
searchMenuItem.setVisible(false); searchMenuItem.setVisible(false);
saveMenuItem.setVisible(false); saveMenuItem.setVisible(false);
break; break;
case EDIT:
editBanner.setVisibility(View.VISIBLE);
// setEditing(true);
editMenuItem.setVisible(false);
doneMenuItem.setVisible(true);
searchMenuItem.setVisible(true);
saveMenuItem.setVisible(false);
break;
} }
} }

View File

@@ -110,37 +110,12 @@ public class SubmitDebugLogViewModel extends ViewModel {
}); });
} }
void onQueryUpdated(@NonNull String query) {
throw new UnsupportedOperationException("Not yet implemented.");
}
void onSearchClosed() {
throw new UnsupportedOperationException("Not yet implemented.");
}
void onEditButtonPressed() {
throw new UnsupportedOperationException("Not yet implemented.");
}
void onDoneEditingButtonPressed() {
throw new UnsupportedOperationException("Not yet implemented.");
}
void onLogDeleted(@NonNull LogLine line) {
throw new UnsupportedOperationException("Not yet implemented.");
}
boolean onBackPressed() { boolean onBackPressed() {
if (mode.getValue() == Mode.EDIT) {
mode.setValue(Mode.NORMAL);
return true;
} else {
return false; return false;
} }
}
enum Mode { enum Mode {
NORMAL, EDIT, SUBMITTING NORMAL, SUBMITTING
} }
enum Event { enum Event {

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="@color/transparent_black_40"/> <solid android:color="@color/transparent_black_25"/>
</shape> </shape>

View File

@@ -20,28 +20,12 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
tools:visibility="visible"/> tools:visibility="visible"/>
<TextView
android:id="@+id/debug_log_edit_banner"
android:layout_width="0dp"
android:layout_height="0dp"
android:padding="8dp"
android:gravity="center"
android:text="@string/SubmitDebugLogActivity_tap_a_line_to_delete_it"
android:textColor="@color/core_white"
android:fontFamily="sans-serif-medium"
android:background="@color/core_ultramarine"
android:visibility="gone"
app:layout_constraintTop_toTopOf="@id/debug_log_warning_banner"
app:layout_constraintBottom_toBottomOf="@id/debug_log_warning_banner"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.constraintlayout.widget.Barrier <androidx.constraintlayout.widget.Barrier
android:id="@+id/debug_log_header_barrier" android:id="@+id/debug_log_header_barrier"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:barrierDirection="bottom" app:barrierDirection="bottom"
app:constraint_referenced_ids="debug_log_warning_banner,debug_log_edit_banner" /> app:constraint_referenced_ids="debug_log_warning_banner" />
<WebView <WebView
android:id="@+id/debug_log_lines" android:id="@+id/debug_log_lines"
@@ -98,34 +82,130 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
tools:visibility="visible"> tools:visibility="visible">
<LinearLayout
android:id="@+id/debug_log_levels"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/debug_log_filter"
android:layout_marginVertical="5dp"
android:paddingVertical="4dp"
android:orientation="horizontal"
android:gravity="center"
>
<TextView
android:id="@+id/debug_log_verbose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Signal.Text.Caption"
android:textAllCaps="true"
android:padding="8dp"
android:background="@drawable/tintable_pill_bg"
android:backgroundTint="@color/signal_background_secondary"
android:text="@string/SubmitDebugLogActivity_verbose"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/debug_log_debug"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Signal.Text.Caption"
android:textAllCaps="true"
android:padding="8dp"
android:background="@drawable/tintable_pill_bg"
android:backgroundTint="@color/signal_background_secondary"
android:text="@string/SubmitDebugLogActivity_debug"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/debug_log_verbose"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/debug_log_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/SubmitDebugLogActivity_info"
style="@style/Signal.Text.Caption"
android:textAllCaps="true"
android:padding="8dp"
android:background="@drawable/tintable_pill_bg"
android:backgroundTint="@color/signal_background_secondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/debug_log_debug"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/debug_log_warning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/SubmitDebugLogActivity_warning"
style="@style/Signal.Text.Caption"
android:textAllCaps="true"
android:padding="8dp"
android:background="@drawable/tintable_pill_bg"
android:backgroundTint="@color/signal_background_secondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/info"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/debug_log_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/SubmitDebugLogActivity_error"
style="@style/Signal.Text.Caption"
android:textAllCaps="true"
android:padding="8dp"
android:background="@drawable/tintable_pill_bg"
android:backgroundTint="@color/signal_background_secondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/debug_log_warning"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/debug_log_signalUncaughtException"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/SubmitDebugLogActivity_signal_uncaught_exception"
style="@style/Signal.Text.Caption"
android:textAllCaps="true"
android:padding="8dp"
android:background="@drawable/tintable_pill_bg"
android:backgroundTint="@color/signal_background_secondary"
android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/debug_log_error"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
<ImageButton <ImageButton
android:id="@+id/debug_log_filter" android:id="@+id/debug_log_filter"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:background="@drawable/circle_touch_highlight_background" android:background="@drawable/circle_touch_highlight_background"
android:layout_marginTop="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:padding="8dp" android:padding="8dp"
android:src="@drawable/symbol_filter_24" android:src="@drawable/symbol_filter_24"
app:tint="@color/signal_colorOnSurface" app:tint="@color/signal_colorOnSurface"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toBottomOf="@id/debug_log_levels" />
app:layout_constraintBottom_toBottomOf="parent" />
<ImageButton <ImageButton
android:id="@+id/case_sensitive_button" android:id="@+id/case_sensitive_button"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:background="@drawable/circle_touch_highlight_background" android:background="@drawable/circle_touch_highlight_background"
android:layout_marginTop="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:padding="8dp" android:padding="8dp"
android:src="@drawable/symbol_match_case_24" android:src="@drawable/symbol_match_case_24"
app:tint="@color/signal_colorOnSurface" app:tint="@color/signal_colorOnSurface"
app:layout_constraintStart_toEndOf="@+id/debug_log_filter" app:layout_constraintStart_toEndOf="@id/debug_log_filter"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toBottomOf="@id/debug_log_levels"
app:layout_constraintBottom_toBottomOf="parent" /> app:layout_constraintBottom_toBottomOf="parent" />
<TextView <TextView
@@ -133,19 +213,17 @@
style="@style/Signal.Text.Body" style="@style/Signal.Text.Body"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/debug_log_search_up" app:layout_constraintEnd_toStartOf="@+id/debug_log_search_up"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toBottomOf="@id/debug_log_levels"
tools:text="37 of 73" /> tools:text="37 of 73" />
<ImageButton <ImageButton
android:id="@+id/debug_log_search_up" android:id="@+id/debug_log_search_up"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:background="?selectableItemBackgroundBorderless" android:background="?selectableItemBackgroundBorderless"
@@ -154,13 +232,12 @@
app:tint="@color/core_ultramarine" app:tint="@color/core_ultramarine"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/debug_log_search_down" app:layout_constraintEnd_toStartOf="@+id/debug_log_search_down"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toBottomOf="@id/debug_log_levels" />
<ImageButton <ImageButton
android:id="@+id/debug_log_search_down" android:id="@+id/debug_log_search_down"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:background="?selectableItemBackgroundBorderless" android:background="?selectableItemBackgroundBorderless"
@@ -169,8 +246,7 @@
app:tint="@color/core_ultramarine" app:tint="@color/core_ultramarine"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toBottomOf="@id/debug_log_levels" />
</org.thoughtcrime.securesms.components.ConversationSearchBottomBar> </org.thoughtcrime.securesms.components.ConversationSearchBottomBar>
<org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton <org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton
@@ -179,6 +255,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_margin="8dp" android:layout_margin="8dp"
android:paddingTop="8dp"
android:visibility="gone" android:visibility="gone"
app:circularProgressMaterialButton__label="@string/SubmitDebugLogActivity_submit" app:circularProgressMaterialButton__label="@string/SubmitDebugLogActivity_submit"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View File

@@ -12,18 +12,6 @@
app:actionViewClass="org.thoughtcrime.securesms.components.SearchView" app:actionViewClass="org.thoughtcrime.securesms.components.SearchView"
app:showAsAction="collapseActionView|always" /> app:showAsAction="collapseActionView|always" />
<item
android:id="@+id/menu_edit_log"
android:title="@string/SubmitDebugLogActivity_edit"
android:visible="false"
app:showAsAction="always" />
<item
android:id="@+id/menu_done_editing_log"
android:title="@string/SubmitDebugLogActivity_done"
android:visible="false"
app:showAsAction="always" />
<item <item
android:id="@+id/menu_save" android:id="@+id/menu_save"
android:icon="@drawable/symbol_save_android_24" android:icon="@drawable/symbol_save_android_24"

View File

@@ -2928,6 +2928,13 @@
<string name="SubmitDebugLogActivity_this_log_will_be_posted_publicly_online_for_contributors">This log will be posted publicly online for contributors to view. You may examine it before uploading.</string> <string name="SubmitDebugLogActivity_this_log_will_be_posted_publicly_online_for_contributors">This log will be posted publicly online for contributors to view. You may examine it before uploading.</string>
<!-- Banner message shown while submitting debug log --> <!-- Banner message shown while submitting debug log -->
<string name="SubmitDebugLogActivity_your_log_will_be_posted_online">When you click Submit, your log will be posted online for 30 days at a unique, unpublished URL. You may Save it locally first.</string> <string name="SubmitDebugLogActivity_your_log_will_be_posted_online">When you click Submit, your log will be posted online for 30 days at a unique, unpublished URL. You may Save it locally first.</string>
<!-- Debug log level names to filter by levels. -->
<string name="SubmitDebugLogActivity_signal_uncaught_exception" translatable="false">Uncaught</string>
<string name="SubmitDebugLogActivity_verbose" translatable="false">Verbose</string>
<string name="SubmitDebugLogActivity_debug" translatable="false">Debug</string>
<string name="SubmitDebugLogActivity_info" translatable="false">Info</string>
<string name="SubmitDebugLogActivity_warning" translatable="false">Warn</string>
<string name="SubmitDebugLogActivity_error" translatable="false">Error</string>
<!-- SupportEmailUtil --> <!-- SupportEmailUtil -->
<string name="SupportEmailUtil_support_email" translatable="false">support@signal.org</string> <string name="SupportEmailUtil_support_email" translatable="false">support@signal.org</string>

View File

@@ -54,6 +54,7 @@ const session = editor.getSession();
let logLines = ""; // Original logLines let logLines = ""; // Original logLines
let input = ""; // Search query input let input = ""; // Search query input
let selectedLevels = []; // Log levels that are selected in checkboxes
let markers = []; // IDs of highlighted search markers let markers = []; // IDs of highlighted search markers
let matchRanges = []; // Ranges of all search matches let matchRanges = []; // Ranges of all search matches
let matchCount = 0; // Total number of matches let matchCount = 0; // Total number of matches
@@ -134,6 +135,7 @@ function onSearchDown() {
} }
function onSearchClose() { function onSearchClose() {
editor.setValue(logLines, -1);
editor.getSelection().clearSelection(); editor.getSelection().clearSelection();
input = ""; input = "";
clearMarkers(); clearMarkers();
@@ -156,19 +158,64 @@ function onFilter() {
isFiltered = true; isFiltered = true;
editor.getSelection().clearSelection(); editor.getSelection().clearSelection();
clearMarkers(); clearMarkers();
applyFilter();
}
function onFilterClose() {
isFiltered = false;
clearMarkers();
editor.getSelection().clearSelection();
if (selectedLevels.length === 0) {
editor.setValue(logLines, -1);
} else {
const filtered = logLines const filtered = logLines
.split("\n") .split("\n")
.filter((line) => { .filter((line) => {
const newLine = isCaseSensitive ? line : line.toLowerCase(); return selectedLevels.some((level) => line.includes(level));
return newLine.includes(isCaseSensitive ? input : input.toLowerCase());
}) })
.join("\n"); .join("\n");
editor.setValue(filtered, -1); editor.setValue(filtered, -1);
} }
function onFilterClose() {
isFiltered = false;
editor.setValue(logLines, -1);
highlightAllMatches(input); highlightAllMatches(input);
} }
function onFilterLevel(sLevels) {
selectedLevels = sLevels;
if (isFiltered) {
applyFilter();
} else {
if (selectedLevels.length === 0) {
editor.setValue(logLines, -1);
editor.scrollToRow(0);
} else {
const filtered = logLines
.split("\n")
.filter((line) => {
return selectedLevels.some((level) => line.includes(level));
})
.join("\n");
editor.setValue(filtered, -1);
}
onSearch();
}
}
function applyFilter() {
const filtered = logLines
.split("\n")
.filter((line) => {
const newLine = isCaseSensitive ? line : line.toLowerCase();
const lineMatch = newLine.includes(isCaseSensitive ? input : input.toLowerCase());
const levelMatch = selectedLevels.length === 0 || selectedLevels.some((level) => line.includes(level));
return lineMatch && levelMatch;
})
.join("\n");
editor.setValue(filtered, -1);
}

View File

@@ -47,7 +47,7 @@ object DebugLogsViewer {
fun presentLines(webview: WebView, lines: String) { fun presentLines(webview: WebView, lines: String) {
// Set the debug log lines // Set the debug log lines
val escaped = JSONObject.quote(lines) val escaped = JSONObject.quote(lines)
webview.evaluateJavascript("editor.insert($escaped); logLines=$escaped;", null) webview.evaluateJavascript("editor.insert($escaped); logLines+=$escaped;", null)
} }
@JvmStatic @JvmStatic
@@ -80,6 +80,12 @@ object DebugLogsViewer {
webview.evaluateJavascript("onFilterClose()", null) webview.evaluateJavascript("onFilterClose()", null)
} }
@JvmStatic
fun onFilterLevel(webview: WebView, selectedLevels: String) {
webview.evaluateJavascript("if (isFiltered) { onFilter(); }", null)
webview.evaluateJavascript("onFilterLevel($selectedLevels)", null)
}
@JvmStatic @JvmStatic
fun onSearchUp(webview: WebView) { fun onSearchUp(webview: WebView) {
webview.evaluateJavascript("onSearchUp();", null) webview.evaluateJavascript("onSearchUp();", null)