diff --git a/client/resources.qrc b/client/resources.qrc index ff101a5d..5b4d6ae7 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -215,6 +215,5 @@ ui/qml/Controls2/ListViewWithLabelsType.qml ui/qml/Pages2/PageServiceDnsSettings.qml ui/qml/Controls2/TopCloseButtonType.qml - ui/qml/Components/HomeRootMenuButton.qml diff --git a/client/ui/qml/Components/HomeRootMenuButton.qml b/client/ui/qml/Components/HomeRootMenuButton.qml deleted file mode 100644 index ca800125..00000000 --- a/client/ui/qml/Components/HomeRootMenuButton.qml +++ /dev/null @@ -1,127 +0,0 @@ -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts - -import "../Controls2/TextTypes" -import "../Controls2" - -Item { - id: root - - property string text - property int textMaximumLineCount: 2 - property int textElide: Qt.ElideRight - - property string descriptionText - - property var clickedFunction - - property string rightImageSource - - property string textColor: "#d7d8db" - property string descriptionColor: "#878B91" - property real textOpacity: 1.0 - - property string rightImageColor: "#d7d8db" - - property bool descriptionOnTop: false - - property string defaultServerHostName - property string defaultContainerName - - implicitWidth: content.implicitWidth + content.anchors.topMargin + content.anchors.bottomMargin - implicitHeight: content.implicitHeight + content.anchors.leftMargin + content.anchors.rightMargin - - ColumnLayout { - id: content - - anchors.right: parent.right - anchors.left: parent.left - anchors.bottom: parent.bottom - - RowLayout { - Layout.topMargin: 24 - Layout.leftMargin: 24 - Layout.rightMargin: 24 - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - - Header1TextType { - Layout.maximumWidth: root.width - 48 - 18 - 12 // todo - - maximumLineCount: 2 - elide: Qt.ElideRight - - text: root.text - Layout.alignment: Qt.AlignLeft - } - - - ImageButtonType { - id: rightImage - - hoverEnabled: false - image: rightImageSource - imageColor: rightImageColor - - icon.width: 18 - icon.height: 18 - backgroundRadius: 16 - horizontalPadding: 4 - topPadding: 4 - bottomPadding: 3 - } - } - - LabelTextType { - Layout.bottomMargin: 44 - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - - text: { - var description = "" - if (ServersModel.isDefaultServerHasWriteAccess()) { - if (SettingsController.isAmneziaDnsEnabled() - && ContainersModel.isAmneziaDnsContainerInstalled(ServersModel.getDefaultServerIndex())) { - description += "Amnezia DNS | " - } - } else { - if (ServersModel.isDefaultServerConfigContainsAmneziaDns()) { - description += "Amnezia DNS | " - } - } - - description += root.defaultContainerName + " | " + root.defaultServerHostName - return description - } - } - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - hoverEnabled: true - - onEntered: { - rightImage.backgroundColor = rightImage.hoveredColor - - root.textOpacity = 0.8 - } - - onExited: { - rightImage.backgroundColor = rightImage.defaultColor - - root.textOpacity = 1 - } - - onPressedChanged: { - rightImage.backgroundColor = pressed ? rightImage.pressedColor : entered ? rightImage.hoveredColor : rightImage.defaultColor - - root.textOpacity = 0.7 - } - - onClicked: { - if (clickedFunction && typeof clickedFunction === "function") { - clickedFunction() - } - } - } -} diff --git a/client/ui/qml/Controls2/DrawerType.qml b/client/ui/qml/Controls2/DrawerType.qml index 07e05f43..72765d78 100644 --- a/client/ui/qml/Controls2/DrawerType.qml +++ b/client/ui/qml/Controls2/DrawerType.qml @@ -4,7 +4,6 @@ import QtQuick.Controls Drawer { id: drawer property bool needCloseButton: true - property bool isOpened: false Connections { target: PageController @@ -53,16 +52,12 @@ Drawer { } onOpened: { - isOpened = true - if (needCloseButton) { PageController.drawerOpen() } } onClosed: { - isOpened = false - if (needCloseButton) { PageController.drawerClose() } @@ -72,27 +67,4 @@ Drawer { PageController.updateNavigationBarColor(initialPageNavigationBarColor) } } - - - onPositionChanged: { - if (isOpened && (position <= 0.99 && position >= 0.95)) { - mouseArea.canceled() - drawer.close() - mouseArea.exited() - dropArea.exited() - } - } - - DropArea { - id: dropArea - } - - MouseArea { - id: mouseArea - anchors.fill: parent - - onPressed: { - isOpened = true - } - } } diff --git a/client/ui/qml/Pages2/PageHome.qml b/client/ui/qml/Pages2/PageHome.qml index ee7cc678..d395cd22 100644 --- a/client/ui/qml/Pages2/PageHome.qml +++ b/client/ui/qml/Pages2/PageHome.qml @@ -26,11 +26,17 @@ PageType { property string defaultServerHostName: ServersModel.defaultServerHostName property string defaultContainerName: ContainersModel.defaultContainerName + MouseArea { + anchors.fill: parent + enabled: buttonContent.state === "expanded" + onClicked: { + buttonContent.state = "collapsed" + } + } + Item { - anchors.top: parent.top - anchors.bottom: buttonBackground.top - anchors.right: parent.right - anchors.left: parent.left + anchors.fill: parent + anchors.bottomMargin: buttonContent.collapsedHeight ConnectButton { anchors.centerIn: parent @@ -41,17 +47,66 @@ PageType { target: PageController function onRestorePageHomeState(isContainerInstalled) { - menu.visible = true + buttonContent.state = "expanded" if (isContainerInstalled) { containersDropDown.menuVisible = true } } + function onForceCloseDrawer() { + buttonContent.state = "collapsed" + } + } + + MouseArea { + id: dragArea + + anchors.fill: buttonBackground + cursorShape: Qt.PointingHandCursor + hoverEnabled: true + + drag.target: buttonContent + drag.axis: Drag.YAxis + drag.maximumY: root.height - buttonContent.collapsedHeight + drag.minimumY: root.height - root.height * 0.9 + + /** If drag area is released at any point other than min or max y, transition to the other state */ + onReleased: { + if (buttonContent.state === "collapsed" && buttonContent.y < dragArea.drag.maximumY) { + buttonContent.state = "expanded" + return + } + if (buttonContent.state === "expanded" && buttonContent.y > dragArea.drag.minimumY) { + buttonContent.state = "collapsed" + return + } + } + + onEntered: { + collapsedButtonChevron.backgroundColor = collapsedButtonChevron.hoveredColor + collapsedButtonHeader.opacity = 0.8 + } + onExited: { + collapsedButtonChevron.backgroundColor = collapsedButtonChevron.defaultColor + collapsedButtonHeader.opacity = 1 + } + onPressedChanged: { + collapsedButtonChevron.backgroundColor = pressed ? collapsedButtonChevron.pressedColor : entered ? collapsedButtonChevron.hoveredColor : collapsedButtonChevron.defaultColor + collapsedButtonHeader.opacity = 0.7 + } + + + onClicked: { + if (buttonContent.state === "collapsed") { + buttonContent.state = "expanded" + } + } } Rectangle { id: buttonBackground - anchors.fill: defaultServerInfo + anchors { left: buttonContent.left; right: buttonContent.right; top: buttonContent.top } + height: root.height radius: 16 color: root.defaultColor border.color: root.borderColor @@ -67,44 +122,167 @@ PageType { } } - HomeRootMenuButton { - id: defaultServerInfo - height: 130 - anchors.right: parent.right - anchors.left: parent.left - anchors.bottom: parent.bottom + ColumnLayout { + id: buttonContent - text: root.defaultServerName - rightImageSource: "qrc:/images/controls/chevron-down.svg" + /** Initial height of button content */ + property int collapsedHeight: 0 + /** True when expanded objects should be visible */ + property bool expandedVisibility: buttonContent.state === "expanded" || (buttonContent.state === "collapsed" && dragArea.drag.active === true) + /** True when collapsed objects should be visible */ + property bool collapsedVisibility: buttonContent.state === "collapsed" && dragArea.drag.active === false - defaultContainerName: root.defaultContainerName - defaultServerHostName: root.defaultServerHostName + Drag.active: dragArea.drag.active + anchors.right: root.right + anchors.left: root.left + y: root.height - buttonContent.height - clickedFunction: function() { - menu.visible = true + Component.onCompleted: { + buttonContent.state = "collapsed" } - } - DrawerType { - id: menu - - interactive: { - if (stackView && stackView.currentItem) { - return (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageHome)) ? true : false - } else { - return false + /** Set once based on first implicit height change once all children are layed out */ + onImplicitHeightChanged: { + if (buttonContent.state === "collapsed" && collapsedHeight == 0) { + collapsedHeight = implicitHeight } } - dragMargin: buttonBackground.height + 56 // page start tabBar height - width: parent.width - height: parent.height * 0.9 + onStateChanged: { + if (buttonContent.state === "collapsed") { + var initialPageNavigationBarColor = PageController.getInitialPageNavigationBarColor() + if (initialPageNavigationBarColor !== 0xFF1C1D21) { + PageController.updateNavigationBarColor(initialPageNavigationBarColor) + } + PageController.drawerClose() + return + } + if (buttonContent.state === "expanded") { + if (PageController.getInitialPageNavigationBarColor() !== 0xFF1C1D21) { + PageController.updateNavigationBarColor(0xFF1C1D21) + } + PageController.drawerOpen() + return + } + } + + /** Two states of buttonContent, great place to add any future animations for the drawer */ + states: [ + State { + name: "collapsed" + PropertyChanges { + target: buttonContent + y: root.height - collapsedHeight + } + }, + State { + name: "expanded" + PropertyChanges { + target: buttonContent + y: dragArea.drag.minimumY + + } + } + ] + + transitions: [ + Transition { + from: "collapsed" + to: "expanded" + PropertyAnimation { + target: buttonContent + properties: "y" + duration: 200 + } + }, + Transition { + from: "expanded" + to: "collapsed" + PropertyAnimation { + target: buttonContent + properties: "y" + duration: 200 + } + } + ] + + RowLayout { + Layout.topMargin: 24 + Layout.leftMargin: 24 + Layout.rightMargin: 24 + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + visible: buttonContent.collapsedVisibility + + spacing: 0 + + Header1TextType { + id: collapsedButtonHeader + Layout.maximumWidth: buttonContent.width - 48 - 18 - 12 // todo + + maximumLineCount: 2 + elide: Qt.ElideRight + + text: root.defaultServerName + horizontalAlignment: Qt.AlignHCenter + + Behavior on opacity { + PropertyAnimation { duration: 200 } + } + } + + ImageButtonType { + id: collapsedButtonChevron + + Layout.leftMargin: 8 + + hoverEnabled: false + image: "qrc:/images/controls/chevron-down.svg" + imageColor: "#d7d8db" + + icon.width: 18 + icon.height: 18 + backgroundRadius: 16 + horizontalPadding: 4 + topPadding: 4 + bottomPadding: 3 + + onClicked: { + if (buttonContent.state === "collapsed") { + buttonContent.state = "expanded" + } + } + } + } + + LabelTextType { + Layout.bottomMargin: 44 + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + visible: buttonContent.collapsedVisibility + + text: { + var description = "" + if (ServersModel.isDefaultServerHasWriteAccess()) { + if (SettingsController.isAmneziaDnsEnabled() + && ContainersModel.isAmneziaDnsContainerInstalled(ServersModel.getDefaultServerIndex())) { + description += "Amnezia DNS | " + } + } else { + if (ServersModel.isDefaultServerConfigContainsAmneziaDns()) { + description += "Amnezia DNS | " + } + } + + description += root.defaultContainerName + " | " + root.defaultServerHostName + return description + } + } ColumnLayout { id: serversMenuHeader - anchors.top: parent.top - anchors.right: parent.right - anchors.left: parent.left + + Layout.alignment: Qt.AlignTop | Qt.AlignHCenter + Layout.fillWidth: true + visible: buttonContent.expandedVisibility Header1TextType { Layout.fillWidth: true @@ -185,13 +363,14 @@ PageType { Layout.topMargin: 48 Layout.leftMargin: 16 Layout.rightMargin: 16 + visible: buttonContent.expandedVisibility actionButtonImage: "qrc:/images/controls/plus.svg" headerText: qsTr("Servers") actionButtonFunction: function() { - menu.visible = false + buttonContent.state = "collapsed" connectionTypeSelection.visible = true } } @@ -201,10 +380,23 @@ PageType { } } - FlickableType { - anchors.top: serversMenuHeader.bottom - anchors.topMargin: 16 + Flickable { + id: serversContainer + Layout.alignment: Qt.AlignTop | Qt.AlignHCenter + Layout.fillWidth: true + Layout.topMargin: 16 contentHeight: col.implicitHeight + implicitHeight: root.height - (root.height * 0.1) - serversMenuHeader.implicitHeight - 52 //todo 52 is tabbar height + visible: buttonContent.expandedVisibility + clip: true + + ScrollBar.vertical: ScrollBar { + id: scrollBar + policy: serversContainer.height >= serversContainer.contentHeight ? ScrollBar.AlwaysOff : ScrollBar.AlwaysOn + } + + Keys.onUpPressed: scrollBar.decrease() + Keys.onDownPressed: scrollBar.increase() Column { id: col @@ -299,7 +491,7 @@ PageType { onClicked: function() { ServersModel.currentlyProcessedIndex = index PageController.goToPage(PageEnum.PageSettingsServerInfo) - menu.visible = false + buttonContent.state = "collapsed" } } }