Newer
Older
property var allowEmptyPass
// TODO get a nice background color for this mainwindow. It should be customizable.
// TODO refactorize all this mess into discrete components.
TabBar {
id: bar
width: parent.width
TabButton {
text: qsTr("Info")
}
TabButton {
text: qsTr("Gateways")
}
}
StackLayout {
anchors.fill: parent
currentIndex: bar.currentIndex
id: mainStatus
text: "off"
font.pixelSize: 26
id: mainCurrentGateway
text: ""
font.pixelSize: 20
SwitchDelegate {
id: vpntoggle
text: qsTr("")
checked: false
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
Connections {
onCheckedChanged: {
if (vpntoggle.checked == true && ctx.status == "off") {
backend.switchOn()
}
if (vpntoggle.checked === false && ctx.status == "on") {
backend.switchOff()
}
}
}
contentItem: Text {
rightPadding: vpntoggle.indicator.width + control.spacing
text: vpntoggle.text
font: vpntoggle.font
opacity: enabled ? 1.0 : 0.3
color: vpntoggle.down ? "#17a81a" : "#21be2b"
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
indicator: Rectangle {
implicitWidth: 48
implicitHeight: 26
x: vpntoggle.width - width - vpntoggle.rightPadding
y: parent.height / 2 - height / 2
radius: 13
color: vpntoggle.checked ? "#17a81a" : "transparent"
border.color: vpntoggle.checked ? "#17a81a" : "#cccccc"
Rectangle {
x: vpntoggle.checked ? parent.width - width : 0
width: 26
height: 26
radius: 13
color: vpntoggle.down ? "#cccccc" : "#ffffff"
border.color: vpntoggle.checked ? (vpntoggle.down ? "#17a81a" : "#21be2b") : "#999999"
}
}
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
visible: vpntoggle.down || vpntoggle.highlighted
color: vpntoggle.down ? "#bdbebf" : "#eeeeee"
}
Text {
id: manualOverrideWarning
font.pixelSize: 10
color: "grey"
text: qsTr("Location has been manually set.")
anchors.horizontalCenter: parent.horizontalCenter
visible: manualSelectionButton.checked
}
}
}
Item {
id: gatewayTab
anchors.centerIn: parent
Column {
anchors.centerIn: parent
spacing: 10
RadioButton {
id: autoSelectionButton
checked: true
text: qsTr("Automatic")
// TODO still needs to change to automatic on the backend, and maybe note
// that the change will be effective on the next reconnect.
}
RadioButton {
id: manualSelectionButton
text: qsTr("Manual")
}
ComboBox {
id: gwSelector
editable: false
visible: manualSelectionButton.checked
model: [qsTr("Automatic")]
onActivated: {
console.debug("Selected gateway:", currentText)
backend.useGateway(currentText.toString())
Connections {
target: jsonModel
onDataChanged: {
// TODO pass QML_DEBUG variable to be hyper-verbose
//console.debug(jsonModel.getJson())
gwSelector.model = Object.keys(ctx.gateways)
console.debug(jsonModel.getJson())
donate.visible = true
if (ctx.loginDialog == 'true') {
console.debug(jsonModel.getJson())
console.debug("DEBUG: should display login")
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
}
console.debug("ERRORS:", ctx.errors)
if (msg == undefined) {
if (ctx.errors == 'bad_auth_502'
|| ctx.errors == 'bad_auth_timeout') {
msg = qsTr("Oops! The authentication service seems down. Please try again later")
if (allowEmptyPass) {
// For now, this is a libraryVPN, so we can be explicit about what credentials are here.
// Another option to consider is to customize the error strings while vendoring.
//: Incorrect library card number
msg = qsTr("Please check your Patron ID")
} else {
msg = qsTr("Could not log in with those credentials, please retry")
}
initFailure.title = qsTr("Login Error")
} else {
//: %1 -> application name
//: %2 -> error string
msg = qsTr("Got an error starting %1: %2").arg(ctx.appName).arg(
ctx.errors)
}
function shouldAllowEmptyPass() {
let obj = JSON.parse(providers.getJson())
let active = obj['default']
let allProviders = obj['providers']
if (allProviders[i]['name'] === active) {
return (allProviders[i]['authEmptyPass'] === 'true')
}
}
return false
loginDone = false
console.debug("Platform:", Qt.platform.os)
console.debug("DEBUG: Pre-seeded providers:")
console.debug(providers.getJson())
allowEmptyPass = shouldAllowEmptyPass()
/* TODO get appVisible flag from backend */
switch (st) {
case "off":
//: %1 -> application name
return qsTr("%1 off").arg(ctx.appName)
case "on":
//: %1 -> application name
return qsTr("%1 on").arg(ctx.appName)
case "connecting":
//: %1 -> application name
return qsTr("Connecting to %1").arg(ctx.appName)
case "stopping":
//: %1 -> application name
return qsTr("Stopping %1").arg(ctx.appName)
case "failed":
//: %1 -> application name
return qsTr("%1 blocking internet").arg(
ctx.appName) // TODO failed is not handed yet
/* TODO change this!!! automatic: Paris (FR) */
switch (st) {
case "off":
//: %1 -> application name
return qsTr("%1 off").arg(ctx.appName)
case "on":
//: %1 -> application name
//: %2 -> current gateway
return qsTr("%1 on - %2").arg(ctx.appName).arg(ctx.currentLocation)
case "connecting":
//: %1 -> application name
//: %2 -> current gateway
return qsTr("Connecting to %1 - %2").arg(ctx.appName).arg(
case "stopping":
//: %1 -> application name
return qsTr("Stopping %1").arg(ctx.appName)
case "failed":
//: %1 -> application name
return qsTr("%1 blocking internet").arg(
ctx.appName) // TODO failed is not handed yet
"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"
systray.activatedSignal()
/* the systray menu cannot be buried in a child qml file because
* otherwise the ids are not available
* from other components
*/
Connections {
target: systray
onActivatedSignal: {
if (Qt.platform.os === "windows" || desktop === "LXQt") {
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
MenuItem {
id: autoSelectionItem
text: qsTr("automatic")
checkable: true
checked: true
enabled: false
}
/* a minimal segfault for submenu */
// Menu {}
MenuSeparator {}
MenuItem {
id: manualSelectionItem
text: qsTr("Pick gateway…")
checkable: true
checked: false
enabled: true
}
MenuSeparator {}
MenuItem {
text: {
if (vpn.state == "failed")
qsTr("Reconnect")
else
qsTr("Turn on")
}
onTriggered: {
backend.switchOn()
}
visible: ctx ? (ctx.status == "off"
|| ctx.status == "failed") : false
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
Qt.openUrlExternally(Qt.resolvedUrl(ctx.helpURL))
}
}
Qt.openUrlExternally(
Qt.resolvedUrl(
"https://0xacab.org/leap/bitmask-vpn/issues"))
text: qsTr("Quit")
onTriggered: backend.quit()
}
}
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
Component.onCompleted: {
icon.source = icons["off"]
tooltip = qsTr("Checking status…")
console.debug("systray init completed")
hide()
if (systrayVisible) {
console.log("show systray")
show()
if (Qt.platform.os === "windows") {
let appname = ctx ? ctx.appName : "VPN"
showNotification(
appname
+ " is up and running. Please use system tray icon to control it.")
}
}
}
// Helper to show notification messages
function showNotification(msg) {
console.log("Going to show notification message: ", msg)
if (supportsMessages) {
let appname = ctx ? ctx.appName : "VPN"
showMessage(appname, msg, null, 15000)
} else {
console.log("System doesn't support systray notifications")
}
}
AboutDialog {
id: about
visible: false
}
MessageDialog {
id: errorStartingVPN
//buttons: MessageDialog.Ok
title: qsTr("Error starting VPN")
text: ""
detailedText: ""
visible: false
MessageDialog {
id: authAgent
//buttons: MessageDialog.Ok
title: qsTr("Missing authentication agent")
text: qsTr("Could not find a polkit authentication agent. Please run one and try again.")
visible: false
FailDialog {