diff --git a/TODO.md b/TODO.md index cef34e35..b5903d7a 100644 --- a/TODO.md +++ b/TODO.md @@ -5,11 +5,11 @@ - update glass theme - back/front buttons in small window - minimum sizes -- save/restore swipeview current rooms for accounts - lag when switching accounts - message delegate too tall - unread counts on accounts - fix compact mode +- left rooms opacity - fix escape keybinds (filter rooms, message selection) - if last room event is a membership change, it won't be visible in timeline diff --git a/mirage.pro b/mirage.pro index f0032d58..75d111f7 100644 --- a/mirage.pro +++ b/mirage.pro @@ -58,11 +58,6 @@ dev { } -# Libraries includes - -include(submodules/SortFilterProxyModel/SortFilterProxyModel.pri) - - # Custom functions defineReplace(glob_filenames) { diff --git a/src/gui/Base/HFilterModel.qml b/src/gui/Base/HFilterModel.qml new file mode 100644 index 00000000..b82febf1 --- /dev/null +++ b/src/gui/Base/HFilterModel.qml @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later + +import QtQuick 2.12 +import QtQml.Models 2.12 + +DelegateModel { + filterOnGroup: "filtered" + + groups: DelegateModelGroup { + id: filtered + name: "filtered" + includeByDefault: false + } + + onAcceptItemChanged: refilterAll() + + items.onChanged: { + for (let i = 0; i < inserted.length; i++) + for (let offset = 0; offset <= inserted[i].count - 1; offset++) + refilterAt(inserted[i].index + offset) + } + + + property var acceptItem: item => true + readonly property alias filtered: filtered + + + function refilterAt(index) { + const item = items.get(index) + item.inFiltered = acceptItem(item.model) + } + + function refilterAll() { + for (let i = 0; i < items.count; i++) refilterAt(i) + } + + function filteredFindIndex(id) { + for (let i = 0; i < filtered.count; i++) + if (filtered.get(i).id === id) return i + + return null + } + + function filteredFind(id) { + for (let i = 0; i < filtered.count; i++) + if (filtered.get(i).id === id) return get(i) + + return null + } +} diff --git a/src/gui/Base/HSortFilterProxyModel.qml b/src/gui/Base/HSortFilterProxyModel.qml deleted file mode 100644 index 54c9944d..00000000 --- a/src/gui/Base/HSortFilterProxyModel.qml +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later - -import QtQuick 2.12 -import SortFilterProxyModel 0.2 - -SortFilterProxyModel { - function findIndex(id) { - for (let i = 0; i < count; i++) - if (get(i).id === id) return i - - return null - } - - function find(id) { - for (let i = 0; i < count; i++) - if (get(i).id === id) return get(i) - - return null - } -} diff --git a/src/gui/MainPane/AccountsBar.qml b/src/gui/MainPane/AccountsBar.qml index f2c96868..5d6a68ff 100644 --- a/src/gui/MainPane/AccountsBar.qml +++ b/src/gui/MainPane/AccountsBar.qml @@ -34,7 +34,10 @@ HColumnLayout { roomList.currentIndex === -1 ? -1 : model.findIndex( - roomList.model.get(roomList.currentIndex).for_account, -1, + roomList.model.filtered.get( + roomList.currentIndex, + ).model.for_account, + -1, ) highlight: Item { diff --git a/src/gui/MainPane/FilterRoomsField.qml b/src/gui/MainPane/FilterRoomsField.qml index 55a6638e..6e6e1042 100644 --- a/src/gui/MainPane/FilterRoomsField.qml +++ b/src/gui/MainPane/FilterRoomsField.qml @@ -20,13 +20,13 @@ HTextField { Keys.onEnterPressed: Keys.onReturnPressed(event) Keys.onReturnPressed: { - if (window.settings.clearRoomFilterOnEnter) text = "" roomList.showRoomAtIndex() + if (window.settings.clearRoomFilterOnEnter) text = "" } Keys.onEscapePressed: { - if (window.settings.clearRoomFilterOnEscape) text = "" mainUI.pageLoader.forceActiveFocus() + if (window.settings.clearRoomFilterOnEscape) text = "" } diff --git a/src/gui/MainPane/RoomList.qml b/src/gui/MainPane/RoomList.qml index 4ff00d27..90d834cf 100644 --- a/src/gui/MainPane/RoomList.qml +++ b/src/gui/MainPane/RoomList.qml @@ -2,13 +2,21 @@ import QtQuick 2.12 import QtQuick.Layouts 1.12 -import SortFilterProxyModel 0.2 import ".." import "../Base" HListView { id: roomList - model: filter ? proxyModel : proxyModel.sourceModel + + model: HFilterModel { + model: ModelStore.get("every_room") + delegate: Room { + width: roomList.width + onActivated: showRoomAtIndex(model.index) + } + + acceptItem: item => utils.filterMatches(filter, item.display_name) + } section.property: "for_account" section.labelPositioning: @@ -18,10 +26,7 @@ HListView { width: roomList.width } - delegate: Room { - width: roomList.width - onActivated: showRoomAtIndex(model.index) - } + onFilterChanged: model.refilterAll() property string filter: "" @@ -50,22 +55,23 @@ HListView { function showRoomAtIndex(index=currentIndex) { if (index === -1) index = 0 - index = Math.min(index, model.count - 1) + index = Math.min(index, model.filtered.count - 1) - const room = model.get(index) + const room = model.filtered.get(index).model pageLoader.showRoom(room.for_account, room.id) currentIndex = index } function showAccountRoomAtIndex(index) { - const userId = - model.get(currentIndex === -1 ? 0 : currentIndex).for_account + const userId = model.filtered.get( + currentIndex === -1 ? 0 : currentIndex + ).model.for_account const rooms = ModelStore.get(userId, "rooms") if (! rooms.count) return const room = rooms.get(utils.numberWrapAt(index, rooms.count)) - showRoomAtIndex(model.findIndex(room.id)) + showRoomAtIndex(model.filteredFindIndex(room.id)) } @@ -97,15 +103,6 @@ HListView { } } - HSortFilterProxyModel { - id: proxyModel - sourceModel: ModelStore.get("every_room") - - filters: ExpressionFilter { - expression: utils.filterMatches(filter, model.display_name) - } - } - Rectangle { anchors.fill: parent z: -100 diff --git a/src/gui/Pages/Chat/RoomPane/MemberView.qml b/src/gui/Pages/Chat/RoomPane/MemberView.qml index f325c28f..1e121038 100644 --- a/src/gui/Pages/Chat/RoomPane/MemberView.qml +++ b/src/gui/Pages/Chat/RoomPane/MemberView.qml @@ -2,7 +2,6 @@ import QtQuick 2.12 import QtQuick.Layouts 1.12 -import SortFilterProxyModel 0.2 import "../../.." import "../../../Base" @@ -14,26 +13,17 @@ HColumnLayout { id: memberList clip: true - // https://github.com/oKcerG/SortFilterProxyModel/issues/75 - model: filterField.text ? proxy : proxy.sourceModel + model: HFilterModel { + model: ModelStore.get(chat.userId, chat.roomId, "members") + delegate: MemberDelegate { width: memberList.width } - delegate: MemberDelegate { - width: memberList.width + acceptItem: item => + utils.filterMatches(filterField.text, item.display_name) } Layout.fillWidth: true Layout.fillHeight: true - readonly property HSortFilterProxyModel proxy: HSortFilterProxyModel { - sourceModel: ModelStore.get(chat.userId, chat.roomId, "members") - - filters: ExpressionFilter { - expression: utils.filterMatches( - filterField.text, model.display_name, - ) - } - } - Rectangle { anchors.fill: parent z: -100 @@ -68,6 +58,8 @@ HColumnLayout { // declared normally Component.onCompleted: placeholderText = qsTr("Filter members") + onTextChanged: memberList.model.refilterAll() + Behavior on opacity { HNumberAnimation {} } } diff --git a/src/gui/Utils.qml b/src/gui/Utils.qml index 1e7c6253..3add6868 100644 --- a/src/gui/Utils.qml +++ b/src/gui/Utils.qml @@ -227,6 +227,8 @@ QtObject { } function filterMatches(filter, text) { + if (! filter) return true + const filter_lower = filter.toLowerCase() if (filter_lower === filter) {