From 158942d1b5fc59ff466e1752949864794fb6c62e Mon Sep 17 00:00:00 2001 From: James Graham Date: Fri, 29 Mar 2024 09:09:13 +0000 Subject: [PATCH] UserInfo compact Make UserInfo work in compact mode. This includes showing the account switch popup in a dialog BUG: 482261 --- src/CMakeLists.txt | 1 + src/qml/AccountSwitchDialog.qml | 147 ++++++++++++++ src/qml/RoomListPage.qml | 4 +- src/qml/UserInfo.qml | 285 ++++++++-------------------- src/qml/UserInfoDesktop.qml | 3 + src/settings/NeoChatGeneralPage.qml | 9 + 6 files changed, 235 insertions(+), 214 deletions(-) create mode 100644 src/qml/AccountSwitchDialog.qml diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9b53b8480..5caa0fa9c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -287,6 +287,7 @@ qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN qml/QrScannerPage.qml qml/JoinRoomDialog.qml qml/ConfirmUrlDialog.qml + qml/AccountSwitchDialog.qml RESOURCES qml/confetti.png qml/glowdot.png diff --git a/src/qml/AccountSwitchDialog.qml b/src/qml/AccountSwitchDialog.qml new file mode 100644 index 000000000..e7fef8098 --- /dev/null +++ b/src/qml/AccountSwitchDialog.qml @@ -0,0 +1,147 @@ +// SPDX-FileCopyrightText: 2024 James Graham +// SPDX-License-Identifier: GPL-2.0-or-later + +import QtQuick +import QtQuick.Layouts + +import org.kde.kirigami as Kirigami + +import org.kde.kirigamiaddons.labs.components as KirigamiComponents +import org.kde.kirigamiaddons.delegates as Delegates + +import org.kde.neochat +import org.kde.neochat.accounts + +Kirigami.Dialog { + id: root + + required property NeoChatConnection connection + + parent: applicationWindow().overlay + + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + standardButtons: Kirigami.Dialog.NoButton + + width: Math.min(applicationWindow().width, Kirigami.Units.gridUnit * 24) + title: i18nc("@title: dialog to switch between logged in accounts", "Switch Account") + + onVisibleChanged: if (visible) { + accountView.forceActiveFocus() + } + + contentItem: ListView { + id: accountView + property var addAccount + + implicitHeight: contentHeight + + Kirigami.Theme.colorSet: Kirigami.Theme.View + Kirigami.Theme.inherit: false + + footer: Delegates.RoundedItemDelegate { + id: addDelegate + width: parent.width + highlighted: focus && !accountView.addAccount.pressed + Component.onCompleted: accountView.addAccount = this + icon { + name: "list-add" + width: Kirigami.Units.iconSizes.smallMedium + height: Kirigami.Units.iconSizes.smallMedium + } + text: i18nc("@button: login to or register a new account.", "Add Account") + contentItem: Delegates.SubtitleContentItem { + itemDelegate: parent + subtitle: i18n("Log in or create a new account") + labelItem.textFormat: Text.PlainText + subtitleItem.textFormat: Text.PlainText + } + + onClicked: { + pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'WelcomePage.qml'), {}, { + title: i18nc("@title:window", "Login") + }); + if (switchUserButton.checked) { + switchUserButton.checked = false; + } + accountView.currentIndex = Controller.activeConnectionIndex; + } + Keys.onUpPressed: { + accountView.currentIndex = accountView.count - 1; + accountView.forceActiveFocus(); + } + Keys.onDownPressed: { + accountView.currentIndex = 0; + accountView.forceActiveFocus(); + } + } + clip: true + model: AccountRegistry + + keyNavigationEnabled: false + Keys.onDownPressed: { + if (accountView.currentIndex === accountView.count - 1) { + accountView.addAccount.forceActiveFocus(); + accountView.currentIndex = -1; + } else { + accountView.incrementCurrentIndex(); + } + } + Keys.onUpPressed: { + if (accountView.currentIndex === 0) { + accountView.addAccount.forceActiveFocus(); + accountView.currentIndex = -1; + } else { + accountView.decrementCurrentIndex(); + } + } + Keys.onEnterPressed: accountView.currentItem.clicked() + Keys.onReturnPressed: accountView.currentItem.clicked() + + onVisibleChanged: { + for (let i = 0; i < accountView.count; i++) { + if (model.data(model.index(i, 0), Qt.DisplayRole) === root.connection.localUser.id) { + accountView.currentIndex = i; + break; + } + } + } + + delegate: Delegates.RoundedItemDelegate { + id: userDelegate + + required property NeoChatConnection connection + + width: parent.width + text: connection.localUser.displayName + + contentItem: RowLayout { + KirigamiComponents.Avatar { + implicitWidth: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing + implicitHeight: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing + sourceSize { + width: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing + height: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing + } + source: userDelegate.connection.localUser.avatarMediaId ? ("image://mxc/" + userDelegate.connection.localUser.avatarMediaId) : "" + name: userDelegate.connection.localUser.displayName ?? userDelegate.connection.localUser.id + } + + Delegates.SubtitleContentItem { + itemDelegate: userDelegate + subtitle: userDelegate.connection.localUser.id + labelItem.textFormat: Text.PlainText + subtitleItem.textFormat: Text.PlainText + } + } + + onClicked: { + Controller.activeConnection = userDelegate.connection; + root.close() + } + } + } +} diff --git a/src/qml/RoomListPage.qml b/src/qml/RoomListPage.qml index 3844cf066..9f31cc46b 100644 --- a/src/qml/RoomListPage.qml +++ b/src/qml/RoomListPage.qml @@ -264,7 +264,6 @@ Kirigami.Page { footer: Loader { width: parent.width - active: !root.collapsed sourceComponent: Kirigami.Settings.isMobile ? exploreComponentMobile : userInfoDesktop } @@ -314,7 +313,6 @@ Kirigami.Page { Component { id: userInfo UserInfo { - visible: !root.collapsed bottomEdge: false connection: root.connection } @@ -323,8 +321,8 @@ Kirigami.Page { Component { id: userInfoDesktop UserInfoDesktop { - visible: !root.collapsed connection: root.connection + collapsed: root.collapsed } } diff --git a/src/qml/UserInfo.qml b/src/qml/UserInfo.qml index a3832357a..8203a61d3 100644 --- a/src/qml/UserInfo.qml +++ b/src/qml/UserInfo.qml @@ -18,6 +18,8 @@ RowLayout { required property NeoChatConnection connection + property bool collapsed: false + property bool bottomEdge: true property var addAccount @@ -26,6 +28,7 @@ RowLayout { Layout.topMargin: Kirigami.Units.smallSpacing Layout.bottomMargin: Kirigami.Units.smallSpacing + Layout.rightMargin: Kirigami.Units.largeSpacing Layout.minimumHeight: bottomEdge ? Kirigami.Units.gridUnit * 2 : -1 onVisibleChanged: { @@ -73,242 +76,102 @@ RowLayout { ColumnLayout { Layout.fillWidth: true + Layout.maximumWidth: Math.round(root.width * 0.55) + visible: !root.collapsed spacing: 0 QQC2.Label { id: displayNameLabel + Layout.fillWidth: true text: root.connection.localUser.displayName textFormat: Text.PlainText elide: Text.ElideRight - Layout.fillWidth: true } QQC2.Label { + id: idLabel + Layout.fillWidth: true text: (root.connection.label.length > 0 ? (root.connection.label + " ") : "") + root.connection.localUser.id font.pointSize: displayNameLabel.font.pointSize * 0.8 opacity: 0.7 textFormat: Text.PlainText elide: Text.ElideRight - Layout.fillWidth: true } } - QQC2.ToolButton { - id: switchUserButton - icon.name: "system-switch-user" - checkable: true - text: i18n("Switch User") - display: QQC2.AbstractButton.IconOnly - Accessible.name: text - QQC2.ToolTip.text: text - QQC2.ToolTip.visible: hovered - QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay - Layout.minimumWidth: Layout.preferredWidth - Layout.alignment: Qt.AlignRight + Kirigami.ActionToolBar { + alignment: Qt.AlignRight + display: QQC2.Button.IconOnly + + actions: [ + Kirigami.Action { + id: switchUserButton + text: i18n("Switch User") + icon.name: "system-switch-user" + onTriggered: accountSwitchDialog.createObject(QQC2.ApplicationWindow.overlay, { + connection: root.connection + }).open(); + }, + Kirigami.Action { + text: i18n("Open Settings") + icon.name: "settings-configure" + onTriggered: pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat.settings', 'NeoChatSettings.qml'), { + connection: root.connection + }, { + title: i18n("Configure"), + width: Kirigami.Units.gridUnit * 50, + height: Kirigami.Units.gridUnit * 42 + }) + } + ] + Shortcut { sequence: "Ctrl+U" onActivated: switchUserButton.toggle() } } - QQC2.ToolButton { - icon.name: "list-add" - onClicked: ; //TODO - text: i18n("Add") //TODO find better message - display: QQC2.AbstractButton.IconOnly - QQC2.ToolTip.text: text - QQC2.ToolTip.visible: hovered - QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay - Layout.minimumWidth: Layout.preferredWidth - Layout.alignment: Qt.AlignRight - visible: false - } - QQC2.ToolButton { - visible: Config.developerTools - icon.name: "tools" - onClicked: applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'DevtoolsPage.qml'), { - connection: root.connection - }, { - title: i18n("Developer Tools") - }); - text: i18n("Open developer tools") - display: QQC2.AbstractButton.IconOnly - Layout.minimumWidth: Layout.preferredWidth - Layout.alignment: Qt.AlignRight - QQC2.ToolTip.text: text - QQC2.ToolTip.visible: hovered - QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay - } - QQC2.ToolButton { - icon.name: "settings-configure" - onClicked: pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat.settings', 'NeoChatSettings.qml'), { - connection: root.connection - }, { - title: i18n("Configure"), - width: Kirigami.Units.gridUnit * 50, - height: Kirigami.Units.gridUnit * 42 - }) - text: i18n("Open Settings") - display: QQC2.AbstractButton.IconOnly - Layout.minimumWidth: Layout.preferredWidth - Layout.alignment: Qt.AlignRight - QQC2.ToolTip.text: text - QQC2.ToolTip.visible: hovered - QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay - } - Item { - width: 1 - } + // QQC2.ToolButton { + // Layout.alignment: Qt.AlignRight + // display: QQC2.AbstractButton.IconOnly + // action: Kirigami.Action { + // id: switchUserButton + // text: i18n("Switch User") + // icon.name: "system-switch-user" + // onTriggered: accountSwitchDialog.createObject(QQC2.ApplicationWindow.overlay, { + // connection: root.connection + // }).open(); + // } + // QQC2.ToolTip.text: text + // QQC2.ToolTip.visible: hovered + // QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay + // Shortcut { + // sequence: "Ctrl+U" + // onActivated: switchUserButton.trigger() + // } + // } + // QQC2.ToolButton { + // Layout.alignment: Qt.AlignRight + // display: QQC2.AbstractButton.IconOnly + // action: Kirigami.Action { + // text: i18n("Open Settings") + // icon.name: "settings-configure" + // onTriggered: pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat.settings', 'NeoChatSettings.qml'), { + // connection: root.connection + // }, { + // title: i18n("Configure"), + // width: Kirigami.Units.gridUnit * 50, + // height: Kirigami.Units.gridUnit * 42 + // }) + // } + // QQC2.ToolTip.text: text + // QQC2.ToolTip.visible: hovered + // QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay + // } AccountMenu { id: accountMenu y: root.bottomEdge ? -height : accountButton.height connection: root.connection } - QQC2.Popup { - id: accountsPopup - parent: root - - visible: switchUserButton.checked - onVisibleChanged: if (visible) - accounts.forceActiveFocus() - - x: -Kirigami.Units.smallSpacing - y: root.bottomEdge ? -height - Kirigami.Units.smallSpacing - 1 : root.height + Kirigami.Units.smallSpacing - 1 - width: root.width + (root.bottomEdge ? 0 : Kirigami.Units.smallSpacing * 2) - leftPadding: 0 - rightPadding: 0 - bottomPadding: Kirigami.Units.smallSpacing - topPadding: Kirigami.Units.smallSpacing - - closePolicy: QQC2.Popup.CloseOnEscape - - contentItem: ListView { - id: accounts - implicitHeight: contentHeight - - header: Kirigami.Separator {} - - footer: Delegates.RoundedItemDelegate { - id: addButton - width: parent.width - highlighted: focus || (addAccount.highlighted || addAccount.ListView.isCurrentItem) && !addAccount.pressed - Component.onCompleted: root.addAccount = this - icon { - name: "list-add" - width: Kirigami.Units.iconSizes.smallMedium - height: Kirigami.Units.iconSizes.smallMedium - } - text: i18n("Add Account") - contentItem: Delegates.SubtitleContentItem { - itemDelegate: parent - subtitle: i18n("Log in to an existing account") - labelItem.textFormat: Text.PlainText - subtitleItem.textFormat: Text.PlainText - } - - onClicked: { - pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'WelcomePage.qml'), {}, { - title: i18nc("@title:window", "Login") - }); - if (switchUserButton.checked) { - switchUserButton.checked = false; - } - accounts.currentIndex = Controller.activeConnectionIndex; - } - Keys.onUpPressed: { - accounts.currentIndex = accounts.count - 1; - accounts.forceActiveFocus(); - } - Keys.onDownPressed: { - accounts.currentIndex = 0; - accounts.forceActiveFocus(); - } - } - clip: true - model: AccountRegistry - - keyNavigationEnabled: false - Keys.onDownPressed: { - if (accounts.currentIndex === accounts.count - 1) { - addAccount.forceActiveFocus(); - accounts.currentIndex = -1; - } else { - accounts.incrementCurrentIndex(); - } - } - Keys.onUpPressed: { - if (accounts.currentIndex === 0) { - addAccount.forceActiveFocus(); - accounts.currentIndex = -1; - } else { - accounts.decrementCurrentIndex(); - } - } - - Keys.onReleased: if (event.key == Qt.Key_Escape) { - if (switchUserButton.checked) { - switchUserButton.checked = false; - } - } - - onVisibleChanged: { - for (let i = 0; i < accounts.count; i++) { - if (model.data(model.index(i, 0), Qt.DisplayRole) === root.connection.localUser.id) { - accounts.currentIndex = i; - break; - } - } - } - - delegate: Delegates.RoundedItemDelegate { - id: userDelegate - - required property NeoChatConnection connection - - width: parent.width - text: connection.localUser.displayName - - contentItem: RowLayout { - KirigamiComponents.Avatar { - implicitWidth: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing - implicitHeight: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing - sourceSize { - width: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing - height: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing - } - source: userDelegate.connection.localUser.avatarMediaId ? ("image://mxc/" + userDelegate.connection.localUser.avatarMediaId) : "" - name: userDelegate.connection.localUser.displayName ?? userDelegate.connection.localUser.id - } - - Delegates.SubtitleContentItem { - itemDelegate: userDelegate - subtitle: userDelegate.connection.localUser.id - labelItem.textFormat: Text.PlainText - subtitleItem.textFormat: Text.PlainText - } - } - - onClicked: { - Controller.activeConnection = userDelegate.connection; - if (switchUserButton.checked) { - switchUserButton.checked = false; - } - } - } - } - - background: ColumnLayout { - spacing: 0 - Kirigami.Separator { - Layout.fillWidth: true - visible: root.bottomEdge - } - Rectangle { - Layout.fillWidth: true - Layout.fillHeight: true - color: Kirigami.Theme.backgroundColor - } - Kirigami.Separator { - Layout.fillWidth: true - visible: !root.bottomEdge - } - } + Component { + id: accountSwitchDialog + AccountSwitchDialog {} } } diff --git a/src/qml/UserInfoDesktop.qml b/src/qml/UserInfoDesktop.qml index 7ef92f32c..2a7cbc56e 100644 --- a/src/qml/UserInfoDesktop.qml +++ b/src/qml/UserInfoDesktop.qml @@ -17,6 +17,8 @@ QQC2.ToolBar { */ required property NeoChatConnection connection + property bool collapsed: false + padding: 0 background: Rectangle { @@ -31,6 +33,7 @@ QQC2.ToolBar { Layout.fillWidth: true } UserInfo { + collapsed: root.collapsed bottomEdge: true connection: root.connection } diff --git a/src/settings/NeoChatGeneralPage.qml b/src/settings/NeoChatGeneralPage.qml index a5496ef54..9ad181d8e 100644 --- a/src/settings/NeoChatGeneralPage.qml +++ b/src/settings/NeoChatGeneralPage.qml @@ -215,5 +215,14 @@ FormCard.FormCardPage { Config.save(); } } + FormCard.FormButtonDelegate { + visible: Config.developerTools + text: i18n("Open developer tools") + onClicked: applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'DevtoolsPage.qml'), { + connection: root.connection + }, { + title: i18n("Developer Tools") + }); + } } }