Repair room filter, performance improvements

Chnaging delegate heights is a terrible idea that leads to graphic bugs.
Handle filtering (both room and accounts) and collapsing from a function
that sets the JsonListModel source.
This commit is contained in:
miruka 2019-08-19 10:28:49 -04:00
parent 2865d86d19
commit 165c1b797e
7 changed files with 75 additions and 22 deletions

View File

@ -1,4 +1,6 @@
- Refactoring - Refactoring
- filter string serialize thing
- set client max timeout to 10s
- Make all icon SVG files white/black, since we can now use ColorOverlay - Make all icon SVG files white/black, since we can now use ColorOverlay
- Make the icon blue in EditAccount when hovering and no avatar set - Make the icon blue in EditAccount when hovering and no avatar set

View File

@ -84,7 +84,6 @@ class App:
rl = self.run_in_loop # noqa rl = self.run_in_loop # noqa
ba = self.backend # noqa ba = self.backend # noqa
mo = self.backend.models # noqa mo = self.backend.models # noqa
smo = self.backend.sidepane_model # noqa
cl = self.backend.clients cl = self.backend.clients
tcl = lambda user: cl[f"@test_{user}:matrix.org"] # noqa tcl = lambda user: cl[f"@test_{user}:matrix.org"] # noqa

View File

@ -13,12 +13,17 @@ class Account(ModelItem):
display_name: str = "" display_name: str = ""
avatar_url: str = "" avatar_url: str = ""
profile_updated: datetime = field(default_factory=datetime.now) profile_updated: datetime = field(default_factory=datetime.now)
filter_string: str = ""
def __lt__(self, other: "Account") -> bool: def __lt__(self, other: "Account") -> bool:
name = self.display_name or self.user_id[1:] name = self.display_name or self.user_id[1:]
other_name = other.display_name or other.user_id[1:] other_name = other.display_name or other.user_id[1:]
return name < other_name return name < other_name
# @property
# def filter_string(self) -> str: # TODO: support serializing properties
# return " ".join((self.user_id, self.display_name))
@dataclass @dataclass
class Room(ModelItem): class Room(ModelItem):

View File

