summaryrefslogtreecommitdiff
path: root/gui/qml
diff options
context:
space:
mode:
authorkali kaneko (leap communications) <kali@leap.se>2020-06-04 11:39:41 +0200
committerkali kaneko (leap communications) <kali@leap.se>2020-06-12 20:02:45 +0200
commit9b88f3ce47d090df167263ce2b4b6b430694da72 (patch)
tree3435b273857cc6bd26009767fa701673358d57cb /gui/qml
parent719413cad922e1d34f2ea495bae0165cae53b22f (diff)
[feat] add qt gui
Signed-off-by: kali kaneko (leap communications) <kali@leap.se>
Diffstat (limited to 'gui/qml')
-rw-r--r--gui/qml/main.qml208
1 files changed, 208 insertions, 0 deletions
diff --git a/gui/qml/main.qml b/gui/qml/main.qml
new file mode 100644
index 0000000..38f5331
--- /dev/null
+++ b/gui/qml/main.qml
@@ -0,0 +1,208 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+import QtQuick.Dialogs 1.2
+import QtQuick.Extras 1.2
+import Qt.labs.platform 1.1
+
+ApplicationWindow {
+
+ id: app
+ visible: false
+
+ property var ctx
+
+ Connections {
+ target: jsonModel
+ onDataChanged: {
+ ctx = JSON.parse(jsonModel.getJson());
+ }
+ }
+
+ Component.onCompleted: {
+ /* stupid as it sounds, windows doesn't like to have the systray icon
+ not being attached to an actual application window.
+ We can still use this quirk, and can use the AppWindow with deferred
+ Loaders as a placeholder for all the many dialogs, or to load
+ a nice splash screen etc... */
+ app.visible = true;
+ hide();
+ }
+
+ function toHuman(st) {
+ switch(st) {
+ case "off":
+ // TODO improve string interpolation, give context to translators etc
+ return qsTr(ctx.appName + " off");
+ case "on":
+ return qsTr(ctx.appName + " on");
+ case "connecting":
+ return qsTr("Connecting to " + ctx.appName);
+ case "stopping":
+ return qsTr("Stopping " + ctx.appName);
+ case "failed":
+ return qsTr(ctx.appName + " blocking internet"); // TODO failed is not handed yet
+ }
+ }
+
+ property var icons: {
+ "off": "qrc:/assets/icon/png/black/vpn_off.png",
+ "on": "qrc:/assets/icon/png/black/vpn_on.png",
+ "wait": "qrc:/assets/icon/png/black/vpn_wait_0.png",
+ "blocked": "qrc:/assets/icon/png/black/vpn_blocked.png",
+ }
+
+
+ SystemTrayIcon {
+
+ id: systray
+ visible: true
+ onActivated: {
+ console.debug("app is", ctx.appName)
+ menu.open()
+ }
+
+ Component.onCompleted: {
+ icon.source = icons["off"]
+ tooltip = qsTr("Checking status...")
+ console.debug("systray init completed")
+ show();
+ }
+
+
+ menu: Menu {
+ StateGroup {
+ id: vpn
+ state: ctx ? ctx.status : ""
+ states: [
+ State { name: "initializing" },
+ State {
+ name: "off"
+ PropertyChanges { target: systray; tooltip: toHuman("off"); icon.source: icons["off"] }
+ PropertyChanges { target: statusItem; text: toHuman("off") }
+ },
+ State {
+ name: "on"
+ PropertyChanges { target: systray; tooltip: toHuman("on"); icon.source: icons["on"] }
+ PropertyChanges { target: statusItem; text: toHuman("on") }
+ },
+ State {
+ name: "starting"
+ PropertyChanges { target: systray; tooltip: toHuman("connecting"); icon.source: icons["wait"] }
+ PropertyChanges { target: statusItem; text: toHuman("connecting") }
+ },
+ State {
+ name: "stopping"
+ PropertyChanges { target: systray; tooltip: toHuman["stopping"]; icon.source: icons["wait"] }
+ PropertyChanges { target: statusItem; text: toHuman["stopping"] }
+ },
+ State {
+ name: "failed"
+ PropertyChanges { target: systray; tooltip: toHuman["failed"]; icon.source: icons["wait"] }
+ PropertyChanges { target: statusItem; text: toHuman["failed"] }
+ }
+ ]
+ }
+
+ /*
+ LoginDialog {
+ id: login
+ }
+ DonateDialog {
+ id: donate
+ }
+ MessageDialog {
+ id: about
+ buttons: MessageDialog.Ok
+ title: "About"
+ text: "<p>%1 is an easy, fast, and secure VPN service from %2. %1 does not require a user account, keep logs, or track you in any way.</p>
+ <p>This service is paid for entirely by donations from users like you. <a href=\"%3\">Please donate</a>.</p>
+ <p>By using this application, you agree to the <a href=\"%4\">Terms of Service</a>. This service is provided as-is, without any warranty, and is intended for people who work to make the world a better place.</p>".arg(ctxSystray.applicationName).arg(ctxSystray.provider).arg(ctxSystray.donateURL).arg(ctxSystray.tosURL)
+ informativeText: "%1 version: %2".arg(ctxSystray.applicationName).arg(ctxSystray.version)
+ }
+ MessageDialog {
+ id: errorStartingVPN
+ buttons: MessageDialog.Ok
+ modality: Qt.NonModal
+ title: "Error starting VPN"
+ text: "Can't connect to %1".arg(ctxSystray.applicationName)
+ detailedText: ctxSystray.errorStartingMsg
+ visible: ctxSystray.errorStartingMsg != ""
+ }
+ MessageDialog {
+ id: authAgent
+ buttons: MessageDialog.Ok
+ modality: Qt.NonModal
+ title: "Missing authentication agent"
+ text: "Could not find a polkit authentication agent. Please run one and try again."
+ visible: ctxSystray.authAgent == true
+ }
+ MessageDialog {
+ id: initFailure
+ buttons: MessageDialog.Ok
+ modality: Qt.NonModal
+ title: "Initialization Error"
+ text: ctxSystray.errorInitMsg
+ visible: ctxSystray.errorInitMsg != ""
+ }
+ */
+
+ MenuItem {
+ id: statusItem
+ text: qsTr("Checking status...")
+ enabled: false
+ }
+
+ MenuItem {
+ text: {
+ if (vpn.state == "failed")
+ qsTr("Reconnect")
+ else
+ qsTr("Turn on")
+ }
+ onTriggered: {
+ backend.switchOn()
+ }
+ visible: ctx ? (ctx.status == "off" || ctx.status == "failed") : false
+ }
+
+ MenuItem {
+ text: {
+ if (ctx && ctx.status == "starting")
+ qsTr("Cancel")
+ else
+ qsTr("Turn off")
+ }
+ onTriggered: {
+ backend.switchOff()
+ }
+ visible: ctx ? (ctx.status == "on" || ctx.status == "starting" || ctx.status == "failed") : false
+ }
+
+ MenuSeparator {}
+
+ MenuItem {
+ text: qsTr("Help...")
+ //onTriggered: ctxSystray.help()
+ }
+
+ MenuItem {
+ text: qsTr("Donate...")
+ //onTriggered: ctxSystray.donate()
+ visible: true
+ //visible: ctx.showDonate
+ }
+
+ MenuItem {
+ text: qsTr("About...")
+ //onTriggered: about.open()
+ }
+
+ MenuSeparator {}
+
+ MenuItem {
+ text: qsTr("Quit")
+ onTriggered: backend.quit()
+ }
+ }
+ }
+}