Begin yet another model refactor

Use native ListModel which require a lot of changes, but should be
much faster than the old way which exponentially slowed down to a crawl.
Also fix some popup bugs (leave/forget).

Not working yet: side pane keyboard controls, proper highlight,
room & member filtering, local echo replacement
This commit is contained in:
miruka
2019-12-02 16:29:29 -04:00
parent 2ce5e20efa
commit 9990fecc74
49 changed files with 826 additions and 781 deletions

View File

@@ -2,6 +2,7 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import "../.."
import "../../Base"
import "RoomPane"
@@ -13,16 +14,11 @@ Item {
property string userId: ""
property string roomId: ""
property QtObject userInfo: ModelStore.get("accounts").find(userId)
property QtObject roomInfo: ModelStore.get(userId, "rooms").find(roomId)
property bool loadingMessages: false
property bool ready: userInfo !== "waiting" && roomInfo !== "waiting"
readonly property var userInfo:
utils.getItem(modelSources["Account"] || [], "user_id", userId) ||
"waiting"
readonly property var roomInfo: utils.getItem(
modelSources[["Room", userId]] || [], "room_id", roomId
) || "waiting"
property bool ready: Boolean(userInfo && roomInfo)
readonly property alias loader: loader
readonly property alias roomPane: roomPaneLoader.item

View File

@@ -3,18 +3,28 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import Clipboard 0.1
import "../.."
import "../../Base"
import "../../Dialogs"
Rectangle {
id: composer
color: theme.chat.composer.background
Layout.fillWidth: true
Layout.minimumHeight: theme.baseElementsHeight
Layout.preferredHeight: areaScrollView.implicitHeight
Layout.maximumHeight: pageLoader.height / 2
property string indent: " "
property var aliases: window.settings.writeAliases
property string toSend: ""
property string writingUserId: chat.userId
readonly property var writingUserInfo:
utils.getItem(modelSources["Account"] || [], "user_id", writingUserId)
property QtObject writingUserInfo:
ModelStore.get("accounts").find(writingUserId)
property bool textChangedSinceLostFocus: false
@@ -40,20 +50,9 @@ Rectangle {
lineTextUntilCursor.match(/ {1,4}/g).slice(-1)[0].length :
1
function takeFocus() { areaScrollView.forceActiveFocus() }
// property var pr: lineTextUntilCursor
// onPrChanged: print(
// "y", cursorY, "x", cursorX,
// "ltuc <" + lineTextUntilCursor + ">", "dob",
// deleteCharsOnBackspace, "m", lineTextUntilCursor.match(/^ +$/))
id: composer
Layout.fillWidth: true
Layout.minimumHeight: theme.baseElementsHeight
Layout.preferredHeight: areaScrollView.implicitHeight
Layout.maximumHeight: pageLoader.height / 2
color: theme.chat.composer.background
HRowLayout {
anchors.fill: parent
@@ -61,8 +60,8 @@ Rectangle {
HUserAvatar {
id: avatar
userId: writingUserId
displayName: writingUserInfo.display_name
mxc: writingUserInfo.avatar_url
displayName: writingUserInfo ? writingUserInfo.display_name : ""
mxc: writingUserInfo ? writingUserInfo.avatar_url : ""
}
HScrollableTextArea {

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12
import "../../.."
import "../../../Base"
Rectangle {
@@ -25,11 +26,7 @@ Rectangle {
id: transferList
anchors.fill: parent
model: HListModel {
keyField: "uuid"
source: modelSources[["Upload", chat.roomId]] || []
}
model: ModelStore.get(chat.roomId, "uploads")
delegate: Transfer { width: transferList.width }
}
}

View File

@@ -11,7 +11,7 @@ HTileDelegate {
model.invited ? theme.chat.roomPane.member.invitedOpacity : 1
image: HUserAvatar {
userId: model.user_id
userId: model.id
displayName: model.display_name
mxc: model.avatar_url
powerLevel: model.power_level
@@ -19,20 +19,20 @@ HTileDelegate {
invited: model.invited
}
title.text: model.display_name || model.user_id
title.text: model.display_name || model.id
title.color:
memberDelegate.hovered ?
utils.nameColor(model.display_name || model.user_id.substring(1)) :
utils.nameColor(model.display_name || model.id.substring(1)) :
theme.chat.roomPane.member.name
subtitle.text: model.display_name ? model.user_id : ""
subtitle.text: model.display_name ? model.id : ""
subtitle.color: theme.chat.roomPane.member.subtitle
contextMenu: HMenu {
HMenuItem {
icon.name: "copy-user-id"
text: qsTr("Copy user ID")
onTriggered: Clipboard.text = model.user_id
onTriggered: Clipboard.text = model.id
}
}

View File

@@ -2,6 +2,7 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import "../../.."
import "../../../Base"
HColumnLayout {
@@ -9,37 +10,33 @@ HColumnLayout {
id: memberList
clip: true
Layout.fillWidth: true
Layout.fillHeight: true
model: ModelStore.get(chat.userId, chat.roomId, "members")
// model: HSortFilterProxy {
// model: ModelStore.get(chat.userId, chat.roomId, "members")
// comparator: (a, b) =>
// // Sort by power level, then by display name or user ID (no @)
// [
// a.invited,
// b.power_level,
// (a.display_name || a.id.substring(1)).toLocaleLowerCase(),
// ] < [
// b.invited,
// a.power_level,
// (b.display_name || b.id.substring(1)).toLocaleLowerCase(),
// ]
readonly property var originSource:
modelSources[["Member", chat.userId, chat.roomId]] || []
onOriginSourceChanged: filterLimiter.restart()
function filterSource() {
model.source =
utils.filterModelSource(originSource, filterField.text)
}
model: HListModel {
keyField: "user_id"
source: memberList.originSource
}
// filter: (item, index) => utils.filterMatchesAny(
// filterField.text, item.display_name, item.id,
// )
// }
delegate: MemberDelegate {
width: memberList.width
}
Timer {
id: filterLimiter
interval: 16
onTriggered: memberList.filterSource()
}
Layout.fillWidth: true
Layout.fillHeight: true
}
HRowLayout {
@@ -56,7 +53,7 @@ HColumnLayout {
bordered: false
opacity: width >= 16 * theme.uiScale ? 1 : 0
onTextChanged: filterLimiter.restart()
onTextChanged: memberList.model.reFilter()
Layout.fillWidth: true
Layout.fillHeight: true

View File

@@ -172,7 +172,7 @@ HRowLayout {
HRepeater {
id: linksRepeater
model: eventDelegate.currentModel.links
model: JSON.parse(eventDelegate.currentModel.links)
EventMediaLoader {
singleMediaInfo: eventDelegate.currentModel

View File

@@ -3,6 +3,7 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import Clipboard 0.1
import "../../.."
import "../../../Base"
HColumnLayout {
@@ -65,13 +66,8 @@ HColumnLayout {
function json() {
return JSON.stringify(
{
"model": utils.getItem(
modelSources[[
"Event", chat.userId, chat.roomId
]],
"client_id",
model.client_id
),
"model": ModelStore.get(chat.userId, chat.roomId, "events")
.get(model.id),
"source": py.getattr(model.source, "__dict__"),
},
null, 4)

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12
import "../../.."
import "../../../Base"
Rectangle {
@@ -157,12 +158,12 @@ Rectangle {
}
model: HListModel {
keyField: "client_id"
source: modelSources[[
"Event", chat.userId, chat.roomId
]] || []
}
model: ModelStore.get(chat.userId, chat.roomId, "events")
// model: HSortFilterProxy {
// model: ModelStore.get(chat.userId, chat.roomId, "events")
// comparator: "date"
// descendingSort: true
// }
delegate: EventDelegate {}
}

View File

@@ -32,7 +32,7 @@ Rectangle {
textFormat: Text.StyledText
elide: Text.ElideRight
text: {
let tm = chat.roomInfo.typing_members
const tm = JSON.parse(chat.roomInfo.typing_members)
if (tm.length === 0) return ""
if (tm.length === 1) return qsTr("%1 is typing...").arg(tm[0])