Refactor SidePane ListView in a flat way
Also adjust some colors (accentBackground) TODO: Repair Filter rooms field
This commit is contained in:
parent
543f7ac747
commit
2865d86d19
2
TODO.md
2
TODO.md
|
@ -33,7 +33,7 @@
|
|||
- Terrible performance using `QT_QPA_PLATFORM=wayland-egl`, must use `xcb`
|
||||
|
||||
- UI
|
||||
- Highlight selected account/room
|
||||
- Remove first html lists left margin
|
||||
|
||||
- Popup:
|
||||
- label size
|
||||
|
|
|
@ -167,13 +167,15 @@ class Backend:
|
|||
data.append({
|
||||
"type": "Account",
|
||||
"id": account.user_id,
|
||||
"user_id": account.user_id,
|
||||
"data": account.__dict__,
|
||||
})
|
||||
|
||||
for room in sorted(self.models[Room, account.user_id].values()):
|
||||
data.append({
|
||||
"type": "Room",
|
||||
"id": (account.user_id, room.room_id),
|
||||
"id": "/".join((account.user_id, room.room_id)),
|
||||
"user_id": account.user_id,
|
||||
"data": room.__dict__,
|
||||
})
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ CheckBox {
|
|||
anchors.centerIn: parent
|
||||
dimension: parent.width - 2
|
||||
svgName: "check-mark"
|
||||
colorize: theme.colors.accentText
|
||||
colorize: theme.colors.strongAccentBackground
|
||||
|
||||
visible: scale > 0
|
||||
scale: box.checked ? 1 : 0
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../Base"
|
||||
|
||||
Column {
|
||||
id: accountDelegate
|
||||
width: parent.width
|
||||
spacing: theme.spacing / 2
|
||||
|
||||
opacity:
|
||||
paneToolBar.roomFilter && roomList.model.count < 1 ? 0.3 : 1
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
|
||||
property alias roomList: roomList
|
||||
|
||||
property bool forceExpand: paneToolBar.roomFilter && roomList.model.count
|
||||
property bool expanded: true
|
||||
readonly property var modelItem: model
|
||||
|
||||
readonly property bool isCurrent:
|
||||
window.uiState.page == "Pages/EditAccount/EditAccount.qml" &&
|
||||
window.uiState.pageProperties.userId == model.user_id
|
||||
|
||||
Component.onCompleted:
|
||||
expanded = ! window.uiState.collapseAccounts[model.user_id]
|
||||
|
||||
onExpandedChanged: {
|
||||
window.uiState.collapseAccounts[model.user_id] = ! expanded
|
||||
window.uiStateChanged()
|
||||
}
|
||||
|
||||
function activate() {
|
||||
pageStack.showPage(
|
||||
"EditAccount/EditAccount", { "userId": model.user_id }
|
||||
)
|
||||
}
|
||||
|
||||
HInteractiveRectangle {
|
||||
id: rectangle
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
color: theme.sidePane.account.background
|
||||
|
||||
checked: accountDelegate.isCurrent
|
||||
|
||||
TapHandler { onTapped: accountDelegate.activate() }
|
||||
|
||||
HRowLayout {
|
||||
id: row
|
||||
width: parent.width
|
||||
|
||||
HUserAvatar {
|
||||
id: avatar
|
||||
userId: model.user_id
|
||||
displayName: model.display_name
|
||||
avatarUrl: model.avatar_url
|
||||
}
|
||||
|
||||
HLabel {
|
||||
id: accountLabel
|
||||
color: theme.sidePane.account.name
|
||||
text: model.display_name || model.user_id
|
||||
font.pixelSize: theme.fontSize.big
|
||||
elide: HLabel.ElideRight
|
||||
leftPadding: sidePane.currentSpacing
|
||||
rightPadding: leftPadding
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
ExpandButton {
|
||||
id: expandButton
|
||||
opacity: paneToolBar.roomFilter ? 0 : 1
|
||||
expandableItem: accountDelegate
|
||||
Layout.preferredHeight: row.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RoomList {
|
||||
id: roomList
|
||||
visible: height > 0
|
||||
width: parent.width
|
||||
height:
|
||||
childrenRect.height *
|
||||
(accountDelegate.expanded || accountDelegate.forceExpand ? 1 : 0)
|
||||
clip: heightAnimation.running
|
||||
|
||||
userId: modelItem.user_id
|
||||
|
||||
Behavior on height { HNumberAnimation { id: heightAnimation } }
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../Base"
|
||||
|
||||
HListView {
|
||||
id: accountList
|
||||
clip: true
|
||||
|
||||
model: HListModel {
|
||||
keyField: "user_id"
|
||||
source: modelSources["Account"] || []
|
||||
}
|
||||
|
||||
delegate: AccountDelegate {}
|
||||
}
|
21
src/qml/SidePane/AccountRoomList.qml
Normal file
21
src/qml/SidePane/AccountRoomList.qml
Normal file
|
@ -0,0 +1,21 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../Base"
|
||||
|
||||
HListView {
|
||||
id: accountRoomList
|
||||
|
||||
// property bool forceExpand: paneToolBar.roomFilter && roomList.model.count
|
||||
property bool forceExpand: false
|
||||
|
||||
model: HListModel {
|
||||
keyField: "id"
|
||||
source: window.sidePaneModelSource
|
||||
}
|
||||
|
||||
delegate: Loader {
|
||||
width: accountRoomList.width
|
||||
source: "Delegate" +
|
||||
(model.type == "Account" ? "Account.qml" : "Room.qml")
|
||||
}
|
||||
}
|
93
src/qml/SidePane/DelegateAccount.qml
Normal file
93
src/qml/SidePane/DelegateAccount.qml
Normal file
|
@ -0,0 +1,93 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../Base"
|
||||
|
||||
HInteractiveRectangle {
|
||||
id: accountDelegate
|
||||
height: row.height
|
||||
color: theme.sidePane.account.background
|
||||
|
||||
checked: accountDelegate.isCurrent
|
||||
readonly property bool isCurrent:
|
||||
window.uiState.page == "Pages/EditAccount/EditAccount.qml" &&
|
||||
window.uiState.pageProperties.userId == model.data.user_id
|
||||
|
||||
readonly property bool collapsed:
|
||||
! accountRoomList.forceExpand &&
|
||||
window.uiState.collapseAccounts[model.data.user_id] || false
|
||||
|
||||
function toggleCollapse() {
|
||||
window.uiState.collapseAccounts[model.data.user_id] = ! collapsed
|
||||
window.uiStateChanged()
|
||||
}
|
||||
|
||||
function activate() {
|
||||
pageStack.showPage(
|
||||
"EditAccount/EditAccount", { "userId": model.data.user_id }
|
||||
)
|
||||
}
|
||||
|
||||
TapHandler { onTapped: accountDelegate.activate() }
|
||||
|
||||
HRowLayout {
|
||||
id: row
|
||||
width: parent.width
|
||||
|
||||
HUserAvatar {
|
||||
id: avatar
|
||||
userId: model.data.user_id
|
||||
displayName: model.data.display_name
|
||||
avatarUrl: model.data.avatar_url
|
||||
|
||||
opacity: collapsed ? theme.sidePane.account.collapsedOpacity : 1
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
|
||||
Layout.topMargin: model.index > 0 ? sidePane.currentSpacing / 2 : 0
|
||||
Layout.bottomMargin: Layout.topMargin
|
||||
}
|
||||
|
||||
HLabel {
|
||||
id: accountLabel
|
||||
color: theme.sidePane.account.name
|
||||
text: model.data.display_name || model.data.user_id
|
||||
font.pixelSize: theme.fontSize.big
|
||||
elide: HLabel.ElideRight
|
||||
|
||||
leftPadding: sidePane.currentSpacing
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
opacity: collapsed ? theme.sidePane.account.collapsedOpacity : 1
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
HUIButton {
|
||||
id: expandButton
|
||||
iconName: "expand"
|
||||
iconDimension: 16
|
||||
backgroundColor: "transparent"
|
||||
leftPadding: sidePane.currentSpacing
|
||||
rightPadding: leftPadding
|
||||
onClicked: accountDelegate.toggleCollapse()
|
||||
|
||||
visible: opacity > 0
|
||||
opacity:
|
||||
accountRoomList.forceExpand ? 0 :
|
||||
collapsed ? theme.sidePane.account.collapsedOpacity + 0.2 :
|
||||
1
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
|
||||
iconTransform: Rotation {
|
||||
origin.x: expandButton.iconDimension / 2
|
||||
origin.y: expandButton.iconDimension / 2
|
||||
|
||||
angle: collapsed ? 180 : 90
|
||||
Behavior on angle { HNumberAnimation {} }
|
||||
}
|
||||
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,49 +5,58 @@ import "../utils.js" as Utils
|
|||
|
||||
HInteractiveRectangle {
|
||||
id: roomDelegate
|
||||
width: roomList.width
|
||||
height: rowLayout.height
|
||||
color: theme.sidePane.room.background
|
||||
|
||||
opacity: model.left ? theme.sidePane.room.leftRoomOpacity : 1
|
||||
readonly property bool collapsed:
|
||||
! accountRoomList.forceExpand &&
|
||||
window.uiState.collapseAccounts[model.user_id] || false
|
||||
|
||||
visible: height > 0
|
||||
height: collapsed ? 0 : rowLayout.height
|
||||
Behavior on height { HNumberAnimation {} }
|
||||
|
||||
opacity: model.data.left ? theme.sidePane.room.leftRoomOpacity : 1
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
|
||||
checked: isCurrent
|
||||
readonly property bool isCurrent:
|
||||
window.uiState.page == "Chat/Chat.qml" &&
|
||||
window.uiState.pageProperties.userId == userId &&
|
||||
window.uiState.pageProperties.roomId == model.room_id
|
||||
window.uiState.pageProperties.userId == model.user_id &&
|
||||
window.uiState.pageProperties.roomId == model.data.room_id
|
||||
|
||||
function activate() { pageStack.showRoom(userId, model.room_id) }
|
||||
function activate() {
|
||||
pageStack.showRoom(model.user_id, model.data.room_id)
|
||||
print(model.user_id, model.data.room_id)
|
||||
}
|
||||
|
||||
TapHandler { onTapped: activate() }
|
||||
|
||||
HRowLayout {
|
||||
id: rowLayout
|
||||
x: sidePane.currentSpacing
|
||||
width: parent.width - sidePane.currentSpacing * 1.5
|
||||
height: roomName.height + subtitle.height +
|
||||
sidePane.currentSpacing
|
||||
spacing: sidePane.currentSpacing
|
||||
x: spacing
|
||||
width: parent.width - spacing * 1.75
|
||||
height: roomName.height + subtitle.height + spacing
|
||||
|
||||
HRoomAvatar {
|
||||
id: roomAvatar
|
||||
displayName: model.display_name
|
||||
avatarUrl: model.avatar_url
|
||||
displayName: model.data.display_name
|
||||
avatarUrl: model.data.avatar_url
|
||||
}
|
||||
|
||||
HColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
HRowLayout {
|
||||
spacing: theme.spacing / 2
|
||||
spacing: rowLayout.spacing
|
||||
|
||||
HLabel {
|
||||
id: roomName
|
||||
color: theme.sidePane.room.name
|
||||
text: model.display_name || "<i>Empty room</i>"
|
||||
text: model.data.display_name || "<i>Empty room</i>"
|
||||
textFormat:
|
||||
model.display_name? Text.PlainText : Text.StyledText
|
||||
model.data.display_name?
|
||||
Text.PlainText : Text.StyledText
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
|
||||
|
@ -59,13 +68,15 @@ HInteractiveRectangle {
|
|||
|
||||
visible: Layout.maximumWidth > 0
|
||||
Layout.maximumWidth:
|
||||
model.inviter_id && ! model.left ? implicitWidth : 0
|
||||
model.data.inviter_id && ! model.data.left ?
|
||||
implicitWidth : 0
|
||||
Behavior on Layout.maximumWidth { HNumberAnimation {} }
|
||||
}
|
||||
|
||||
HLabel {
|
||||
readonly property var evDate:
|
||||
model.last_event ? model.last_event.date : null
|
||||
model.data.last_event ?
|
||||
model.data.last_event.date : null
|
||||
|
||||
id: lastEventDate
|
||||
font.pixelSize: theme.fontSize.small
|
||||
|
@ -97,9 +108,9 @@ HInteractiveRectangle {
|
|||
elide: Text.ElideRight
|
||||
|
||||
text: {
|
||||
if (! model.last_event) { return "" }
|
||||
if (! model.data.last_event) { return "" }
|
||||
|
||||
let ev = model.last_event
|
||||
let ev = model.data.last_event
|
||||
|
||||
if (ev.event_type === "RoomMessageEmote" ||
|
||||
! ev.event_type.startsWith("RoomMessage")) {
|
|
@ -1,23 +0,0 @@
|
|||
import QtQuick 2.12
|
||||
import "../Base"
|
||||
|
||||
HUIButton {
|
||||
property var expandableItem: null
|
||||
|
||||
id: expandButton
|
||||
iconName: "expand"
|
||||
iconDimension: 16
|
||||
backgroundColor: "transparent"
|
||||
onClicked: expandableItem.expanded = ! expandableItem.expanded
|
||||
|
||||
visible: opacity > 0
|
||||
opacity: expandableItem.forceExpand ? 0 : 1
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
|
||||
iconTransform: Rotation {
|
||||
origin.x: expandButton.iconDimension / 2
|
||||
origin.y: expandButton.iconDimension / 2
|
||||
angle: expandableItem.expanded || expandableItem.forceExpand ? 90 : 180
|
||||
Behavior on angle { HNumberAnimation {} }
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
import QtQuick 2.12
|
||||
import "../Base"
|
||||
import "../utils.js" as Utils
|
||||
|
||||
HFixedListView {
|
||||
id: roomList
|
||||
|
||||
property string userId: ""
|
||||
|
||||
model: HListModel {
|
||||
source: Utils.filterModelSource(
|
||||
modelSources[["Room", userId]] || [],
|
||||
paneToolBar.roomFilter,
|
||||
)
|
||||
keyField: "room_id"
|
||||
}
|
||||
|
||||
delegate: RoomDelegate {}
|
||||
}
|
|
@ -5,13 +5,13 @@ import "../utils.js" as Utils
|
|||
|
||||
HRectangle {
|
||||
id: sidePane
|
||||
clip: true // Avoid artifacts when collapsed
|
||||
clip: true
|
||||
opacity: mainUI.accountsPresent && ! reduce ? 1 : 0
|
||||
visible: opacity > 0
|
||||
|
||||
color: theme.sidePane.background
|
||||
|
||||
property alias accountList: accountList
|
||||
property alias accountRoomList: accountRoomList
|
||||
property alias paneToolBar: paneToolBar
|
||||
|
||||
property real autoWidthRatio: theme.sidePane.autoWidthRatio
|
||||
|
@ -142,13 +142,12 @@ HRectangle {
|
|||
HColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
AccountList {
|
||||
id: accountList
|
||||
AccountRoomList {
|
||||
id: accountRoomList
|
||||
clip: true
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
spacing: currentSpacing
|
||||
bottomMargin: currentSpacing
|
||||
}
|
||||
|
||||
PaneToolBar {
|
||||
|
|
|
@ -15,6 +15,7 @@ ApplicationWindow {
|
|||
// Note: For JS object variables, the corresponding method to notify
|
||||
// key/value changes must be called manually, e.g. settingsChanged().
|
||||
property var modelSources: ({})
|
||||
property var sidePaneModelSource: []
|
||||
|
||||
property var mainUI: null
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ function onCoroutineDone(uuid, result) {
|
|||
function onModelUpdated(syncId, data, serializedSyncId) {
|
||||
if (serializedSyncId == ["Account"] || serializedSyncId[0] == "Room") {
|
||||
py.callCoro("get_flat_sidepane_data", [], data => {
|
||||
print( JSON.stringify( data, null, 4))
|
||||
window.sidePaneModelSource = data
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,12 @@ colors:
|
|||
color inputBackground:
|
||||
hsluv(hue, saturation, intensity * 2, Math.min(0.6, opacity))
|
||||
|
||||
color accentBackground:
|
||||
hsluv(hue, saturation * 1.25, intensity * 42, Math.min(0.6, opacity))
|
||||
|
||||
color strongAccentBackground:
|
||||
hsluv(hue, saturation * 2, intensity * 52, Math.min(0.6, opacity))
|
||||
|
||||
color brightText: hsluv(0, 0, intensity * 100)
|
||||
color text: hsluv(0, 0, intensity * 80)
|
||||
color halfDimText: hsluv(0, 0, intensity * 70)
|
||||
|
@ -83,10 +89,9 @@ controls:
|
|||
|
||||
button:
|
||||
color background: colors.inputBackground
|
||||
color checkedBackground: colors.accentBackground
|
||||
color disabledBackground:
|
||||
hsluv(0, 0, colors.intensity * 2, Math.min(0.6, opacity))
|
||||
color checkedBackground:
|
||||
hsluv(0, 0, colors.intensity * 40, Math.min(0.6, opacity))
|
||||
|
||||
color hoveredOverlay: hsluv(0, 0, 100)
|
||||
color text: colors.text
|
||||
|
@ -95,13 +100,13 @@ controls:
|
|||
interactiveRectangle:
|
||||
color background: "transparent"
|
||||
|
||||
color hoveredOverlay: hsluv(0, 0, 100)
|
||||
color pressedOverlay: hsluv(0, 0, 100)
|
||||
color checkedOverlay: hsluv(0, 0, 100)
|
||||
color hoveredOverlay: hsluv(0, 0, 50)
|
||||
color pressedOverlay: hsluv(0, 0, 50)
|
||||
color checkedOverlay: hsluv(0, 0, 50)
|
||||
|
||||
real hoveredOpacity: 0.1
|
||||
real hoveredOpacity: 0.3
|
||||
real pressedOpacity: 0.2
|
||||
real checkedOpacity: 0.08
|
||||
real checkedOpacity: 0.2
|
||||
|
||||
textField:
|
||||
color background: colors.inputBackground
|
||||
|
@ -109,7 +114,7 @@ controls:
|
|||
|
||||
int borderWidth: 1
|
||||
color border: "transparent"
|
||||
color focusedBorder: colors.accentText
|
||||
color focusedBorder: colors.strongAccentBackground
|
||||
|
||||
color text: colors.text
|
||||
color focusedText: colors.text
|
||||
|
@ -158,6 +163,7 @@ sidePane:
|
|||
color background: colors.strongBackground
|
||||
|
||||
account:
|
||||
real collapsedOpacity: 0.3
|
||||
color background: "transparent"
|
||||
color name: colors.text
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user