Replace SortFilterProxyModel by DelegateModel
This commit is contained in:
		
							
								
								
									
										2
									
								
								TODO.md
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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 | ||||
|   | ||||
| @@ -58,11 +58,6 @@ dev { | ||||
| } | ||||
|  | ||||
|  | ||||
| # Libraries includes | ||||
|  | ||||
| include(submodules/SortFilterProxyModel/SortFilterProxyModel.pri) | ||||
|  | ||||
|  | ||||
| # Custom functions | ||||
|  | ||||
| defineReplace(glob_filenames) { | ||||
|   | ||||
							
								
								
									
										50
									
								
								src/gui/Base/HFilterModel.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/gui/Base/HFilterModel.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
|     } | ||||
| } | ||||
| @@ -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 | ||||
|     } | ||||
| } | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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 = "" | ||||
|     } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 {} } | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -227,6 +227,8 @@ QtObject { | ||||
|     } | ||||
|  | ||||
|     function filterMatches(filter, text) { | ||||
|         if (! filter) return true | ||||
|  | ||||
|         const filter_lower = filter.toLowerCase() | ||||
|  | ||||
|         if (filter_lower === filter) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	