diff --git a/src/qml/GlobalDrawer.qml b/src/qml/GlobalDrawer.qml index 47c32d3..81d8789 100644 --- a/src/qml/GlobalDrawer.qml +++ b/src/qml/GlobalDrawer.qml @@ -1,91 +1,125 @@ /* * Kaidan - A user-friendly XMPP client for every device! * * Copyright (C) 2016-2020 Kaidan developers and contributors * (see the LICENSE file for a full list of copyright authors) * * Kaidan is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * In addition, as a special exception, the author of Kaidan gives * permission to link the code of its release with the OpenSSL * project's "OpenSSL" library (or with modified versions of it that * use the same license as the "OpenSSL" library), and distribute the * linked executables. You must obey the GNU General Public License in * all respects for all of the code used other than "OpenSSL". If you * modify this file, you may extend this exception to your version of * the file, but you are not obligated to do so. If you do not wish to * do so, delete this exception statement from your version. * * Kaidan is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Kaidan. If not, see . */ +import QtQuick 2.7 +import QtQuick.Layouts 1.3 +import QtQuick.Controls 2.3 as Controls import org.kde.kirigami 2.8 as Kirigami + import im.kaidan.kaidan 1.0 + import "settings" Kirigami.GlobalDrawer { id: globalDrawer title: Utils.applicationDisplayName() titleIcon: Utils.getResourcePath("images/kaidan.svg") bannerImageSource: Utils.getResourcePath("images/banner.png") SettingsSheet { id: settingsSheet } + topContent: [ + // This item is used to disable an account temporarily. + RowLayout { + spacing: -4 + + property bool disconnected: kaidan.connectionState === Enums.StateDisconnected + property bool connected: kaidan.connectionState === Enums.StateConnected + + Controls.Switch { + checked: !parent.disconnected + onClicked: parent.disconnected ? kaidan.mainConnect() : kaidan.mainDisconnect() + } + + Text { + text: { + var jidAndStatus = kaidan.jid + " (" + + if (parent.disconnected) + jidAndStatus += qsTr("Offline"); + else if (parent.connected) + jidAndStatus += qsTr("Online"); + else + jidAndStatus += qsTr("Connecting..."); + + jidAndStatus += ")" + + return jidAndStatus + } + + color: parent.connected ? Utils.presenceTypeToColor(Enums.PresOnline) : Utils.presenceTypeToColor(Enums.PresUnavailable) + } + } + ] + actions: [ Kirigami.Action { text: qsTr("Invite friends") icon.name: "mail-invitation" onTriggered: { Utils.copyToClipboard(Utils.invitationUrl(kaidan.jid)) passiveNotification(qsTr("Invitation link copied to clipboard")) } }, Kirigami.Action { text: qsTr("Log out") icon.name: "system-shutdown" onTriggered: { - closeAdditionalLayers() + popLayersAboveLowest() // disconnect (open log in page) kaidan.mainDisconnect(true) } }, Kirigami.Action { text: qsTr("Settings") icon.name: "settings-configure" onTriggered: { // open settings page if (Kirigami.Settings.isMobile) { if (pageStack.layers.depth < 2) - pageStack.layers.push(settingsPage) + pageStack.layers.push(settingsPage) } else { - settingsSheet.open() + settingsSheet.open() } } }, Kirigami.Action { text: qsTr("About") icon.name: "help-about" onTriggered: { - closeAdditionalLayers() + popLayersAboveLowest() // open about sheet aboutDialog.open() } } ] - - function closeAdditionalLayers() { - while (pageStack.layers.depth > 1) - pageStack.layers.pop() - } } diff --git a/src/qml/main.qml b/src/qml/main.qml index 25f6a07..c191f80 100644 --- a/src/qml/main.qml +++ b/src/qml/main.qml @@ -1,147 +1,161 @@ /* * Kaidan - A user-friendly XMPP client for every device! * * Copyright (C) 2016-2020 Kaidan developers and contributors * (see the LICENSE file for a full list of copyright authors) * * Kaidan is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * In addition, as a special exception, the author of Kaidan gives * permission to link the code of its release with the OpenSSL * project's "OpenSSL" library (or with modified versions of it that * use the same license as the "OpenSSL" library), and distribute the * linked executables. You must obey the GNU General Public License in * all respects for all of the code used other than "OpenSSL". If you * modify this file, you may extend this exception to your version of * the file, but you are not obligated to do so. If you do not wish to * do so, delete this exception statement from your version. * * Kaidan is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Kaidan. If not, see . */ import QtQuick 2.7 import QtQuick.Controls.Material 2.3 import org.kde.kirigami 2.8 as Kirigami import StatusBar 0.1 + import im.kaidan.kaidan 1.0 + import "elements" import "settings" Kirigami.ApplicationWindow { id: root minimumHeight: 300 minimumWidth: 280 // radius for using rounded corners readonly property int roundedCornersRadius: Kirigami.Units.smallSpacing * 1.5 StatusBar { color: Material.color(Material.Green, Material.Shade700) } // Global and Contextual Drawers globalDrawer: GlobalDrawer {} contextDrawer: Kirigami.ContextDrawer { id: contextDrawer } AboutDialog { id: aboutDialog focus: true x: (parent.width - width) / 2 y: (parent.height - height) / 2 } SubRequestAcceptSheet { id: subReqAcceptSheet } // when the window was closed, disconnect from jabber server onClosing: { kaidan.mainDisconnect() } // load all pages Component {id: chatPage; ChatPage {}} Component {id: loginPage; LoginPage {}} Component {id: rosterPage; RosterPage {}} Component {id: emptyChatPage; EmptyChatPage {}} Component {id: settingsPage; SettingsPage {}} Component {id: qrCodeScannerPage; QrCodeScannerPage {}} Component {id: userProfilePage; UserProfilePage {}} Component {id: multimediaSettingsPage; MultimediaSettingsPage {}} /** * Shows a passive notification for a long period. */ function passiveNotification(text) { showPassiveNotification(text, "long") } function showPassiveNotificationForConnectionError() { passiveNotification(Utils.connectionErrorMessage(kaidan.connectionError)) } - function openLogInPage() { - // close all pages (we don't know on which page we're on, - // thus we don't use replace) - while (pageStack.depth > 0) - pageStack.pop() - - // toggle global drawer + function openLoginPage() { globalDrawer.enabled = false globalDrawer.visible = false - // push new page + + popLayersAboveLowest() + popAllPages() pageStack.push(loginPage) } - function closeLogInPage() { - // toggle global drawer + /** + * Opens the view with the roster and chat page. + */ + function openChatView() { globalDrawer.enabled = true - // replace page with roster page - pageStack.replace(rosterPage) + popAllPages() + pageStack.push(rosterPage) if (!Kirigami.Settings.isMobile) pageStack.push(emptyChatPage) } + /** + * Pops all layers except the layer with index 0 from the page stack. + */ + function popLayersAboveLowest() { + while (pageStack.layers.depth > 1) + pageStack.layers.pop() + } + + /** + * Pops all pages from the page stack. + */ + function popAllPages() { + while (pageStack.depth > 0) + pageStack.pop() + } + function handleSubRequest(from, message) { kaidan.vCardRequested(from) subReqAcceptSheet.from = from subReqAcceptSheet.message = message subReqAcceptSheet.open() } Component.onCompleted: { kaidan.passiveNotificationRequested.connect(passiveNotification) - kaidan.newCredentialsNeeded.connect(openLogInPage) - kaidan.logInWorked.connect(closeLogInPage) + kaidan.newCredentialsNeeded.connect(openLoginPage) + kaidan.logInWorked.connect(openChatView) kaidan.subscriptionRequestReceived.connect(handleSubRequest) - // push roster page (trying normal start up) - pageStack.push(rosterPage) - if (!Kirigami.Settings.isMobile) - pageStack.push(emptyChatPage) - // Annouce that we're ready and the back-end can start with connecting + openChatView() + + // Announce that the user interface is ready and the application can start connecting. kaidan.start() } Component.onDestruction: { kaidan.passiveNotificationRequested.disconnect(passiveNotification) - kaidan.newCredentialsNeeded.disconnect(openLogInPage) - kaidan.logInWorked.disconnect(closeLogInPage) + kaidan.newCredentialsNeeded.disconnect(openLoginPage) + kaidan.logInWorked.disconnect(openChatView) kaidan.subscriptionRequestReceived.disconnect(handleSubRequest) } }