summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoseph Donofry <rubberduckie3554@gmail.com>2022-12-20 16:34:55 -0500
committerJoseph Donofry <rubberduckie3554@gmail.com>2022-12-20 16:34:55 -0500
commita2e120a8a3764ff0ec45aa6c1515e335bb910589 (patch)
tree056f75dfb1e8e1989284259f71b3f0364e963ce8
parentMake unfiltered messages hidden by default (diff)
downloadnheko-a2e120a8a3764ff0ec45aa6c1515e335bb910589.tar.xz
Add 'clear' button to search bar and implement search indicator via spinner
-rw-r--r--resources/qml/MatrixTextField.qml34
-rw-r--r--resources/qml/MessageView.qml6
-rw-r--r--resources/qml/TopBar.qml1
-rw-r--r--src/timeline/TimelineFilter.cpp9
-rw-r--r--src/timeline/TimelineFilter.h3
5 files changed, 51 insertions, 2 deletions
diff --git a/resources/qml/MatrixTextField.qml b/resources/qml/MatrixTextField.qml
index 3f0f77ed..e3632b61 100644
--- a/resources/qml/MatrixTextField.qml
+++ b/resources/qml/MatrixTextField.qml
@@ -20,6 +20,7 @@ ColumnLayout {
     property alias font: input.font
     property alias echoMode: input.echoMode
     property alias selectByMouse: input.selectByMouse
+    property var hasClear: false
 
     Timer {
         id: timer
@@ -129,6 +130,39 @@ ColumnLayout {
             color: labelC.text ? "transparent" : backgroundColor
         }
 
+        ToolButton {
+            id: clearText
+            Layout.fillWidth: true
+            visible: c.hasClear && searchField.text !== ''
+            icon.source: "image://colorimage/:/icons/icons/ui/round-remove-button.svg?" + (clearText.hovered ? Nheko.colors.highlight : Nheko.colors.buttonText)
+            focusPolicy: Qt.NoFocus
+            onClicked: {
+                searchField.clear()
+                topBar.searchString = "";
+            }
+            hoverEnabled: true
+            background: null
+            anchors {
+                verticalCenter: parent.verticalCenter
+                right: parent.right
+            }
+            // clear the default hover effects.
+
+            Image {
+                height: parent.height - 2 * Nheko.paddingSmall
+                width: height
+                source: "image://colorimage/:/icons/icons/ui/round-remove-button.svg?" + (clearText.hovered ? Nheko.colors.highlight : Nheko.colors.buttonText)
+
+                anchors {
+                    verticalCenter: parent.verticalCenter
+                    right: parent.right
+                    margins: Nheko.paddingSmall
+                }
+
+            }
+
+        }
+
     }
 
     Rectangle {
diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml
index e3e02ee9..a49c046c 100644
--- a/resources/qml/MessageView.qml
+++ b/resources/qml/MessageView.qml
@@ -38,6 +38,8 @@ Item {
 
         property int delegateMaxWidth: ((Settings.timelineMaxWidth > 100 && Settings.timelineMaxWidth < chatRoot.availableWidth) ? Settings.timelineMaxWidth : chatRoot.availableWidth) - chatRoot.padding * 2 - (scrollbar.interactive? scrollbar.width : 0)
 
+        readonly property alias filteringInProgress: filteredTimeline.filteringInProgress
+
         displayMarginBeginning: height / 2
         displayMarginEnd: height / 2
 
@@ -561,7 +563,7 @@ Item {
         footer: Item {
             anchors.horizontalCenter: parent.horizontalCenter
             anchors.margins: Nheko.paddingLarge
-            visible: room && room.paginationInProgress
+            visible: (room && room.paginationInProgress) || chat.filteringInProgress
             // hacky, but works
             height: loadingSpinner.height + 2 * Nheko.paddingLarge
 
@@ -570,7 +572,7 @@ Item {
 
                 anchors.centerIn: parent
                 anchors.margins: Nheko.paddingLarge
-                running: room && room.paginationInProgress
+                running: (room && room.paginationInProgress) || chat.filteringInProgress
                 foreground: Nheko.colors.mid
                 z: 3
             }
diff --git a/resources/qml/TopBar.qml b/resources/qml/TopBar.qml
index 760f20e6..cce2c89b 100644
--- a/resources/qml/TopBar.qml
+++ b/resources/qml/TopBar.qml
@@ -450,6 +450,7 @@ Pane {
                 id: searchField
                 visible: searchButton.searchActive
                 enabled: visible
+                hasClear: true
 
                 Layout.row: 5
                 Layout.column: 2
diff --git a/src/timeline/TimelineFilter.cpp b/src/timeline/TimelineFilter.cpp
index 7dc4c7aa..9389b815 100644
--- a/src/timeline/TimelineFilter.cpp
+++ b/src/timeline/TimelineFilter.cpp
@@ -39,6 +39,7 @@ void
 TimelineFilter::startFiltering()
 {
     incrementalSearchIndex = 0;
+    emit isFilteringChanged();
     invalidateFilter();
 
     continueFiltering();
@@ -82,6 +83,7 @@ TimelineFilter::event(QEvent *ev)
                     continueFiltering();
                 }
             }
+            emit isFilteringChanged();
         }
         return true;
     }
@@ -172,6 +174,7 @@ TimelineFilter::setSource(TimelineModel *s)
         incrementalSearchIndex = 0;
 
         emit sourceChanged();
+        emit isFilteringChanged();
         invalidateFilter();
     }
 }
@@ -201,6 +204,12 @@ TimelineFilter::currentIndex() const
 }
 
 bool
+TimelineFilter::isFiltering() const
+{
+    return incrementalSearchIndex != std::numeric_limits<int>::max() && !(threadId.isEmpty() && contentFilter.isEmpty());
+}
+
+bool
 TimelineFilter::filterAcceptsRow(int source_row, const QModelIndex &) const
 {
     // this chunk is still unfiltered.
diff --git a/src/timeline/TimelineFilter.h b/src/timeline/TimelineFilter.h
index 30ec3300..c35f8da3 100644
--- a/src/timeline/TimelineFilter.h
+++ b/src/timeline/TimelineFilter.h
@@ -20,6 +20,7 @@ class TimelineFilter : public QSortFilterProxyModel
                  contentFilterChanged)
     Q_PROPERTY(TimelineModel *source READ source WRITE setSource NOTIFY sourceChanged)
     Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+    Q_PROPERTY(bool filteringInProgress READ isFiltering NOTIFY isFilteringChanged)
 
 public:
     explicit TimelineFilter(QObject *parent = nullptr);
@@ -28,6 +29,7 @@ public:
     QString filterByContent() const { return contentFilter; }
     TimelineModel *source() const;
     int currentIndex() const;
+    bool isFiltering() const;
 
     void setThreadId(const QString &t);
     void setContentFilter(const QString &t);
@@ -46,6 +48,7 @@ signals:
     void contentFilterChanged();
     void sourceChanged();
     void currentIndexChanged();
+    void isFilteringChanged();
 
 private slots:
     void fetchAgain();