@ -1,16 +1,54 @@
import QtQuick 2.12 import QtQuick 2.12
import QtQuick.Layouts 1.12 import QtQuick.Layouts 1.12
import "../Base" import "../Base"
import "../utils.js" as Utils
HListView { HListView {
id: accountRoomList id: accountRoomList
// property bool forceExpand: paneToolBar.roomFilter && roomList.model.count
property bool forceExpand: false readonly property var originSource: window.sidePaneModelSource
readonly property var collapseAccounts: window.uiState.collapseAccounts
readonly property string filter: paneToolBar.roomFilter
onOriginSourceChanged: Qt.callLater(filterSource)
onFilterChanged: Qt.callLater(filterSource)
onCollapseAccountsChanged: Qt.callLater(filterSource)
function filterSource() {
let show = []
for (let i = 0; i < window.sidePaneModelSource.length; i++) {
let item = window.sidePaneModelSource[i]
if (item.type == "Account" ||
(filter ?
Utils.filterMatches(filter, item.data.filter_string) :
! window.uiState.collapseAccounts[item.user_id]))
{
if (filter && show.length && item.type == "Account" &&
show[show.length - 1].type == "Account" &&
! Utils.filterMatches(filter, item.data.filter_string)) {
// If current and previous items are both accounts,
// that means the previous account had no matching rooms.
show.pop()
}
show.push(item)
}
}
// If last item is an account, that account had no matching rooms.
if (show.length && show[show.length - 1].type == "Account") show.pop()
model.source = show
}
model: HListModel { model: HListModel {
keyField: "id" keyField: "id"
source: window.sidePaneModelSource source: originSource
} }
delegate: Loader { delegate: Loader {

View File

@ -4,17 +4,22 @@ import "../Base"
HInteractiveRectangle { HInteractiveRectangle {
id: accountDelegate id: accountDelegate
height: row.height
color: theme.sidePane.account.background color: theme.sidePane.account.background
checked: isCurrent
height: row.height
checked: accountDelegate.isCurrent
readonly property bool isCurrent: readonly property bool isCurrent:
window.uiState.page == "Pages/EditAccount/EditAccount.qml" && window.uiState.page == "Pages/EditAccount/EditAccount.qml" &&
window.uiState.pageProperties.userId == model.data.user_id window.uiState.pageProperties.userId == model.data.user_id
readonly property bool forceExpand:
Boolean(accountRoomList.filter)
readonly property bool collapsed: readonly property bool collapsed:
! accountRoomList.forceExpand && ! forceExpand &&
window.uiState.collapseAccounts[model.data.user_id] || false accountRoomList.collapseAccounts[model.data.user_id] || false
function toggleCollapse() { function toggleCollapse() {
window.uiState.collapseAccounts[model.data.user_id] = ! collapsed window.uiState.collapseAccounts[model.data.user_id] = ! collapsed
@ -27,6 +32,7 @@ HInteractiveRectangle {
) )
} }
TapHandler { onTapped: accountDelegate.activate() } TapHandler { onTapped: accountDelegate.activate() }
HRowLayout { HRowLayout {
@ -74,7 +80,7 @@ HInteractiveRectangle {
visible: opacity > 0 visible: opacity > 0
opacity: opacity:
accountRoomList.forceExpand ? 0 : accountDelegate.forceExpand ? 0 :
collapsed ? theme.sidePane.account.collapsedOpacity + 0.2 : collapsed ? theme.sidePane.account.collapsedOpacity + 0.2 :
1 1
Behavior on opacity { HNumberAnimation {} } Behavior on opacity { HNumberAnimation {} }

View File

@ -6,29 +6,30 @@ import "../utils.js" as Utils
HInteractiveRectangle { HInteractiveRectangle {
id: roomDelegate id: roomDelegate
color: theme.sidePane.room.background color: theme.sidePane.room.background
readonly property bool collapsed:
! accountRoomList.forceExpand &&
window.uiState.collapseAccounts[model.user_id] || false
visible: height > 0 visible: height > 0
height: collapsed ? 0 : rowLayout.height height: rowLayout.height
Behavior on height { HNumberAnimation {} }
opacity: model.data.left ? theme.sidePane.room.leftRoomOpacity : 1 opacity: model.data.left ? theme.sidePane.room.leftRoomOpacity : 1
checked: isCurrent
Behavior on opacity { HNumberAnimation {} } Behavior on opacity { HNumberAnimation {} }
checked: isCurrent
readonly property bool forceExpand:
Boolean(accountRoomList.filter)
readonly property bool isCurrent: readonly property bool isCurrent:
window.uiState.page == "Chat/Chat.qml" && window.uiState.page == "Chat/Chat.qml" &&
window.uiState.pageProperties.userId == model.user_id && window.uiState.pageProperties.userId == model.user_id &&
window.uiState.pageProperties.roomId == model.data.room_id window.uiState.pageProperties.roomId == model.data.room_id
function activate() { function activate() {
pageStack.showRoom(model.user_id, model.data.room_id) pageStack.showRoom(model.user_id, model.data.room_id)
print(model.user_id, model.data.room_id) print(model.user_id, model.data.room_id)
} }
TapHandler { onTapped: activate() } TapHandler { onTapped: activate() }
HRowLayout { HRowLayout {

View File

@ -89,11 +89,13 @@ function filterMatches(filter, text) {
function filterModelSource(source, filter_text, property="filter_string") { function filterModelSource(source, filter_text, property="filter_string") {
if (! filter_text) { return source } if (! filter_text) return source
let results = [] let results = []
for (let item of source) {
if (filterMatches(filter_text, item[property])) { results.push(item) } for (let i = 0; i < source.length; i++) {
if (filterMatches(filter_text, source[i][property])) {
results.push(item)
}
} }
return results return results
} }