Use an horizontal bar for accounts
This commit is contained in:
parent
8e0c046cdb
commit
fe18b725a5
2
TODO.md
2
TODO.md
|
@ -5,6 +5,8 @@
|
|||
- fix left rooms opacity
|
||||
- fix escape keybinds (filter rooms, message selection)
|
||||
- fix python getting stuck when loading large room
|
||||
- fix accounts in room list not getting their profile updated if mirage starts
|
||||
with a filter
|
||||
|
||||
- account delegates refactor
|
||||
- lag when switching accounts
|
||||
|
|
140
src/gui/Base/HGridView.qml
Normal file
140
src/gui/Base/HGridView.qml
Normal file
|
@ -0,0 +1,140 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
GridView {
|
||||
id: gridView
|
||||
interactive: allowDragging
|
||||
currentIndex: -1
|
||||
keyNavigationWraps: true
|
||||
highlightMoveDuration: theme.animationDuration
|
||||
|
||||
// Keep highlighted delegate at the center
|
||||
highlightRangeMode: GridView.ApplyRange
|
||||
preferredHighlightBegin: height / 2 - currentItemHeight / 2
|
||||
preferredHighlightEnd: height / 2 + currentItemHeight / 2
|
||||
|
||||
maximumFlickVelocity: 4000
|
||||
|
||||
|
||||
highlight: Rectangle {
|
||||
color: theme.controls.gridView.highlight
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
visible: gridView.interactive || ! gridView.allowDragging
|
||||
}
|
||||
|
||||
// property bool debug: false
|
||||
|
||||
// https://doc.qt.io/qt-5/qml-qtquick-viewtransition.html
|
||||
// #handling-interrupted-animations
|
||||
add: Transition {
|
||||
// ScriptAction { script: if (gridView.debug) print("add") }
|
||||
HNumberAnimation { property: "opacity"; from: 0; to: 1 }
|
||||
HNumberAnimation { property: "scale"; from: 0; to: 1 }
|
||||
}
|
||||
|
||||
move: Transition {
|
||||
// ScriptAction { script: if (gridView.debug) print("move") }
|
||||
HNumberAnimation { property: "opacity"; to: 1 }
|
||||
HNumberAnimation { property: "scale"; to: 1 }
|
||||
HNumberAnimation { properties: "x,y" }
|
||||
}
|
||||
|
||||
remove: Transition {
|
||||
// ScriptAction { script: if (gridView.debug) print("remove") }
|
||||
HNumberAnimation { property: "opacity"; to: 0 }
|
||||
HNumberAnimation { property: "scale"; to: 0 }
|
||||
}
|
||||
|
||||
displaced: Transition {
|
||||
// ScriptAction { script: if (gridView.debug) print("displaced") }
|
||||
HNumberAnimation { property: "opacity"; to: 1 }
|
||||
HNumberAnimation { property: "scale"; to: 1 }
|
||||
HNumberAnimation { properties: "x,y" }
|
||||
}
|
||||
|
||||
onSelectedCountChanged: if (! selectedCount) lastCheckedDelegateIndex = 0
|
||||
|
||||
|
||||
property bool allowDragging: true
|
||||
property alias cursorShape: mouseArea.cursorShape
|
||||
property int currentItemHeight: currentItem ? currentItem.height : 0
|
||||
|
||||
property var checked: ({})
|
||||
property int lastCheckedDelegateIndex: 0
|
||||
property int selectedCount: Object.keys(checked).length
|
||||
|
||||
|
||||
function check(...indices) {
|
||||
for (const i of indices) {
|
||||
const model = gridView.model.get(i)
|
||||
checked[model.id] = model
|
||||
}
|
||||
|
||||
lastCheckedDelegateIndex = indices.slice(-1)[0]
|
||||
checkedChanged()
|
||||
}
|
||||
|
||||
function checkFromLastToHere(here) {
|
||||
const indices = utils.range(lastCheckedDelegateIndex, here)
|
||||
eventList.check(...indices)
|
||||
}
|
||||
|
||||
function uncheck(...indices) {
|
||||
for (const i of indices) {
|
||||
const model = gridView.model.get(i)
|
||||
delete checked[model.id]
|
||||
}
|
||||
|
||||
checkedChanged()
|
||||
}
|
||||
|
||||
function toggleCheck(...indices) {
|
||||
const checkedIndices = []
|
||||
|
||||
for (const i of indices) {
|
||||
const model = gridView.model.get(i)
|
||||
|
||||
if (model.id in checked) {
|
||||
delete checked[model.id]
|
||||
} else {
|
||||
checked[model.id] = model
|
||||
checkedIndices.push(i)
|
||||
}
|
||||
}
|
||||
|
||||
if (checkedIndices.length > 0)
|
||||
lastCheckedDelegateIndex = checkedIndices.slice(-1)[0]
|
||||
|
||||
checkedChanged()
|
||||
}
|
||||
|
||||
function getSortedChecked() {
|
||||
return Object.values(checked).sort(
|
||||
(a, b) => a.date > b.date ? 1 : -1
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Connections {
|
||||
target: gridView
|
||||
enabled: ! gridView.allowDragging
|
||||
// interactive gets temporarily set to true below to allow wheel scroll
|
||||
onDraggingChanged: gridView.interactive = false
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
enabled: ! parent.allowDragging || cursorShape !== Qt.ArrowCursor
|
||||
acceptedButtons: Qt.NoButton
|
||||
onWheel: {
|
||||
// Allow wheel usage, will be back to false on any drag attempt
|
||||
parent.interactive = true
|
||||
wheel.accepted = false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,8 +31,6 @@ ListView {
|
|||
|
||||
// https://doc.qt.io/qt-5/qml-qtquick-viewtransition.html
|
||||
// #handling-interrupted-animations
|
||||
// XXX: add transitions are buggy when using DelegateModel, `add` should be
|
||||
// set to `null` and delegates should have `ListView.onAdd: ...` instead.
|
||||
add: Transition {
|
||||
// ScriptAction { script: if (listView.debug) print("add") }
|
||||
HNumberAnimation { property: "opacity"; from: 0; to: 1 }
|
||||
|
|
|
@ -5,11 +5,11 @@ import QtQuick.Layouts 1.12
|
|||
import "../Base"
|
||||
import "../Base/HTile"
|
||||
|
||||
HTile {
|
||||
HTileDelegate {
|
||||
id: account
|
||||
implicitHeight: theme.baseElementsHeight
|
||||
backgroundColor: theme.accountView.account.background
|
||||
padded: false
|
||||
leftPadding: theme.spacing
|
||||
rightPadding: 0 // the "add chat" button has padding
|
||||
|
||||
contentItem: ContentRow {
|
||||
tile: account
|
||||
|
|
|
@ -2,33 +2,36 @@
|
|||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import ".."
|
||||
import "../Base"
|
||||
import "../Base/HTile"
|
||||
|
||||
HColumnLayout {
|
||||
|
||||
Rectangle {
|
||||
implicitHeight: accountList.count >= 2 ? accountList.contentHeight : 0
|
||||
color: theme.accountsBar.accountList.background
|
||||
|
||||
|
||||
property RoomList roomList
|
||||
readonly property alias accountList: accountList
|
||||
|
||||
|
||||
HButton {
|
||||
id: addAccountButton
|
||||
icon.name: "add-account"
|
||||
toolTip.text: qsTr("Add another account")
|
||||
backgroundColor: theme.accountsBar.addAccountButtonBackground
|
||||
onClicked: pageLoader.showPage("AddAccount/AddAccount")
|
||||
Behavior on implicitHeight { HNumberAnimation {} }
|
||||
|
||||
Layout.preferredHeight: theme.baseElementsHeight
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.keys.addNewAccount
|
||||
onActivated: addAccountButton.clicked()
|
||||
}
|
||||
}
|
||||
|
||||
HListView {
|
||||
HGridView {
|
||||
id: accountList
|
||||
anchors.centerIn: parent
|
||||
width: Math.min(cellWidth * count, parent.width)
|
||||
height: parent.height
|
||||
// anchors.topMargin: theme.spacing / 2
|
||||
// anchors.bottomMargin: anchors.topMargin
|
||||
// anchors.leftMargin: -theme.spacing / 2
|
||||
// anchors.rightMargin: anchors.leftMargin
|
||||
|
||||
|
||||
clip: true
|
||||
cellWidth: theme.controls.avatar.size + theme.spacing
|
||||
cellHeight: cellWidth
|
||||
currentIndex:
|
||||
roomList.count === 0 || roomList.currentIndex === -1 ?
|
||||
-1 :
|
||||
|
@ -42,29 +45,23 @@ HColumnLayout {
|
|||
|
||||
delegate: HTileDelegate {
|
||||
id: tile
|
||||
width: accountList.width
|
||||
backgroundColor:
|
||||
theme.accountsBar.accountList.account.background
|
||||
|
||||
topPadding: (accountList.width - avatar.width) / 4
|
||||
bottomPadding: topPadding
|
||||
leftPadding: 0
|
||||
rightPadding: leftPadding
|
||||
width: accountList.cellWidth
|
||||
height: accountList.cellHeight
|
||||
padded: false
|
||||
backgroundColor: theme.accountsBar.accountList.account.background
|
||||
|
||||
contentItem: Item {
|
||||
id: tileContent
|
||||
implicitHeight: avatar.height
|
||||
|
||||
HUserAvatar {
|
||||
id: avatar
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.centerIn: parent
|
||||
userId: model.id
|
||||
displayName: model.display_name
|
||||
mxc: model.avatar_url
|
||||
// compact: tile.compact
|
||||
|
||||
radius:
|
||||
theme.accountsBar.accountList.account.avatarRadius
|
||||
radius: theme.accountsBar.accountList.account.avatarRadius
|
||||
}
|
||||
|
||||
MessageIndicator {
|
||||
|
@ -78,16 +75,15 @@ HColumnLayout {
|
|||
}
|
||||
|
||||
HLoader {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin:
|
||||
accountList.highlightItem ?
|
||||
accountList.highlightItem.border.width :
|
||||
0
|
||||
|
||||
visible: false // XXX
|
||||
anchors.centerIn: parent
|
||||
width: avatar.width
|
||||
height: avatar.height
|
||||
opacity: model.first_sync_done ? 0 : 1
|
||||
|
||||
active: opacity > 0
|
||||
sourceComponent: Rectangle {
|
||||
radius: avatar.radius
|
||||
color: utils.hsluv(0, 0, 0, 0.5)
|
||||
|
||||
HBusyIndicator {
|
||||
|
@ -118,14 +114,14 @@ HColumnLayout {
|
|||
|
||||
Rectangle {
|
||||
id: border
|
||||
width: theme.accountsBar.accountList.account.selectedBorderSize
|
||||
height: parent.height
|
||||
anchors.bottom: parent.bottom
|
||||
width: parent.width
|
||||
height:
|
||||
theme.accountsBar.accountList.account.selectedBorderSize
|
||||
color: theme.accountsBar.accountList.account.selectedBorder
|
||||
}
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.keys.goToPreviousAccount
|
||||
|
@ -142,22 +138,30 @@ HColumnLayout {
|
|||
accountList.currentItem.leftClicked()
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
z: -100
|
||||
color: theme.accountsBar.accountList.background
|
||||
}
|
||||
}
|
||||
|
||||
HButton {
|
||||
id: settingsButton
|
||||
backgroundColor: theme.accountsBar.settingsButtonBackground
|
||||
icon.name: "settings"
|
||||
toolTip.text: qsTr("Open config folder")
|
||||
|
||||
onClicked: py.callCoro("get_config_dir", [], Qt.openUrlExternally)
|
||||
|
||||
Layout.preferredHeight: theme.baseElementsHeight
|
||||
}
|
||||
}
|
||||
|
||||
// HButton {
|
||||
// id: settingsButton
|
||||
// backgroundColor: theme.accountsBar.settingsButtonBackground
|
||||
// icon.name: "settings"
|
||||
// toolTip.text: qsTr("Open config folder")
|
||||
|
||||
// onClicked: py.callCoro("get_config_dir", [], Qt.openUrlExternally)
|
||||
|
||||
// Layout.preferredHeight: theme.baseElementsHeight
|
||||
// }
|
||||
// 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()
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -20,7 +20,7 @@ HTextField {
|
|||
|
||||
Keys.onEnterPressed: Keys.onReturnPressed(event)
|
||||
Keys.onReturnPressed: {
|
||||
roomList.showRoomAtIndex()
|
||||
roomList.showItemAtIndex()
|
||||
if (window.settings.clearRoomFilterOnEnter) text = ""
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,9 @@ HDrawer {
|
|||
id: mainPane
|
||||
saveName: "mainPane"
|
||||
background: null
|
||||
minimumSize:
|
||||
accountBar.width + theme.controls.avatar.size + theme.spacing * 2
|
||||
minimumSize: theme.controls.avatar.size + theme.spacing * 2
|
||||
|
||||
readonly property alias accountBar: accountBar
|
||||
readonly property alias accountsBar: accountsBar
|
||||
readonly property alias roomList: roomList
|
||||
readonly property alias filterRoomsField: filterRoomsField
|
||||
|
||||
|
@ -23,32 +22,36 @@ HDrawer {
|
|||
when: ! mainUI.accountsPresent
|
||||
}
|
||||
|
||||
HRowLayout {
|
||||
HColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
AccountsBar {
|
||||
id: accountBar
|
||||
roomList: roomList
|
||||
|
||||
Layout.fillWidth: false
|
||||
TopBar {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: theme.baseElementsHeight
|
||||
}
|
||||
|
||||
HColumnLayout {
|
||||
RoomList {
|
||||
id: roomList
|
||||
clip: true
|
||||
filter: filterRoomsField.text
|
||||
AccountsBar {
|
||||
id: accountsBar
|
||||
roomList: roomList
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumHeight: parent.height / 3
|
||||
}
|
||||
|
||||
FilterRoomsField {
|
||||
id: filterRoomsField
|
||||
roomList: roomList
|
||||
RoomList {
|
||||
id: roomList
|
||||
clip: true
|
||||
filter: filterRoomsField.text
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
FilterRoomsField {
|
||||
id: filterRoomsField
|
||||
roomList: roomList
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ import "../Base/HTile"
|
|||
HTileDelegate {
|
||||
id: room
|
||||
backgroundColor: theme.accountView.roomList.room.background
|
||||
leftPadding: theme.spacing * 2
|
||||
rightPadding: theme.spacing
|
||||
opacity:
|
||||
model.left ? theme.accountView.roomList.room.leftRoomOpacity : 1
|
||||
|
||||
|
|
63
src/gui/MainPane/TopBar.qml
Normal file
63
src/gui/MainPane/TopBar.qml
Normal file
|
@ -0,0 +1,63 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../Base"
|
||||
|
||||
Rectangle {
|
||||
clip: true
|
||||
color: theme.mainPaneTopBar.background
|
||||
|
||||
HRowLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
HButton {
|
||||
backgroundColor: "transparent"
|
||||
icon.name: "settings"
|
||||
toolTip.text: qsTr("Open config folder")
|
||||
|
||||
onClicked: py.callCoro("get_config_dir", [], Qt.openUrlExternally)
|
||||
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
HButton {
|
||||
backgroundColor: "transparent"
|
||||
|
||||
text: qsTr("%1 %2")
|
||||
.arg(Qt.application.displayName).arg(Qt.application.version)
|
||||
label.color: theme.mainPaneTopBar.nameVersionLabel
|
||||
toolTip.text: qsTr("Open project repository")
|
||||
|
||||
onClicked:
|
||||
Qt.openUrlExternally("https://github.com/mirukana/mirage")
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
HButton {
|
||||
backgroundColor: "transparent"
|
||||
icon.name: "reload-config-files"
|
||||
toolTip.text: qsTr("Reload config files")
|
||||
|
||||
onClicked: mainUI.reloadSettings()
|
||||
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
HButton {
|
||||
visible: Layout.preferredWidth > 0
|
||||
backgroundColor: "transparent"
|
||||
icon.name: "go-back-to-chat-from-main-pane"
|
||||
toolTip.text: qsTr("Go back to room")
|
||||
|
||||
onClicked: mainPane.toggleFocus()
|
||||
|
||||
Layout.preferredWidth: mainPane.collapse ? implicitWidth : 0
|
||||
Layout.fillHeight: true
|
||||
|
||||
Behavior on Layout.preferredWidth { HNumberAnimation {} }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -273,6 +273,9 @@ ui:
|
|||
// color gradientStartColor: hsluv(0, 0, 0, 0.5)
|
||||
// color gradientEndColor: hsluv(0, 0, 0, 0.5)
|
||||
|
||||
mainPaneTopBar:
|
||||
color background: colors.strongBackground
|
||||
color nameVersionLabel: colors.text
|
||||
|
||||
accountsBar:
|
||||
color everyRoomButtonBackground: colors.strongerBackground
|
||||
|
@ -280,7 +283,7 @@ accountsBar:
|
|||
color settingsButtonBackground: colors.strongerBackground
|
||||
|
||||
accountList:
|
||||
color background: colors.strongerBackground
|
||||
color background: colors.mediumBackground
|
||||
|
||||
account:
|
||||
color background: "transparent"
|
||||
|
@ -294,7 +297,7 @@ accountsBar:
|
|||
|
||||
accountView:
|
||||
account:
|
||||
color background: colors.strongBackground
|
||||
color background: "transparent"
|
||||
color name: colors.text
|
||||
|
||||
unreadIndicator:
|
||||
|
|
Loading…
Reference in New Issue
Block a user