Add search functionality to debug log screen.

This commit is contained in:
lisa-signal
2025-08-01 12:47:49 -04:00
committed by Cody Henthorne
parent 962375e422
commit 5e0aa830bf
8 changed files with 313 additions and 35 deletions

View File

@@ -12,6 +12,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
@@ -27,7 +28,9 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.signal.debuglogsviewer.DebugLogsViewer;
import org.thoughtcrime.securesms.BaseActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.ConversationSearchBottomBar;
import org.thoughtcrime.securesms.components.ProgressCard;
import org.thoughtcrime.securesms.components.SearchView;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.LongClickCopySpan;
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
@@ -48,6 +51,7 @@ public class SubmitDebugLogActivity extends BaseActivity {
private View warningBanner;
private View editBanner;
private CircularProgressMaterialButton submitButton;
private ConversationSearchBottomBar searchNav;
private View scrollToBottomButton;
private View scrollToTopButton;
private ProgressCard progressCard;
@@ -57,6 +61,11 @@ public class SubmitDebugLogActivity extends BaseActivity {
private MenuItem searchMenuItem;
private MenuItem saveMenuItem;
private ImageButton caseSensitiveButton;
private TextView searchPosition;
private ImageButton searchUpButton;
private ImageButton searchDownButton;
private boolean isWebViewLoaded;
private boolean hasPresentedLines;
@@ -91,33 +100,71 @@ public class SubmitDebugLogActivity extends BaseActivity {
this.searchMenuItem = menu.findItem(R.id.menu_search);
this.saveMenuItem = menu.findItem(R.id.menu_save);
// TODO [lisa][debug-log-search]
// SearchView searchView = (SearchView) searchMenuItem.getActionView();
// SearchView.OnQueryTextListener queryListener = new SearchView.OnQueryTextListener() {
// @Override
// public boolean onQueryTextSubmit(String query) {
// return true;
// }
//
// @Override
// public boolean onQueryTextChange(String query) {
// return true;
// }
// };
//
// searchMenuItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
// @Override
// public boolean onMenuItemActionExpand(MenuItem item) {
// searchView.setOnQueryTextListener(queryListener);
// return true;
// }
//
// @Override
// public boolean onMenuItemActionCollapse(MenuItem item) {
// searchView.setOnQueryTextListener(null);
// return true;
// }
// });
this.searchNav = findViewById(R.id.debug_log_search_nav);
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);
this.searchDownButton = findViewById(R.id.debug_log_search_down);
searchUpButton.setOnClickListener(v -> {
DebugLogsViewer.onSearchUp(logWebView);
DebugLogsViewer.getSearchPosition(logWebView, position -> searchPosition.setText(position));
});
searchDownButton.setOnClickListener(v -> {
DebugLogsViewer.onSearchDown(logWebView);
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];
int backgroundColor = isCaseSensitive[0] ? R.drawable.circle_tint_darker : R.drawable.circle_touch_highlight_background;
caseSensitiveButton.setBackground(getResources().getDrawable(backgroundColor));
});
SearchView searchView = (SearchView) searchMenuItem.getActionView();
SearchView.OnQueryTextListener queryListener = new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String query) {
DebugLogsViewer.onSearch(logWebView, query);
DebugLogsViewer.getSearchPosition(logWebView, position -> searchPosition.setText(position));
return true;
}
};
searchMenuItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
searchNav.setVisibility(View.VISIBLE);
submitButton.setVisibility(View.GONE);
searchView.setOnQueryTextListener(queryListener);
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
searchNav.setVisibility(View.GONE);
submitButton.setVisibility(View.VISIBLE);
DebugLogsViewer.onSearchClose(logWebView);
DebugLogsViewer.getSearchPosition(logWebView, position -> searchPosition.setText(position));
searchView.setOnQueryTextListener(null);
return true;
}
});
if (viewModel.getMode().getValue() != null) {
presentMode(viewModel.getMode().getValue());
}
return true;
}
@@ -217,16 +264,21 @@ public class SubmitDebugLogActivity extends BaseActivity {
}
private void presentMode(@NonNull SubmitDebugLogViewModel.Mode mode) {
if (editMenuItem == null || doneMenuItem == null || searchMenuItem == null || saveMenuItem == null) {
return;
}
switch (mode) {
case NORMAL:
editBanner.setVisibility(View.GONE);
searchNav.setVisibility(View.GONE);
// TODO [lisa][debug-log-editing]
// setEditing(false);
saveMenuItem.setVisible(true);
// TODO [greyson][log] Not yet implemented
// editMenuItem.setVisible(true);
// doneMenuItem.setVisible(false);
// searchMenuItem.setVisible(true);
searchMenuItem.setVisible(true);
break;
case SUBMITTING:
editBanner.setVisibility(View.GONE);

View File

@@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M2.13 7c0-0.48 0.39-0.88 0.87-0.88h18c0.48 0 0.88 0.4 0.88 0.88S21.48 7.88 21 7.88H3c-0.48 0-0.88-0.4-0.88-0.88Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M5.38 12c0-0.48 0.39-0.88 0.87-0.88h11.5c0.48 0 0.88 0.4 0.88 0.88s-0.4 0.88-0.88 0.88H6.25c-0.48 0-0.88-0.4-0.88-0.88Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M9.5 16.13c-0.48 0-0.88 0.39-0.88 0.87s0.4 0.88 0.88 0.88h5c0.48 0 0.88-0.4 0.88-0.88s-0.4-0.88-0.88-0.88h-5Z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M131,708L296,268L375,268L540,708L464,708L425,596L247,596L207,708L131,708ZM270,532L401,532L337,350L333,350L270,532ZM665,718Q614,718 584,690.5Q554,663 554,618Q554,574 588.5,545.5Q623,517 677,517Q700,517 722,521Q744,525 760,532L760,520Q760,491 739.5,473Q719,455 685,455Q662,455 643,464.5Q624,474 610,492L563,457Q587,428 617.5,414Q648,400 686,400Q755,400 789,432.5Q823,465 823,530L823,708L760,708L760,671L756,671Q742,694 718,706Q694,718 665,718ZM677,664Q712,664 736.5,640Q761,616 761,584Q747,576 727.5,571.5Q708,567 689,567Q657,567 639,581Q621,595 621,618Q621,638 637,651Q653,664 677,664Z"/>
</vector>

View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
tools:viewBindingIgnore="true"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -48,10 +47,9 @@
android:id="@+id/debug_log_lines"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:scrollbars="vertical"
app:layout_constraintTop_toBottomOf="@id/debug_log_header_barrier"
app:layout_constraintBottom_toTopOf="@id/debug_log_submit_button"/>
app:layout_constraintBottom_toTopOf="@id/debug_log_footer_barrier"/>
<ImageButton
android:id="@+id/debug_log_scroll_to_top"
@@ -80,7 +78,83 @@
app:tint="@color/grey_600"
app:srcCompat="@drawable/ic_chevron_down_20"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/debug_log_submit_button"/>
app:layout_constraintBottom_toTopOf="@id/debug_log_footer_barrier"/>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/debug_log_footer_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="top"
app:constraint_referenced_ids="debug_log_submit_button,debug_log_search_nav" />
<org.thoughtcrime.securesms.components.ConversationSearchBottomBar
android:id="@+id/debug_log_search_nav"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/signal_background_secondary"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:visibility="visible">
<ImageButton
android:id="@+id/case_sensitive_button"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/circle_touch_highlight_background"
android:layout_marginStart="16dp"
android:padding="8dp"
android:src="@drawable/symbol_match_case_24"
app:tint="@color/signal_colorOnSurface"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<TextView
android:id="@+id/debug_log_search_position"
style="@style/Signal.Text.Body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/debug_log_search_up"
app:layout_constraintTop_toTopOf="parent"
tools:text="37 of 73" />
<ImageButton
android:id="@+id/debug_log_search_up"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="?selectableItemBackgroundBorderless"
android:padding="8dp"
android:src="@drawable/symbol_chevron_up_24"
app:tint="@color/core_ultramarine"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/debug_log_search_down"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/debug_log_search_down"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="?selectableItemBackgroundBorderless"
android:padding="8dp"
android:src="@drawable/symbol_chevron_down_24"
app:tint="@color/core_ultramarine"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</org.thoughtcrime.securesms.components.ConversationSearchBottomBar>
<org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton
android:id="@+id/debug_log_submit_button"

View File

@@ -8,6 +8,7 @@
android:icon="@drawable/symbol_search_24"
android:title="@string/CameraContacts__menu_search"
android:visible="false"
app:iconTint="@color/signal_colorOnSurface"
app:actionViewClass="org.thoughtcrime.securesms.components.SearchView"
app:showAsAction="collapseActionView|always" />