From ce5a559926e947f43c34977cfe3c8974b9b819de Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Fri, 21 Apr 2023 10:20:32 +0200 Subject: [PATCH] feat(GODT-2586): Two-columns layout for account details. --- .../bridge-gui/bridge-gui/qml/AccountView.qml | 184 +++++++++--------- .../bridge-gui/qml/Configuration.qml | 2 - .../bridge-gui/bridge-gui/qml/MainWindow.qml | 19 +- 3 files changed, 97 insertions(+), 108 deletions(-) diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/AccountView.qml b/internal/frontend/bridge-gui/bridge-gui/qml/AccountView.qml index 7466cbcd..fa9702a8 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/AccountView.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/AccountView.qml @@ -27,67 +27,55 @@ Item { property var notifications property var user - signal showSignIn() + signal showSignIn + signal showSetupGuide(var user, string address) - property int _leftMargin: 64 - property int _rightMargin: 64 + property int _contentWidth: 640 property int _topMargin: 32 - property int _detailsTopMargin: 25 - property int _bottomMargin: 12 + property int _detailsMargin: 25 property int _spacing: 20 - property int _lineWidth: 1 - - ScrollView { - id: scrollView - clip: true + property int _lineThickness: 1 + property bool _connected: root.user ? root.user.state === EUserState.Connected : false + Rectangle { anchors.fill: parent - Component.onCompleted: contentItem.boundsBehavior = Flickable.StopAtBounds // Disable the springy effect when scroll reaches top/bottom. + color: root.colorScheme.background_weak - Item { - // can't use parent here because parent is not ScrollView (Flickable inside contentItem inside ScrollView) - width: scrollView.availableWidth - height: scrollView.availableHeight - - implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin - // do not set implicitWidth because implicit width of ColumnLayout will be equal to maximum implicit width of - // internal items. And if one of internal items would be a Text or Label - implicit width of those is always - // equal to non-wrapped text (i.e. one line only). That will lead to enabling horizontal scroll when not needed - implicitWidth: width + ScrollView { + id: scrollView + anchors.fill: parent + Component.onCompleted: contentItem.boundsBehavior = Flickable.StopAtBounds ColumnLayout { + id: topLevelColumnLayout + anchors.fill: parent spacing: 0 - anchors.fill: parent - Rectangle { - id: topRectangle + id: topArea color: root.colorScheme.background_norm - - implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin - implicitWidth: children[0].implicitWidth + children[0].anchors.leftMargin + children[0].anchors.rightMargin - + clip: true Layout.fillWidth: true + implicitHeight: childrenRect.height ColumnLayout { - spacing: root._spacing + id: topLayout + width: _contentWidth + anchors.horizontalCenter: parent.horizontalCenter + spacing: _spacing - anchors.fill: parent - anchors.leftMargin: root._leftMargin - anchors.rightMargin: root._rightMargin - anchors.topMargin: root._topMargin - anchors.bottomMargin: root._bottomMargin - - RowLayout { // account delegate with action buttons + RowLayout { + // account delegate with action buttons Layout.fillWidth: true + Layout.topMargin: _topMargin AccountDelegate { Layout.fillWidth: true colorScheme: root.colorScheme user: root.user type: AccountDelegate.LargeView - enabled: root.user ? (root.user.state === EUserState.Connected) : false + enabled: _connected } Button { @@ -95,10 +83,11 @@ Item { colorScheme: root.colorScheme text: qsTr("Sign out") secondary: true - visible: root.user ? (root.user.state === EUserState.Connected) : false + visible: _connected onClicked: { - if (!root.user) return - root.user.logout() + if (!root.user) + return; + root.user.logout(); } } @@ -109,8 +98,9 @@ Item { secondary: true visible: root.user ? (root.user.state === EUserState.SignedOut) : false onClicked: { - if (!root.user) return - root.showSignIn() + if (!root.user) + return; + root.showSignIn(); } } @@ -120,8 +110,9 @@ Item { icon.source: "/qml/icons/ic-trash.svg" secondary: true onClicked: { - if (!root.user) return - root.notifications.askDeleteAccount(root.user) + if (!root.user) + return; + root.notifications.askDeleteAccount(root.user); } visible: root.user ? root.user.state !== EUserState.Locked : false } @@ -129,7 +120,7 @@ Item { Rectangle { Layout.fillWidth: true - height: root._lineWidth + height: root._lineThickness color: root.colorScheme.border_weak } @@ -139,12 +130,12 @@ Item { actionText: qsTr("Configure") description: qsTr("Using the mailbox details below (re)configure your client.") type: SettingsItem.Button - enabled: root.user ? root.user.state === EUserState.Connected : false - visible: root.user ? !root.user.splitMode || root.user.addresses.length==1 : false + visible: _connected && (!root.user.splitMode) || (root.user.addresses.length === 1) showSeparator: splitMode.visible onClicked: { - if (!root.user) return - root.showSetupGuide(root.user, user.addresses[0]) + if (!root.user) + return; + root.showSetupGuide(root.user, user.addresses[0]); } Layout.fillWidth: true @@ -157,15 +148,14 @@ Item { description: qsTr("Setup multiple email addresses individually.") type: SettingsItem.Toggle checked: root.user ? root.user.splitMode : false - visible: root.user ? root.user.addresses.length > 1 : false - enabled: root.user ? (root.user.state === EUserState.Connected) : false + visible: _connected && root.user.addresses.length > 1 showSeparator: addressSelector.visible onClicked: { - if (!splitMode.checked){ - root.notifications.askEnableSplitMode(user) + if (!splitMode.checked) { + root.notifications.askEnableSplitMode(user); } else { - addressSelector.currentIndex = 0 - root.user.toggleSplitMode(!splitMode.checked) + addressSelector.currentIndex = 0; + root.user.toggleSplitMode(!splitMode.checked); } } @@ -174,8 +164,8 @@ Item { RowLayout { Layout.fillWidth: true - enabled: root.user ? (root.user.state === EUserState.Connected) : false - visible: root.user ? root.user.splitMode : false + Layout.bottomMargin: _spacing + visible: _connected && root.user.splitMode ComboBox { id: addressSelector @@ -189,60 +179,68 @@ Item { text: qsTr("Configure") secondary: true onClicked: { - if (!root.user) return - root.showSetupGuide(root.user, addressSelector.displayText) + if (!root.user) + return; + root.showSetupGuide(root.user, addressSelector.displayText); } } } + + Rectangle { + height: 0 + } // just for some extra space before separator } } Rectangle { + id: bottomArea + Layout.fillWidth: true + implicitHeight: bottomLayout.implicitHeight color: root.colorScheme.background_weak - implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin - implicitWidth: children[0].implicitWidth + children[0].anchors.leftMargin + children[0].anchors.rightMargin - - Layout.fillWidth: true - ColumnLayout { - id: configuration - - anchors.fill: parent - anchors.leftMargin: root._leftMargin - anchors.rightMargin: root._rightMargin - anchors.topMargin: root._detailsTopMargin - anchors.bottomMargin: root._spacing - - spacing: root._spacing - visible: root.user ? (root.user.state === EUserState.Connected) : false - - property string currentAddress: addressSelector.displayText + id: bottomLayout + width: _contentWidth + anchors.horizontalCenter: parent.horizontalCenter + spacing: _spacing + visible: _connected Label { + Layout.topMargin: _detailsMargin colorScheme: root.colorScheme text: qsTr("Mailbox details") type: Label.Body_semibold } - Configuration { - colorScheme: root.colorScheme - title: qsTr("IMAP") - hostname: Backend.hostname - port: Backend.imapPort.toString() - username: configuration.currentAddress - password: root.user ? root.user.password : "" - security : Backend.useSSLForIMAP ? "SSL" : "STARTTLS" - } + RowLayout { + id: configuration + spacing: _spacing + Layout.fillWidth: true + Layout.fillHeight: true - Configuration { - colorScheme: root.colorScheme - title: qsTr("SMTP") - hostname : Backend.hostname - port : Backend.smtpPort.toString() - username : configuration.currentAddress - password : root.user ? root.user.password : "" - security : Backend.useSSLForSMTP ? "SSL" : "STARTTLS" + property string currentAddress: addressSelector.displayText + + Configuration { + Layout.fillWidth: true + colorScheme: root.colorScheme + title: qsTr("IMAP") + hostname: Backend.hostname + port: Backend.imapPort.toString() + username: configuration.currentAddress + password: root.user ? root.user.password : "" + security: Backend.useSSLForIMAP ? "SSL" : "STARTTLS" + } + + Configuration { + Layout.fillWidth: true + colorScheme: root.colorScheme + title: qsTr("SMTP") + hostname: Backend.hostname + port: Backend.smtpPort.toString() + username: configuration.currentAddress + password: root.user ? root.user.password : "" + security: Backend.useSSLForSMTP ? "SSL" : "STARTTLS" + } } } } diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/Configuration.qml b/internal/frontend/bridge-gui/bridge-gui/qml/Configuration.qml index 1ba9ebe4..84121e81 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/Configuration.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/Configuration.qml @@ -61,8 +61,6 @@ Rectangle { type: Label.Body_semibold } - Item{} - ConfigurationItem{ colorScheme: root.colorScheme; label: qsTr("Hostname") ; value: root.hostname } ConfigurationItem{ colorScheme: root.colorScheme; label: qsTr("Port") ; value: root.port } ConfigurationItem{ colorScheme: root.colorScheme; label: qsTr("Username") ; value: root.username } diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/MainWindow.qml b/internal/frontend/bridge-gui/bridge-gui/qml/MainWindow.qml index 491206ad..877eaf9f 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/MainWindow.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/MainWindow.qml @@ -28,25 +28,18 @@ import "tests" ApplicationWindow { id: root - - width: 960 - height: 576 - + colorScheme: ProtonStyle.currentStyle visible: true - minimumHeight: contentLayout.implicitHeight - minimumWidth: contentLayout.implicitWidth - colorScheme: ProtonStyle.currentStyle + property int _defaultWidth: 1080 + property int _defaultHeight: 780 + width: _defaultWidth + height: _defaultHeight + minimumWidth: _defaultWidth property var notifications - // This is needed because on MacOS if first window shown is not transparent - - // all other windows of application will not have transparent background (black - // instead of transparency). In our case that mean that if MainWindow will be - // shown before StatusWindow - StatusWindow will not have transparent corners. - color: "transparent" - // show Setup Guide on every new user Connections { target: Backend.users