summaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
Diffstat (limited to 'gui')
-rw-r--r--gui/components/BoldLabel.qml15
-rw-r--r--gui/components/ErrorBox.qml33
-rw-r--r--gui/components/InitErrors.qml49
-rw-r--r--gui/components/LightLabel.qml1
-rw-r--r--gui/components/MainView.qml4
-rw-r--r--gui/components/Splash.qml15
-rw-r--r--gui/components/StatusBox.qml89
-rw-r--r--gui/components/VPNState.qml104
-rw-r--r--gui/gui.qrc14
-rw-r--r--gui/main.qml130
-rw-r--r--gui/resources/alert.svg4
-rw-r--r--gui/resources/fonts/Montserrat-Regular.ttfbin0 -> 245708 bytes
-rw-r--r--gui/resources/fonts/Montserrat-SemiBold.ttfbin0 -> 243816 bytes
13 files changed, 294 insertions, 164 deletions
diff --git a/gui/components/BoldLabel.qml b/gui/components/BoldLabel.qml
index 6c6c3c3..d4a6ba3 100644
--- a/gui/components/BoldLabel.qml
+++ b/gui/components/BoldLabel.qml
@@ -4,18 +4,15 @@ import "../themes/themes.js" as Theme
import "../themes"
Label {
- FontLoader {
- id: boldFont
- source: "qrc:/oxanium-bold.ttf"
+ color: "black"
+
+ font {
+ pixelSize: Theme.fontSize * 1.5
+ family: boldFont.name
+ bold: true
}
- font.pixelSize: Theme.fontSize * 1.55555
- //font.family: boldFont.name
- font.bold: true
- //color: Theme.fontColorDark
- color: "black"
text: parent.text
- //wrapMode: Text.WordWrap
Accessible.name: text
Accessible.role: Accessible.StaticText
}
diff --git a/gui/components/ErrorBox.qml b/gui/components/ErrorBox.qml
new file mode 100644
index 0000000..40c12d0
--- /dev/null
+++ b/gui/components/ErrorBox.qml
@@ -0,0 +1,33 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+import QtGraphicalEffects 1.0
+import "../themes/themes.js" as Theme
+
+Item {
+ id: errorBox
+ width: parent.width
+ property var errorText: ""
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: connectionImage.bottom
+
+ // TODO alert icon, by type
+
+ Rectangle {
+
+ id: labelWrapper
+ color: "transparent"
+ height: label.paintedHeight + Theme.windowMargin
+ width: parent.width
+ anchors.verticalCenter: parent.verticalCenter
+
+ Label {
+ id: label
+ width: labelWrapper.width - Theme.windowMargin
+ anchors.centerIn: parent
+ text: errorBox.errorText //+ " " + "<b><u>" + alertLinkText + "</b></u>"
+ horizontalAlignment: Text.AlignHCenter
+ wrapMode: Text.Wrap
+ font.pixelSize: Theme.fontSizeSmall
+ }
+ }
+}
diff --git a/gui/components/InitErrors.qml b/gui/components/InitErrors.qml
new file mode 100644
index 0000000..2859168
--- /dev/null
+++ b/gui/components/InitErrors.qml
@@ -0,0 +1,49 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+import QtGraphicalEffects 1.0
+
+ErrorBox {
+
+ state: "noerror"
+
+ states: [
+ State {
+ name: "noerror"
+ when: root.error == ""
+ PropertyChanges {
+ target: splashSpinner
+ visible: true
+ }
+ PropertyChanges {
+ target: splashErrorBox
+ visible: false
+ }
+ },
+ State {
+ name: "nohelpers"
+ when: root.error == "nohelpers"
+ PropertyChanges {
+ target: splashSpinner
+ visible: false
+ }
+ PropertyChanges {
+ target: splashErrorBox
+ errorText: qsTr("Could not find helpers. Please check your installation")
+ visible: true
+ }
+ },
+ State {
+ name: "nopolkit"
+ when: root.error == "nopolkit"
+ PropertyChanges {
+ target: splashSpinner
+ visible: false
+ }
+ PropertyChanges {
+ target: splashErrorBox
+ errorText: qsTr("Could not find polkit agent.")
+ visible: true
+ }
+ }
+ ]
+}
diff --git a/gui/components/LightLabel.qml b/gui/components/LightLabel.qml
index 78f82b6..ea723c7 100644
--- a/gui/components/LightLabel.qml
+++ b/gui/components/LightLabel.qml
@@ -11,7 +11,6 @@ Text {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
- //lineHeightMode: Text.FixedHeight
wrapMode: Text.Wrap
Accessible.role: Accessible.StaticText
diff --git a/gui/components/MainView.qml b/gui/components/MainView.qml
index 7ce723d..1918c7f 100644
--- a/gui/components/MainView.qml
+++ b/gui/components/MainView.qml
@@ -26,6 +26,10 @@ Page {
delegate: ItemDelegate {
width: parent.width
text: model.text
+ visible: {
+ if (isDonationService) {return true}
+ return model.text != qsTr("Donate")
+ }
highlighted: ListView.isCurrentItem
icon.color: "transparent"
icon.source: model.icon
diff --git a/gui/components/Splash.qml b/gui/components/Splash.qml
index b494494..6bdd3ab 100644
--- a/gui/components/Splash.qml
+++ b/gui/components/Splash.qml
@@ -5,6 +5,7 @@ import QtGraphicalEffects 1.0
Page {
id: splash
property int timeoutInterval: 1600
+ property alias errors: splashErrorBox
Column {
width: parent.width * 0.8
@@ -24,7 +25,13 @@ Page {
fillMode: Image.PreserveAspectFit
}
- Spinner {}
+ Spinner {
+ id: splashSpinner
+ }
+
+ InitErrors {
+ id: splashErrorBox
+ }
}
Timer {
@@ -39,10 +46,10 @@ Page {
}
function loadMainViewWhenReady() {
- console.debug("ready?")
+ if (root.error != "") {
+ return
+ }
if (ctx && ctx.isReady) {
- console.debug("ready?", ctx.isReady)
- // FIXME check errors == None
loader.source = "MainView.qml"
} else {
delay(100, loadMainViewWhenReady)
diff --git a/gui/components/StatusBox.qml b/gui/components/StatusBox.qml
index fa24cd8..a20b930 100644
--- a/gui/components/StatusBox.qml
+++ b/gui/components/StatusBox.qml
@@ -19,27 +19,33 @@ Item {
Rectangle {
id: statusBoxBackground
- anchors.fill: parent
- anchors.margins: 20
- anchors.bottomMargin: 30
height: 300
radius: 10
color: Theme.bgColor
- border.color: Theme.accentOff
- border.width: 2
antialiasing: true
+ anchors {
+ fill: parent
+ margins: 20
+ bottomMargin: 30
+ }
+ border {
+ color: Theme.accentOff
+ width: 2
+ }
}
ToolButton {
id: settingsButton
objectName: "settingsButton"
+ font.pixelSize: Qt.application.font.pixelSize * 1.2
opacity: 1
- font.pixelSize: Qt.application.font.pixelSize * 1.6
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.topMargin: Theme.windowMargin + 10
- anchors.leftMargin: Theme.windowMargin + 10
+ anchors {
+ top: parent.top
+ left: parent.left
+ topMargin: Theme.windowMargin + 10
+ leftMargin: Theme.windowMargin + 10
+ }
onClicked: {
if (stackView.depth > 1) {
@@ -51,75 +57,78 @@ Item {
Icon {
id: settingsImage
- width: 24
- height: 24
- // TODO move arrow left to toolbar top
+ width: 16
+ height: 16
+ anchors.centerIn: settingsButton
source: stackView.depth
> 1 ? "../resources/arrow-left.svg" : "../resources/gear-fill.svg"
- anchors.centerIn: settingsButton
}
}
- Column {
- id: col
- anchors.centerIn: parent
- anchors.topMargin: 24
- width: parent.width * 0.8
-
+ Rectangle {
+ id: statusLabelWrapper
+ height: 45
+ anchors {
+ top: statusBoxBackground.top
+ topMargin: 40
+ horizontalCenter: parent.horizontalCenter
+ }
BoldLabel {
id: connectionState
- text: ""
+ anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
+ text: ""
}
+ }
+
+ Column {
+ id: col
+ width: parent.width * 0.8
+ anchors.horizontalCenter: parent.horizontalCenter
VerticalSpacer {
id: spacerPreImg
- visible: false
- height: 40
+ visible: true
+ height: 150
}
Image {
id: connectionImage
- height: 200
+ height: 160
source: "../resources/spy.gif"
+ anchors.horizontalCenter: parent.horizontalCenter
fillMode: Image.PreserveAspectFit
}
VerticalSpacer {
id: spacerPostImg
- visible: false
- height: 35
+ visible: true
+ height: 30
}
MaterialButton {
id: toggleVPN
+ spacing: 8
+
anchors.horizontalCenter: parent.horizontalCenter
Layout.alignment: Qt.AlignBottom
- font.capitalization: Font.Capitalize
- spacing: 8
+
+ font {
+ capitalization: Font.Capitalize
+ family: lightFont.name
+ bold: false
+ }
onClicked: {
if (vpn.state === "on") {
- console.debug("should turn off")
backend.switchOff()
} else if (vpn.state === "off") {
- console.debug("should turn on")
backend.switchOn()
} else {
console.debug("unknown state")
}
}
-
-
- /*
- XXX this hijacks click events, so better no pointing for now.
- MouseArea {
- anchors.fill: toggleVPN
- hoverEnabled: true
- cursorShape: !hoverEnabled ? Qt.ForbiddenCursor : Qt.PointingHandCursor
- }
- */
}
}
}
diff --git a/gui/components/VPNState.qml b/gui/components/VPNState.qml
index 8856ad4..9d443ce 100644
--- a/gui/components/VPNState.qml
+++ b/gui/components/VPNState.qml
@@ -4,15 +4,21 @@ import QtQuick.Controls 2.12
import "../themes/themes.js" as Theme
StateGroup {
+ property var initializing: "initializing"
+ property var off: "off"
+ property var on: "on"
+ property var starting: "starting"
+ property var stopping: "stopping"
+ property var failed: "failed"
- state: ctx ? ctx.status : "off"
+ state: ctx ? ctx.status : vpnStates.off
states: [
State {
- name: "initializing"
+ name: initializing
},
State {
- name: "off"
+ name: off
PropertyChanges {
target: connectionState
text: qsTr("Connection\nUnsecured")
@@ -24,10 +30,6 @@ StateGroup {
PropertyChanges {
target: connectionImage
source: "../resources/spy.gif"
- //anchors.right: parent.right
- //anchors.rightMargin: -8
- // XXX need to nulify horizontalcenter somehow,
- // it gets fixed to parent.center
}
PropertyChanges {
target: toggleVPN
@@ -42,16 +44,14 @@ StateGroup {
text: toHuman("off")
}
StateChangeScript {
- script: {
-
- }
+ script: {}
}
},
State {
- name: "on"
+ name: on
PropertyChanges {
target: connectionState
- text: qsTr("Connection\nSecure")
+ text: qsTr("Connection\nSecured")
}
PropertyChanges {
target: statusBoxBackground
@@ -60,17 +60,6 @@ StateGroup {
PropertyChanges {
target: connectionImage
source: "../resources/riseup-icon.svg"
- // TODO need to offset the logo or increase the image
- // to fixed height
- height: 120
- }
- PropertyChanges {
- target: spacerPreImg
- visible: true
- }
- PropertyChanges {
- target: spacerPostImg
- visible: true
}
PropertyChanges {
target: toggleVPN
@@ -86,20 +75,11 @@ StateGroup {
text: toHuman("on")
}
StateChangeScript {
- script: {
-
- // TODO check donation
- //if (needsDonate && !shownDonate) {
- // donate.visible = true;
- // shownDonate = true;
- // backend.donateSeen();
- //}
- }
+ script: {}
}
},
State {
- name: "starting"
- //when: toggleVPN.pressed == true
+ name: starting
PropertyChanges {
target: connectionState
text: qsTr("Connecting")
@@ -127,13 +107,11 @@ StateGroup {
text: toHuman("connecting")
}
StateChangeScript {
- script: {
-
- }
+ script: {}
}
},
State {
- name: "stopping"
+ name: stopping
PropertyChanges {
target: connectionState
text: "Switching\nOff"
@@ -143,6 +121,12 @@ StateGroup {
border.color: Theme.accentConnecting
}
PropertyChanges {
+ // ?? is this image correct?
+ target: connectionImage
+ source: "../resources/birds.svg"
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ PropertyChanges {
target: systray
tooltip: toHuman("stopping")
icon.source: icons["wait"]
@@ -153,23 +137,39 @@ StateGroup {
}
},
State {
- name: "failed"
- // TODO
+ name: failed
}
]
-
-
- /*
- transitions: Transition {
- from: "off"
- to: "starting"
- reversible: true
-
- ParallelAnimation {
- ColorAnimation { duration: 500 }
+ transitions: [
+ Transition {
+ to: on
+ ColorAnimation {
+ target: statusBoxBackground
+ duration: 500
+ }
+ },
+ Transition {
+ to: off
+ ColorAnimation {
+ target: statusBoxBackground
+ duration: 500
+ }
+ },
+ Transition {
+ to: starting
+ ColorAnimation {
+ target: statusBoxBackground
+ duration: 500
+ }
+ },
+ Transition {
+ to: stopping
+ ColorAnimation {
+ target: statusBoxBackground
+ duration: 500
+ }
}
- }
- */
+ ]
function toHuman(st) {
switch (st) {
case "off":
diff --git a/gui/gui.qrc b/gui/gui.qrc
index dde4c8f..c794ef1 100644
--- a/gui/gui.qrc
+++ b/gui/gui.qrc
@@ -3,6 +3,7 @@
<file>main.qml</file>
+ <!-- gui components -->
<file>themes/themes.js</file>
<file>components/MainView.qml</file>
<file>components/Splash.qml</file>
@@ -23,6 +24,10 @@
<file>components/Icon.qml</file>
<file>components/MaterialButton.qml</file>
<file>components/VPNState.qml</file>
+ <file>components/InitErrors.qml</file>
+ <file>components/ErrorBox.qml</file>
+
+ <!-- resources, assets -->
<file>resources/icon-noshield.svg</file>
<file>resources/location.svg</file>
<file>resources/settings.svg</file>
@@ -43,8 +48,13 @@
<file>resources/riseup-icon.svg</file>
<file>resources/spy.gif</file>
<file>resources/quit.svg</file>
+ <file>resources/alert.svg</file>
+
+ <!-- fonts -->
+ <file alias="montserrat-light.ttf">resources/fonts/Montserrat-Regular.ttf</file>
+ <file alias="montserrat-bold.ttf">resources/fonts/Montserrat-SemiBold.ttf</file>
- <!-- old, to remove -->
+ <!-- begin, to remove -->
<file>qml/VpnState.qml</file>
<file>qml/AboutDialog.qml</file>
<file>qml/DonateDialog.qml</file>
@@ -57,7 +67,7 @@
<file>qml/VPNSwitch.qml</file>
<file>qml/BridgesItem.qml</file>
<file>qml/logic.js</file>
- <!-- to remove -->
+ <!-- end, to remove -->
<file>assets/icon/png/black/vpn_off.png</file>
<file>assets/icon/png/black/vpn_on.png</file>
diff --git a/gui/main.qml b/gui/main.qml
index 16677a2..f847377 100644
--- a/gui/main.qml
+++ b/gui/main.qml
@@ -1,21 +1,23 @@
+
+
/*
TODO (ui rewrite)
- [x] add systray
- [x] systray status
- [x] splash screen
- - [ ] splash delay/transitions
- - [ ] nested states
- - [ ] splash init errors
- - [ ] font: monserrat
- - [ ] donation dialog
- - [ ] add gateway to systray
- - [ ] control actions from systray
+ - [x] splash delay/transitions
+ - [x] font: monserrat
+ - [x] nested states
+ - [x] splash init errors
- [ ] minimize/hide from systray
- - [ ] parse ctx flags (need dialog, etc)
- [ ] gateway selector
- [ ] bridges
+ - [ ] control actions from systray
+ - [ ] add gateway to systray
+ - [ ] donation dialog
+ - [ ] parse ctx flags (need dialog, etc)
+ - [ ] udp support
*/
-
import QtQuick 2.0
import QtQuick.Controls 2.4
import QtQuick.Dialogs 1.2
@@ -40,6 +42,9 @@ ApplicationWindow {
Material.accent: Material.Green
property var ctx
+ property var error: ""
+ property bool isDonationService: false
+ property bool showDonationReminder: false
property var icons: {
"off": "qrc:/assets/icon/png/white/vpn_off.png",
@@ -48,64 +53,77 @@ ApplicationWindow {
"blocked": "qrc:/assets/icon/png/white/vpn_blocked.png"
}
+ FontLoader {
+ id: lightFont
+ source: "qrc:/montserrat-light.ttf"
+ }
+
+ FontLoader {
+ id: boldFont
+ source: "qrc:/montserrat-bold.ttf"
+ }
+
+ font.family: lightFont.name
+
Loader {
- id: loader
- asynchronous: true
- anchors.fill: parent
+ id: loader
+ asynchronous: true
+ anchors.fill: parent
}
Systray {
- id: systray
+ id: systray
}
+
Connections {
- target: jsonModel
- function onDataChanged() {
- ctx = JSON.parse(jsonModel.getJson())
+ target: jsonModel
+ function onDataChanged() {
+ let j = jsonModel.getJson()
if (qmlDebug) {
- console.debug(jsonModel.getJson())
+ console.debug(j)
}
-
- // FIXME -- use nested state machines for all these cases.
-
- //gwSelector.model = Object.keys(ctx.locations)
-
- /*
- if (ctx.donateDialog == 'true') {
- Logic.setNeedsDonate(true);
- }
- if (ctx.loginDialog == 'true') {
- console.debug(jsonModel.getJson())
- console.debug("DEBUG: should display login")
- login.visible = true
- }
- if (ctx.loginOk == 'true') {
- loginOk.visible = true
- }
- if (ctx.errors) {
- login.visible = false
- if (ctx.errors == "nohelpers") {
- showInitFailure(
- qsTr("Could not find helpers. Please check your installation"))
- } else if (ctx.errors == "nopolkit") {
- showInitFailure(qsTr("Could not find polkit agent."))
- } else {
- showInitFailure()
- }
- }
- if (ctx.donateURL) {
- donateItem.visible = true
- }
-
- if (ctx.status == "on") {
- gwNextConnectionText.visible = false
- gwReconnectText.visible = false
- }
- */
- }
+ ctx = JSON.parse(j)
+ if (ctx.errors) {
+ console.debug("errors, setting root.error")
+ root.error = ctx.errors
+ } else {
+ root.error = ""
+ }
+ if (ctx.donateURL) {
+ isDonationService = true;
+ }
+ if (ctx.donateDialog == 'true') {
+ showDonationReminder = true;
+ }
+ //gwSelector.model = Object.keys(ctx.locations)
+ // TODO check donation
+ //if (needsDonate && !shownDonate) {
+ // donate.visible = true;
+ // shownDonate = true;
+ // // move this to onClick of "close" for widget
+ // backend.donateSeen();
+ //}
+ // TODO refactor donate widget into main view (with close window!)
+ //if (ctx.status == "on") {
+ // gwNextConnectionText.visible = false
+ // gwReconnectText.visible = false
+ // when: vpn.status == "on"
+ //}
+
+ /*
+ TODO libraries need login
+ if (ctx.loginDialog == 'true') {
+ login.visible = true
+ }
+ if (ctx.loginOk == 'true') {
+ loginOk.visible = true
+ }
+ */
+ }
}
- onSceneGraphError: function(error, msg) {
+ onSceneGraphError: function (error, msg) {
console.debug("ERROR while initializing scene")
console.debug(msg)
}
diff --git a/gui/resources/alert.svg b/gui/resources/alert.svg
new file mode 100644
index 0000000..cd178eb
--- /dev/null
+++ b/gui/resources/alert.svg
@@ -0,0 +1,4 @@
+<svg width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+ <path fill="#494c4e" d="M12 2l10 20H2L12 2m0-2c-.758 0-1.45.428-1.79 1.106l-10 20c-.31.62-.276 1.356.09 1.946.363.59 1.007.948 1.7.948h20c.693 0 1.337-.36 1.7-.95.365-.59.4-1.325.09-1.945l-10-20C13.45.428 12.756 0 12 0z"/>
+ <path fill="#494c4e" d="M12 20c-.832 0-1.507-.672-1.507-1.5S11.168 17 12 17s1.507.672 1.507 1.5S12.832 20 12 20zm.985-4.806c-.093.47-.505.806-.985.806s-.892-.337-.985-.806l-.996-5c-.06-.293.017-.598.208-.83.19-.23.476-.364.776-.364h1.99c.302 0 .587.134.777.365.192.23.27.536.21.83l-.995 5z"/>
+</svg>
diff --git a/gui/resources/fonts/Montserrat-Regular.ttf b/gui/resources/fonts/Montserrat-Regular.ttf
new file mode 100644
index 0000000..8d443d5
--- /dev/null
+++ b/gui/resources/fonts/Montserrat-Regular.ttf
Binary files differ
diff --git a/gui/resources/fonts/Montserrat-SemiBold.ttf b/gui/resources/fonts/Montserrat-SemiBold.ttf
new file mode 100644
index 0000000..f8a43f2
--- /dev/null
+++ b/gui/resources/fonts/Montserrat-SemiBold.ttf
Binary files differ