Single room list approach, account bar scrolls

This commit is contained in:
miruka 2020-04-29 14:00:02 -04:00
parent 56c09e6b48
commit fcf88209f2
13 changed files with 129 additions and 172 deletions

View File

@ -1,5 +1,7 @@
# TODO
- rename goto*account → scrollto*account
- account number binds
- update glass theme
- back/front buttons in small window
- minimum sizes

View File

@ -871,6 +871,7 @@ class MatrixClient(nio.AsyncClient):
"""
self.models[self.user_id, "rooms"].pop(room_id, None)
self.models["every_room"].pop((self.user_id, room_id), None)
self.models.pop((self.user_id, room_id, "events"), None)
self.models.pop((self.user_id, room_id, "members"), None)
@ -1209,8 +1210,9 @@ class MatrixClient(nio.AsyncClient):
mentions = 0
unreads = 0
self.models[self.user_id, "rooms"][room.room_id] = Room(
room_item = Room(
id = room.room_id,
for_account = self.user_id,
given_name = room.name or "",
display_name = room.display_name or "",
avatar_url = room.gen_avatar_url or "",
@ -1244,9 +1246,11 @@ class MatrixClient(nio.AsyncClient):
last_event_date = last_event_date,
mentions = mentions,
unreads = unreads,
)
self.models[self.user_id, "rooms"][room.room_id] = room_item
self.models["every_room"][self.user_id, room.room_id] = room_item
# List members that left the room, then remove them from our model
left_the_room = [
user_id

View File

@ -40,9 +40,9 @@ class Account(ModelItem):
first_sync_done: bool = False
def __lt__(self, other: "Account") -> bool:
"""Sort by display name or user ID."""
name = self.display_name or self.id[1:]
other_name = other.display_name or other.id[1:]
"""Sort by user ID."""
name = self.id[1:]
other_name = other.id[1:]
return name.lower() < other_name.lower()
@ -51,6 +51,7 @@ class Room(ModelItem):
"""A matrix room we are invited to, are or were member of."""
id: str = field()
for_account: str = field()
given_name: str = ""
display_name: str = ""
main_alias: str = ""
@ -90,19 +91,22 @@ class Room(ModelItem):
Invited rooms are first, then joined rooms, then left rooms.
Within these categories, sort by last event date (room with recent
messages are first), then by display names, but
messages are first), then by display names, then account, but
keep rooms with mentions on top, followed by rooms with unread events.
"""
# Left rooms may still have an inviter_id, so check left first.
return (
self.for_account,
self.left,
other.inviter_id,
bool(other.mentions),
bool(other.unreads),
other.last_event_date,
(self.display_name or self.id).lower(),
) < (
other.for_account,
other.left,
self.inviter_id,
bool(self.mentions),

View File

@ -217,7 +217,7 @@ HDrawer {
NumberAnimation {
running: doUselessThing
target: mainUI.mainPane.mainPaneList
target: mainUI.mainPane.roomList
property: "rotation"
duration: 250
from: 360
@ -225,19 +225,4 @@ HDrawer {
loops: Animation.Infinite
onStopped: target.rotation = 0
}
NumberAnimation {
running: doUselessThing
target: mainUI.pageLoader
property: "scale"
duration: 250
from: 1
to: -1
onStopped: if (doUselessThing) {
[from, to] = [to, from]
start()
} else {
target.scale = 1
}
}
}

View File

@ -17,17 +17,19 @@ HTile {
HUserAvatar {
id: avatar
userId: model.id
displayName: model.display_name
mxc: model.avatar_url
userId: accountModel.id
displayName: accountModel.display_name
mxc: accountModel.avatar_url
radius: 0
}
TitleLabel {
text: model.display_name || model.id
text: accountModel.display_name || accountModel.id
color:
hovered ?
utils.nameColor(model.display_name || model.id.substring(1)) :
utils.nameColor(
accountModel.display_name || accountModel.id.substring(1),
) :
theme.accountView.account.name
Behavior on color { HColorAnimation {} }
@ -40,7 +42,7 @@ HTile {
backgroundColor: "transparent"
toolTip.text: qsTr("Add new chat")
onClicked: pageLoader.showPage(
"AddChat/AddChat", {userId: model.id},
"AddChat/AddChat", {userId: accountModel.id},
)
Layout.fillHeight: true
@ -59,7 +61,7 @@ HTile {
HMenuItem {
icon.name: "copy-user-id"
text: qsTr("Copy user ID")
onTriggered: Clipboard.text = model.id
onTriggered: Clipboard.text = accountModel.id
}
HMenuItemPopupSpawner {
@ -68,17 +70,18 @@ HTile {
text: qsTr("Sign out")
popup: "Popups/SignOutPopup.qml"
properties: { "userId": model.id }
properties: { "userId": accountModel.id }
}
}
onLeftClicked: {
pageLoader.showPage(
"AccountSettings/AccountSettings", { "userId": model.id }
"AccountSettings/AccountSettings", { "userId": accountModel.id }
)
}
property var accountModel
property bool isCurrent: false

View File

@ -1,16 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12
import ".."
import "../Base"
HSwipeView {
id: swipeView
orientation: Qt.Vertical
Repeater {
model: ModelStore.get("accounts")
AccountView {}
}
}

View File

@ -1,46 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12
import QtQuick.Layouts 1.12
import ".."
import "../Base"
HLoader {
id: loader
active:
HSwipeView.isCurrentItem ||
HSwipeView.isNextItem ||
HSwipeView.isPreviousItem
readonly property bool isCurrent: HSwipeView.isCurrentItem
sourceComponent: HColumnLayout {
id: column
readonly property QtObject accountModel: model
readonly property alias roomList: roomList
Account {
id: account
isCurrent: loader.isCurrent
Layout.fillWidth: true
}
RoomList {
id: roomList
clip: true
accountModel: column.accountModel
roomPane: swipeView
isCurrent: loader.isCurrent
Layout.fillWidth: true
Layout.fillHeight: true
}
FilterRoomsField {
roomList: roomList
Layout.fillWidth: true
}
}
}

View File

@ -8,21 +8,21 @@ import "../Base"
import "../Base/HTile"
HColumnLayout {
property AccountSwipeView accountSwipeView
property RoomList roomList
HButton {
id: everyRoomButton
icon.name: "every-room"
toolTip.text: qsTr("Every room")
backgroundColor: theme.accountsBar.everyRoomButtonBackground
// onClicked: pageLoader.showPage("AddAccount/AddAccount")
id: addAccountButton
icon.name: "add-account"
toolTip.text: qsTr("Add another account")
backgroundColor: theme.accountsBar.addAccountButtonBackground
onClicked: pageLoader.showPage("AddAccount/AddAccount")
Layout.preferredHeight: theme.baseElementsHeight
HShortcut {
sequences: window.settings.keys.showEveryRoom
onActivated: everyRoomButton.clicked()
sequences: window.settings.keys.addNewAccount
onActivated: addAccountButton.clicked()
}
}
@ -30,10 +30,14 @@ HColumnLayout {
id: accountList
clip: true
model: ModelStore.get("accounts")
currentIndex: accountSwipeView.currentIndex
currentIndex:
roomList.currentIndex === -1 ?
-1 :
model.findIndex(
roomList.model.get(roomList.currentIndex).for_account, -1,
)
highlight: Item {
Rectangle {
anchors.fill: parent
color: theme.accountsBar.accountList.account.selectedBackground
@ -74,7 +78,7 @@ HColumnLayout {
}
}
onLeftClicked: accountSwipeView.currentIndex = model.index
onLeftClicked: roomList.goToAccount(model.id)
}
Layout.fillWidth: true
@ -82,12 +86,18 @@ HColumnLayout {
HShortcut {
sequences: window.settings.keys.goToPreviousAccount
onActivated: accountSwipeView.decrementWrapIndex()
onActivated: {
accountList.decrementCurrentIndex()
accountList.currentItem.leftClicked()
}
}
HShortcut {
sequences: window.settings.keys.goToNextAccount
onActivated: accountSwipeView.incrementWrapIndex()
onActivated: {
accountList.incrementCurrentIndex()
accountList.currentItem.leftClicked()
}
}
Rectangle {
@ -97,21 +107,6 @@ HColumnLayout {
}
}
HButton {
id: addAccountButton
icon.name: "add-account"
toolTip.text: qsTr("Add another account")
backgroundColor: theme.accountsBar.addAccountButtonBackground
onClicked: pageLoader.showPage("AddAccount/AddAccount")
Layout.preferredHeight: theme.baseElementsHeight
HShortcut {
sequences: window.settings.keys.addNewAccount
onActivated: addAccountButton.clicked()
}
}
HButton {
id: settingsButton
backgroundColor: theme.accountsBar.settingsButtonBackground

View File

@ -21,7 +21,7 @@ HTextField {
Keys.onEnterPressed: Keys.onReturnPressed(event)
Keys.onReturnPressed: {
if (window.settings.clearRoomFilterOnEnter) text = ""
roomList.showRoom()
roomList.showRoomAtIndex()
}
Keys.onEscapePressed: {
@ -36,13 +36,11 @@ HTextField {
Behavior on opacity { HNumberAnimation {} }
HShortcut {
enabled: loader.isCurrent
sequences: window.settings.keys.clearRoomFilter
onActivated: filterField.text = ""
}
HShortcut {
enabled: loader.isCurrent
sequences: window.settings.keys.toggleFocusMainPane
onActivated: {
if (filterField.activeFocus) {

View File

@ -10,7 +10,9 @@ HDrawer {
background: null
// minimumSize: bottomBar.addAccountButton.width
// property alias filter: bottomBar.roomFilter
readonly property alias accountBar: accountBar
readonly property alias roomList: roomList
readonly property alias filterRoomsField: filterRoomsField
readonly property bool small:
width < theme.controls.avatar.size + theme.spacing * 2
@ -28,17 +30,26 @@ HDrawer {
AccountsBar {
id: accountBar
accountSwipeView: accountSwipeView
roomList: roomList
Layout.fillWidth: false
}
AccountSwipeView {
id: accountSwipeView
currentIndex: 0
HColumnLayout {
RoomList {
id: roomList
clip: true
Layout.fillWidth: true
Layout.fillHeight: true
Layout.fillWidth: true
Layout.fillHeight: true
}
FilterRoomsField {
id: filterRoomsField
roomList: roomList
Layout.fillWidth: true
}
}
}
}

View File

@ -146,7 +146,7 @@ HTileDelegate {
popup: "Popups/InviteToRoomPopup.qml"
properties: ({
userId: userId,
userId: model.for_account,
roomId: model.id,
roomName: model.display_name,
invitingAllowed: Qt.binding(() => model.can_invite)
@ -169,7 +169,7 @@ HTileDelegate {
label.textFormat: Text.StyledText
onTriggered: py.callClientCoro(
userId, "join", [model.id]
model.for_account, "join", [model.id]
)
}
@ -181,7 +181,7 @@ HTileDelegate {
popup: "Popups/LeaveRoomPopup.qml"
properties: ({
userId: userId,
userId: model.for_account,
roomId: model.id,
roomName: model.display_name,
})
@ -195,7 +195,7 @@ HTileDelegate {
popup: "Popups/ForgetRoomPopup.qml"
autoDestruct: false
properties: ({
userId: userId,
userId: model.for_account,
roomId: model.id,
roomName: model.display_name,
})
@ -203,14 +203,12 @@ HTileDelegate {
}
property string userId
readonly property bool joined: ! invited && ! parted
readonly property bool invited: model.inviter_id && ! parted
readonly property bool parted: model.left
readonly property ListModel eventModel:
ModelStore.get(userId, model.id, "events")
ModelStore.get(model.for_account, model.id, "events")
readonly property QtObject lastEvent:
eventModel.count > 0 ? eventModel.get(0) : null

View File

@ -7,44 +7,78 @@ import "../Base"
HListView {
id: roomList
model: ModelStore.get(accountModel.id, "rooms")
model: ModelStore.get("every_room")
section.property: "for_account"
section.labelPositioning:
ViewSection.InlineLabels | ViewSection.CurrentLabelAtStart
section.delegate: Account {
accountModel: ModelStore.get("accounts").find(section)
width: roomList.width
}
delegate: Room {
width: roomList.width
userId: accountModel.id
onActivated: showRoom(model.index)
onActivated: showRoomAtIndex(model.index)
}
onIsCurrentChanged: if (isCurrent) showRoom()
readonly property var sectionIndice: {
const sections = {}
const accounts = ModelStore.get("accounts")
let total = 0
for (let i = 0; i < accounts.count; i++) {
const userId = accounts.get(i).id
sections[userId] = total
total += ModelStore.get(userId, "rooms").count
}
return sections
}
property var accountModel
property var roomPane
property bool isCurrent: false
function goToAccount(userId) {
currentIndex = sectionIndice[userId]
}
function goToAccountNumber(num) {
currentIndex = Object.values(sectionIndice).sort()[num]
}
function showRoom(index=currentIndex) {
function showRoomAtIndex(index=currentIndex) {
if (index === -1) index = 0
if (index >= model.count) return
pageLoader.showRoom(accountModel.id, model.get(index).id)
index = Math.min(index, model.count - 1)
const room = model.get(index)
pageLoader.showRoom(room.for_account, room.id)
currentIndex = index
}
function showAccountRoomAtIndex(index) {
const userId =
model.get(currentIndex === -1 ? 0 : currentIndex).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))
}
Timer {
id: showRoomLimiter
interval: 200
onTriggered: showRoom()
onTriggered: showRoomAtIndex()
}
HShortcut {
enabled: isCurrent
sequences: window.settings.keys.goToPreviousRoom
onActivated: { decrementCurrentIndex(); showRoomLimiter.restart() }
}
HShortcut {
enabled: isCurrent
sequences: window.settings.keys.goToNextRoom
onActivated: { incrementCurrentIndex(); showRoomLimiter.restart() }
}
@ -54,28 +88,13 @@ HListView {
Item {
HShortcut {
enabled: isCurrent
sequence: window.settings.keys.focusRoomAtIndex[modelData]
onActivated: showRoom(parseInt(modelData - 1, 10))
onActivated:
showAccountRoomAtIndex(parseInt(modelData - 1, 10))
}
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
onWheel: {
const goingDown = wheel.angleDelta.y < 0
if (! goingDown && roomList.atYBeginning)
roomPane.decrementCurrentIndex()
else if (goingDown && roomList.atYEnd)
roomPane.incrementCurrentIndex()
else
wheel.accepted = false
}
}
Rectangle {
anchors.fill: parent
z: -100

View File

@ -14,18 +14,18 @@ QtObject {
ListModel {
property var modelId
function findIndex(id) {
function findIndex(id, default_=null) {
for (let i = 0; i < count; i++)
if (get(i).id === id) return i
return null
return default_
}
function find(id) {
function find(id, default_=null) {
for (let i = 0; i < count; i++)
if (get(i).id === id) return get(i)
return null
return default_
}
}
}