Add a basic member list pane to rooms
1
TODO.md
@ -1,7 +1,6 @@
|
||||
- Refactoring
|
||||
- Migrate more JS functions to their own files / Implement in Python instead
|
||||
- Don't bake in size properties for components
|
||||
- Cleanup unused icons
|
||||
|
||||
- Bug fixes
|
||||
- dataclass-like `default_factory` for ListItem
|
||||
|
@ -3,9 +3,9 @@ import QtQuick.Layouts 1.3
|
||||
import "../Base"
|
||||
import "Banners"
|
||||
import "RoomEventList"
|
||||
import "DetailsPane"
|
||||
import "RoomSidePane"
|
||||
|
||||
HSplitView {
|
||||
HColumnLayout {
|
||||
property string userId: ""
|
||||
property string category: ""
|
||||
property string roomId: ""
|
||||
@ -32,46 +32,58 @@ HSplitView {
|
||||
}
|
||||
)
|
||||
|
||||
HColumnLayout {
|
||||
RoomHeader {
|
||||
id: roomHeader
|
||||
displayName: roomInfo.displayName
|
||||
topic: roomInfo.topic || ""
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
RoomHeader {
|
||||
displayName: roomInfo.displayName
|
||||
topic: roomInfo.topic || ""
|
||||
}
|
||||
|
||||
RoomEventList {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
TypingMembersBar {}
|
||||
|
||||
InviteBanner {
|
||||
visible: category === "Invites"
|
||||
inviter: roomInfo.inviter
|
||||
}
|
||||
|
||||
UnknownDevicesBanner {
|
||||
visible: category == "Rooms" && hasUnknownDevices
|
||||
}
|
||||
|
||||
SendBox {
|
||||
id: sendBox
|
||||
visible: category == "Rooms" && ! hasUnknownDevices
|
||||
}
|
||||
|
||||
LeftBanner {
|
||||
visible: category === "Left"
|
||||
leftEvent: roomInfo.leftEvent
|
||||
}
|
||||
Layout.preferredHeight: 32
|
||||
}
|
||||
|
||||
DetailsPane {
|
||||
property int parentWidth: parent.width
|
||||
onParentWidthChanged: width = Math.min(parent.width * 0.3, 300)
|
||||
|
||||
Layout.minimumWidth: 36
|
||||
Layout.maximumWidth: parent.width
|
||||
HSplitView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
HColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
RoomEventList {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
TypingMembersBar {}
|
||||
|
||||
InviteBanner {
|
||||
visible: category === "Invites"
|
||||
inviter: roomInfo.inviter
|
||||
}
|
||||
|
||||
UnknownDevicesBanner {
|
||||
visible: category == "Rooms" && hasUnknownDevices
|
||||
}
|
||||
|
||||
SendBox {
|
||||
id: sendBox
|
||||
visible: category == "Rooms" && ! hasUnknownDevices
|
||||
}
|
||||
|
||||
LeftBanner {
|
||||
visible: category === "Left"
|
||||
leftEvent: roomInfo.leftEvent
|
||||
}
|
||||
}
|
||||
|
||||
RoomSidePane {
|
||||
id: roomSidePane
|
||||
|
||||
property int referenceWidth: roomHeader.buttonsWidth
|
||||
onReferenceWidthChanged: width = referenceWidth
|
||||
|
||||
Layout.minimumWidth: 36
|
||||
Layout.maximumWidth: parent.width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,15 +6,14 @@ HRectangle {
|
||||
property string displayName: ""
|
||||
property string topic: ""
|
||||
|
||||
property bool collapseButtons: width < 480
|
||||
property alias buttonsWidth: viewButtons.width
|
||||
|
||||
id: roomHeader
|
||||
color: HStyle.chat.roomHeader.background
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 32
|
||||
|
||||
HRowLayout {
|
||||
id: row
|
||||
spacing: 8
|
||||
anchors.fill: parent
|
||||
|
||||
HAvatar {
|
||||
@ -30,7 +29,12 @@ HRectangle {
|
||||
font.pixelSize: HStyle.fontSize.big
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
Layout.maximumWidth: row.width - row.totalSpacing - avatar.width
|
||||
|
||||
Layout.maximumWidth:
|
||||
row.width - Layout.leftMargin * 2 - avatar.width -
|
||||
viewButtons.width -
|
||||
(expandButton.visible ? expandButton.width : 0)
|
||||
Layout.leftMargin: 8
|
||||
}
|
||||
|
||||
HLabel {
|
||||
@ -39,10 +43,56 @@ HRectangle {
|
||||
font.pixelSize: HStyle.fontSize.small
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
|
||||
Layout.maximumWidth:
|
||||
row.width - row.totalSpacing - avatar.width - roomName.width
|
||||
row.width - Layout.leftMargin * 2 - avatar.width -
|
||||
roomName.width - viewButtons.width -
|
||||
(expandButton.visible ? expandButton.width : 0)
|
||||
Layout.leftMargin: 8
|
||||
}
|
||||
|
||||
HSpacer {}
|
||||
|
||||
Row {
|
||||
id: viewButtons
|
||||
Layout.maximumWidth: collapseButtons ? 0 : implicitWidth
|
||||
|
||||
HButton {
|
||||
iconName: "room_view_members"
|
||||
}
|
||||
|
||||
HButton {
|
||||
iconName: "room_view_files"
|
||||
}
|
||||
|
||||
HButton {
|
||||
iconName: "room_view_notifications"
|
||||
}
|
||||
|
||||
HButton {
|
||||
iconName: "room_view_history"
|
||||
}
|
||||
|
||||
HButton {
|
||||
iconName: "room_view_settings"
|
||||
}
|
||||
|
||||
Behavior on Layout.maximumWidth {
|
||||
NumberAnimation { id: buttonsAnimation; duration: 150 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HButton {
|
||||
id: expandButton
|
||||
z: 1
|
||||
anchors.right: parent.right
|
||||
opacity: collapseButtons ? 1 : 0
|
||||
visible: opacity > 0
|
||||
iconName: "reduced_room_buttons"
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: buttonsAnimation.duration * 2 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
37
harmonyqml/components/Chat/RoomSidePane/MemberDelegate.qml
Normal file
@ -0,0 +1,37 @@
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
import "../../Base"
|
||||
|
||||
MouseArea {
|
||||
id: memberDelegate
|
||||
width: memberList.width
|
||||
height: childrenRect.height
|
||||
|
||||
property var member: Backend.users.get(modelData)
|
||||
|
||||
HRowLayout {
|
||||
width: parent.width
|
||||
spacing: memberList.spacing
|
||||
|
||||
HAvatar {
|
||||
id: memberAvatar
|
||||
name: member.displayName.value
|
||||
}
|
||||
|
||||
HColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth:
|
||||
parent.width - parent.totalSpacing - memberAvatar.width
|
||||
|
||||
HLabel {
|
||||
id: memberName
|
||||
text: member.displayName.value
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
|
||||
Layout.maximumWidth: parent.width
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
harmonyqml/components/Chat/RoomSidePane/MembersView.qml
Normal file
@ -0,0 +1,30 @@
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
import "../../Base"
|
||||
|
||||
Column {
|
||||
property int normalSpacing: 8
|
||||
property bool collapsed:
|
||||
width < roomSidePane.Layout.minimumWidth + normalSpacing
|
||||
|
||||
leftPadding: collapsed ? 0 : normalSpacing
|
||||
rightPadding: leftPadding
|
||||
|
||||
ListView {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
id: memberList
|
||||
|
||||
spacing: collapsed ? 0 : normalSpacing
|
||||
topMargin: spacing
|
||||
bottomMargin: topMargin
|
||||
|
||||
Behavior on spacing {
|
||||
NumberAnimation { duration: 150 }
|
||||
}
|
||||
|
||||
model: chatPage.roomInfo.members
|
||||
delegate: MemberDelegate {}
|
||||
}
|
||||
}
|
16
harmonyqml/components/Chat/RoomSidePane/RoomSidePane.qml
Normal file
@ -0,0 +1,16 @@
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
import "../../Base"
|
||||
|
||||
HRectangle {
|
||||
id: roomSidePane
|
||||
|
||||
HColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
MembersView {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
@ -50,8 +50,21 @@ Item {
|
||||
Component.onCompleted: {
|
||||
if (pageStack.initialPageSet) { return }
|
||||
pageStack.initialPageSet = true
|
||||
showRoom("@test_mary:matrix.org", "Rooms", "!TSXGsbBbdwsdylIOJZ:matrix.org")
|
||||
//showPage(accountsLoggedIn ? "Default" : "SignIn")
|
||||
showPage(accountsLoggedIn ? "Default" : "SignIn")
|
||||
if (accountsLoggedIn) { initialRoomTimer.start() }
|
||||
}
|
||||
|
||||
Timer {
|
||||
// TODO: remove this, debug
|
||||
id: initialRoomTimer
|
||||
interval: appWindow.reloadedTimes > 0 ? 0 : 5000
|
||||
repeat: false
|
||||
onTriggered: pageStack.showRoom(
|
||||
"@test_mary:matrix.org",
|
||||
"Rooms",
|
||||
//"!TSXGsbBbdwsdylIOJZ:matrix.org"
|
||||
"!HfNYlUkGqcWcpDQJpb:matrix.org"
|
||||
)
|
||||
}
|
||||
|
||||
onCurrentItemChanged: if (currentItem) {
|
||||
|
@ -10,6 +10,8 @@ ApplicationWindow {
|
||||
|
||||
onClosing: Backend.clients.removeAll()
|
||||
|
||||
property int reloadedTimes: 0
|
||||
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
source: "UI.qml"
|
||||
|
@ -70,9 +70,12 @@ class Engine(QQmlApplicationEngine):
|
||||
|
||||
def reloadQml(self) -> None:
|
||||
loader = self.rootObjects()[0].findChild(QObject, "UILoader")
|
||||
|
||||
source = loader.property("source")
|
||||
loader.setProperty("source", None)
|
||||
self.clearComponentCache()
|
||||
|
||||
window = self.rootObjects()[0]
|
||||
reloaded_times = window.property("reloadedTimes")
|
||||
window.setProperty("reloadedTimes", reloaded_times + 1)
|
||||
|
||||
loader.setProperty("source", source)
|
||||
|
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 1h-24v16.981h4v5.019l7-5.019h13z"/></svg>
|
Before Width: | Height: | Size: 137 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M21 13v10h-6v-6h-6v6h-6v-10h-3l12-12 12 12h-3zm-1-5.907v-5.093h-3v2.093l3 3z"/></svg>
|
Before Width: | Height: | Size: 177 B |
1
harmonyqml/icons/reduced_room_buttons.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M6 12c0 1.657-1.343 3-3 3s-3-1.343-3-3 1.343-3 3-3 3 1.343 3 3zm9 0c0 1.657-1.343 3-3 3s-3-1.343-3-3 1.343-3 3-3 3 1.343 3 3zm9 0c0 1.657-1.343 3-3 3s-3-1.343-3-3 1.343-3 3-3 3 1.343 3 3z"/></svg>
|
After Width: | Height: | Size: 288 B |
1
harmonyqml/icons/room_view_files.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M22 13v-13h-20v24h8.409c4.857 0 3.335-8 3.335-8 3.009.745 8.256.419 8.256-3zm-4-7h-12v-1h12v1zm0 3h-12v-1h12v1zm0 3h-12v-1h12v1zm-2.091 6.223c2.047.478 4.805-.279 6.091-1.179-1.494 1.998-5.23 5.708-7.432 6.881 1.156-1.168 1.563-4.234 1.341-5.702z"/></svg>
|
After Width: | Height: | Size: 347 B |
1
harmonyqml/icons/room_view_history.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 12c0 6.627-5.373 12-12 12s-12-5.373-12-12h2c0 5.514 4.486 10 10 10s10-4.486 10-10-4.486-10-10-10c-2.777 0-5.287 1.141-7.099 2.977l2.061 2.061-6.962 1.354 1.305-7.013 2.179 2.18c2.172-2.196 5.182-3.559 8.516-3.559 6.627 0 12 5.373 12 12zm-13-6v8h7v-2h-5v-6h-2z"/></svg>
|
After Width: | Height: | Size: 364 B |
Before Width: | Height: | Size: 344 B After Width: | Height: | Size: 344 B |
1
harmonyqml/icons/room_view_notifications.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15.137 3.945c-.644-.374-1.042-1.07-1.041-1.82v-.003c.001-1.172-.938-2.122-2.096-2.122s-2.097.95-2.097 2.122v.003c.001.751-.396 1.446-1.041 1.82-4.667 2.712-1.985 11.715-6.862 13.306v1.749h20v-1.749c-4.877-1.591-2.195-10.594-6.863-13.306zm-3.137-2.945c.552 0 1 .449 1 1 0 .552-.448 1-1 1s-1-.448-1-1c0-.551.448-1 1-1zm3 20c0 1.598-1.392 3-2.971 3s-3.029-1.402-3.029-3h6z"/></svg>
|
After Width: | Height: | Size: 471 B |
1
harmonyqml/icons/room_view_settings.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M6 18h-2v5h-2v-5h-2v-3h6v3zm-2-17h-2v12h2v-12zm11 7h-6v3h2v12h2v-12h2v-3zm-2-7h-2v5h2v-5zm11 14h-6v3h2v5h2v-5h2v-3zm-2-14h-2v12h2v-12z"/></svg>
|
After Width: | Height: | Size: 235 B |