Warning, /network/neochat/src/qml/SearchPage.qml is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
0002 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0003 
0004 import QtQuick
0005 import QtQuick.Controls as QQC2
0006 import QtQuick.Layouts
0007 
0008 import org.kde.kirigami as Kirigami
0009 
0010 /**
0011  * @brief Component for a generic search page.
0012  *
0013  * This component provides a header with the search field and a ListView to visualise
0014  * search results from the given model.
0015  */
0016 Kirigami.ScrollablePage {
0017     id: root
0018 
0019     /**
0020      * @brief Any additional controls after the search button.
0021      */
0022     property alias headerTrailing: headerContent.children
0023 
0024     /**
0025      * @brief The model that provides the search results.
0026      *
0027      * The model needs to provide the following properties:
0028      *      - searchText
0029      *      - searching
0030      * Where searchText is the text from the searchField and is used to match results
0031      * and searching is true while the model is finding results.
0032      *
0033      * The model must also provide a search() function to start the search if
0034      * it doesn't do so when the searchText is changed.
0035      */
0036     property alias model: listView.model
0037 
0038     /**
0039      * @brief The number of delegates currently in the view.
0040      */
0041     property alias count: listView.count
0042 
0043     /**
0044      * @brief The delegate to use to visualize the model data.
0045      */
0046     property alias modelDelegate: listView.delegate
0047 
0048     /**
0049      * @brief The delegate to appear as the header of the list.
0050      */
0051     property alias listHeaderDelegate: listView.header
0052 
0053     /**
0054      * @brief The delegate to appear as the footer of the list.
0055      */
0056     property alias listFooterDelegate: listView.footer
0057 
0058     /**
0059      * @brief The placeholder text in the search field.
0060      */
0061     property alias searchFieldPlaceholder: searchField.placeholderText
0062 
0063     /**
0064      * @brief The text to show when no search term has been entered.
0065      */
0066     property alias noSearchPlaceholderMessage: noSearchMessage.text
0067 
0068     /**
0069      * @brief The text to show when no results have been found.
0070      */
0071     property alias noResultPlaceholderMessage: noResultMessage.text
0072 
0073     /**
0074      * @brief The verticalLayoutDirection property of the internal ListView.
0075      */
0076     property alias listVerticalLayoutDirection: listView.verticalLayoutDirection
0077 
0078     /**
0079      * @brief Force the search field to be focussed.
0080      */
0081     function focusSearch() {
0082         searchField.forceActiveFocus();
0083     }
0084 
0085     header: QQC2.Control {
0086         padding: Kirigami.Units.largeSpacing
0087 
0088         background: Rectangle {
0089             Kirigami.Theme.colorSet: Kirigami.Theme.Window
0090             Kirigami.Theme.inherit: false
0091             color: Kirigami.Theme.backgroundColor
0092 
0093             Kirigami.Separator {
0094                 anchors {
0095                     left: parent.left
0096                     bottom: parent.bottom
0097                     right: parent.right
0098                 }
0099             }
0100         }
0101 
0102         contentItem: RowLayout {
0103             id: headerContent
0104             spacing: Kirigami.Units.largeSpacing
0105 
0106             Kirigami.SearchField {
0107                 id: searchField
0108                 focus: true
0109                 Layout.fillWidth: true
0110                 Keys.onEnterPressed: searchButton.clicked()
0111                 Keys.onReturnPressed: searchButton.clicked()
0112                 onTextChanged: {
0113                     searchTimer.restart();
0114                     if (model) {
0115                         model.searchText = text;
0116                     }
0117                 }
0118             }
0119             QQC2.Button {
0120                 id: searchButton
0121                 icon.name: "search"
0122                 onClicked: {
0123                     if (typeof model.search === 'function') {
0124                         model.search();
0125                     }
0126                 }
0127             }
0128             Timer {
0129                 id: searchTimer
0130                 interval: 500
0131                 running: true
0132                 onTriggered: if (typeof model.search === 'function') {
0133                     model.search();
0134                 }
0135             }
0136         }
0137     }
0138 
0139     ListView {
0140         id: listView
0141         Layout.fillWidth: true
0142         Layout.fillHeight: true
0143         spacing: 0
0144 
0145         section.property: "section"
0146 
0147         Kirigami.PlaceholderMessage {
0148             id: noSearchMessage
0149             anchors.centerIn: parent
0150             visible: searchField.text.length === 0 && listView.count === 0
0151         }
0152 
0153         Kirigami.PlaceholderMessage {
0154             id: noResultMessage
0155             anchors.centerIn: parent
0156             visible: searchField.text.length > 0 && listView.count === 0 && !root.model.searching
0157         }
0158 
0159         Kirigami.LoadingPlaceholder {
0160             anchors.centerIn: parent
0161             visible: searchField.text.length > 0 && listView.count === 0 && root.model.searching
0162         }
0163     }
0164 }