1091 lines
48 KiB
QML
1091 lines
48 KiB
QML
import QtQuick
|
||
import QtQuick.Layouts
|
||
import QtQuick.Controls
|
||
import org.kde.kirigami as Kirigami
|
||
import org.kde.plasma.core as PlasmaCore
|
||
import org.kde.plasma.components as PlasmaComponents
|
||
import org.kde.plasma.extras as PlasmaExtras
|
||
import org.kde.plasma.plasmoid
|
||
|
||
PlasmoidItem {
|
||
id: root
|
||
|
||
Plasmoid.title: "MeowRelay"
|
||
|
||
// compactRepresentation extra content
|
||
property var iflag: getFlag(current)
|
||
property var iflag_extra: getFlag(current) + current
|
||
|
||
// extra
|
||
hideOnWindowDeactivate: !plasmoid.configuration.isPinned
|
||
|
||
property var scrollbartype: Plasmoid.configuration.SBdisplay ? ScrollBar.AsNeeded : ScrollBar.AlwaysOff
|
||
|
||
//me/profile
|
||
property var profileData: null
|
||
property alias profileDataAlias: root.profileData
|
||
|
||
property string user: profileData.user
|
||
property bool is_admin: profileData.user_data.is_admin
|
||
property bool share: profileData.user_data.share
|
||
property bool ebalka: profileData.ebalka
|
||
property string current_device: profileData.current_device
|
||
property string current: profileData.current
|
||
property string provider: profileData.provider
|
||
property string ip: profileData.ip
|
||
property var features: profileData.features
|
||
property var devices: profileData.devices
|
||
|
||
//routes
|
||
property var routesData: null
|
||
|
||
//stats
|
||
property var statsData: null
|
||
|
||
property double uptime: statsData.uptime
|
||
property var servers: statsData.servers
|
||
|
||
// tabs json responses
|
||
ListModel { id: routeModel }
|
||
ListModel { id: statsModel }
|
||
ListModel { id: profileModel }
|
||
ListModel { id: devicesModel }
|
||
ListModel { id: featuresModel }
|
||
|
||
// buttons blocker (antispam)
|
||
property int isLoadingItems: 0
|
||
property bool isLoading: false // колясочные технологии, по итогу юзается токо isLoadingItems
|
||
property bool isBlocked: false
|
||
property bool shareBlocked: false
|
||
property bool ebalkaBlocked: false
|
||
property bool refreshBlocked: false
|
||
property bool countriesBlocked: false
|
||
property bool devicesBlocked: false
|
||
property bool featuresBlocked: false
|
||
|
||
onIsLoadingItemsChanged: {
|
||
if (isLoadingItems > 0) {
|
||
isLoading = true
|
||
}
|
||
else if (isLoadingItems < 0) {
|
||
isLoading = false
|
||
isLoadingItems = 0
|
||
}
|
||
else {
|
||
isLoading = false
|
||
}
|
||
}
|
||
|
||
// flags
|
||
function getFlag(code) {
|
||
if (!code || code.length !== 2) return '❔';
|
||
let upper = code.toUpperCase();
|
||
let c1 = upper.charCodeAt(0) + 127397;
|
||
let c2 = upper.charCodeAt(1) + 127397;
|
||
return String.fromCodePoint(c1, c2);
|
||
}
|
||
|
||
// traffic
|
||
function formatTraffic(bytes) {
|
||
if (bytes === 0) return "0 B";
|
||
var units = ["B", "KB", "MB", "GB", "TB"];
|
||
var i = Math.floor(Math.log(bytes) / Math.log(1024));
|
||
var size = (bytes / Math.pow(1024, i)).toFixed(1);
|
||
return parseFloat(size) + " " + units[i];
|
||
}
|
||
|
||
Timer {
|
||
id: meowRelayWatchdog
|
||
interval: 10000
|
||
repeat: false
|
||
onTriggered: {
|
||
console.error("MeowRelay unreachable!") //ваша няшка умерла
|
||
routeModel.clear()
|
||
routeModel.append({"code":"ERR","name":"Error, MeowRelay unreachable :<","provider":"NONE"})
|
||
routesData = [{"code":"ERR","name":"Error, MeowRelay unreachable :<","provider":"NONE"}]
|
||
profileData = {"provider":"NONE"}
|
||
statsData = null
|
||
isBlocked = false
|
||
isLoadingItems = 0
|
||
countriesBlocked = true
|
||
shareBlocked = true
|
||
ebalkaBlocked = true
|
||
devicesBlocked = true
|
||
featuresBlocked = true
|
||
Plasmoid.configuration.OnErrorRefresh ? (
|
||
meowRelayWatchdog.start(),
|
||
isLoadingItems += Plasmoid.configuration.BIrefresh,
|
||
//isBlocked = true,
|
||
superWorker.sendMessage({ "action": "fetch_routes" }),
|
||
superWorker.sendMessage({ "action": "fetch_profile" }),
|
||
superWorker.sendMessage({ "action": "fetch_stats" }),
|
||
fetchRoutesTimer.restart(),
|
||
fetchProfileTimer.restart(),
|
||
fetchStatsTimer.restart()
|
||
) : null
|
||
}
|
||
}
|
||
Timer {
|
||
id: meowRelayWatchdogStats
|
||
interval: 10000
|
||
repeat: false
|
||
onTriggered: {
|
||
console.error("MeowRelay unreachable!") //ваша няшка умерла
|
||
refreshBlocked = false
|
||
}
|
||
}
|
||
Timer {
|
||
id: meowRelayPing
|
||
interval: Plasmoid.configuration.AutoPingInt * 1000
|
||
running: Plasmoid.configuration.AutoPing
|
||
repeat: false
|
||
onTriggered: {
|
||
superWorker.sendMessage({ "action": "ping" })
|
||
console.log("MeowRelay ping pong")
|
||
}
|
||
}
|
||
|
||
// раб в отдельном потоке чтобы кде не фризило
|
||
WorkerScript {
|
||
id: superWorker
|
||
source: "worker.mjs"
|
||
|
||
property var handlers: ({
|
||
"fetch_routes": ({ data }) => {
|
||
routeModel.clear();
|
||
routesData = data;
|
||
for (let i = 0; i < data.length; i++) {
|
||
routeModel.append(data[i]);
|
||
};
|
||
if (Plasmoid.configuration.BIrefresh || Plasmoid.configuration.BIautoupdate) {
|
||
isLoadingItems -= 1
|
||
};
|
||
refreshBlocked = false;
|
||
},
|
||
"fetch_stats": ({ data }) => {
|
||
statsModel.clear();
|
||
statsData = data;
|
||
var serverArray = [];
|
||
for (var Name in servers) {
|
||
if (servers.hasOwnProperty(Name)) {
|
||
var item = servers[Name];
|
||
item.name = Name;
|
||
item.pingString = item.ping.join(" ");
|
||
item.trafficString = item.traffic.join(" ");
|
||
item.speedString = item.speed.join(" ");
|
||
serverArray.push(item);
|
||
}
|
||
}
|
||
serverArray.sort(function(a, b) {
|
||
return b.connected - a.connected;
|
||
});
|
||
for (let i = 0; i < serverArray.length; i++) {
|
||
statsModel.append(serverArray[i]);
|
||
};
|
||
if (Plasmoid.configuration.BIrefresh || Plasmoid.configuration.BIautoupdate) {
|
||
isLoadingItems -= 1
|
||
};
|
||
meowRelayWatchdogStats.stop();
|
||
refreshBlocked = false;
|
||
},
|
||
"fetch_profile": ({ data }) => {
|
||
profileModel.clear();
|
||
devicesModel.clear();
|
||
featuresModel.clear();
|
||
profileData = data;
|
||
for (let i = 0; i < data.length; i++) {
|
||
profileModel.append(data[i]);
|
||
}
|
||
for (let i = 0; i < data.devices.length; i++) {
|
||
devicesModel.append(data.devices[i])
|
||
}
|
||
for (let i = 0; i < data.features.length; i++) {
|
||
featuresModel.append(data.features[i])
|
||
}
|
||
if (Plasmoid.configuration.BIrefresh || Plasmoid.configuration.BIautoupdate) {
|
||
isLoadingItems -= 1
|
||
}
|
||
meowRelayWatchdog.stop();
|
||
isBlocked = false;
|
||
refreshBlocked = false;
|
||
countriesBlocked = false;
|
||
shareBlocked = false;
|
||
ebalkaBlocked = false;
|
||
devicesBlocked = false;
|
||
featuresBlocked = false;
|
||
},
|
||
"post_country": ({ status }) => {
|
||
if (status === 200) {
|
||
superWorker.sendMessage({ "action": "fetch_profile" })
|
||
//done
|
||
}
|
||
else {
|
||
superWorker.sendMessage({ "actions": "fetch_routes" })
|
||
//error
|
||
};
|
||
if (Plasmoid.configuration.BIpostcountry) {
|
||
isLoadingItems -= 1
|
||
}
|
||
},
|
||
"post_share": ({ status }) => {
|
||
if (status === 200) {
|
||
superWorker.sendMessage({ "action": "fetch_profile" })
|
||
//done
|
||
}
|
||
else {
|
||
superWorker.sendMessage({ "action": "fetch_profile" })
|
||
// share = !share
|
||
//error
|
||
};
|
||
if (Plasmoid.configuration.BIpostshare) {
|
||
isLoadingItems -= 1
|
||
}
|
||
shareBlocked = false;
|
||
},
|
||
"post_ebalka": ({ status, ip }) => {
|
||
if (status === 200 && ip != null) {
|
||
superWorker.sendMessage({ "action": "fetch_profile" })
|
||
//done
|
||
}
|
||
else {
|
||
superWorker.sendMessage({ "action": "fetch_profile" }) // кофе
|
||
//error
|
||
};
|
||
if (Plasmoid.configuration.BIpostebalka) {
|
||
isLoadingItems -= 1
|
||
}
|
||
if (Plasmoid.configuration.BIdevicesupdate) {
|
||
isLoadingItems -= 1
|
||
}
|
||
ebalkaBlocked = false;
|
||
devicesBlocked = false;
|
||
},
|
||
"post_name": ({ status }) => {
|
||
if (status === 200) {
|
||
superWorker.sendMessage({ "action": "fetch_profile" })
|
||
//done
|
||
}
|
||
else {
|
||
//error
|
||
};
|
||
if (Plasmoid.configuration.BIdevicesupdate) {
|
||
isLoadingItems -= 1
|
||
}
|
||
devicesBlocked = false;
|
||
},
|
||
"post_feature": ({ status }) => {
|
||
superWorker.sendMessage({ "action": "fetch_profile" });
|
||
if (Plasmoid.configuration.BIfeaturesupdate) {
|
||
isLoadingItems -= 1
|
||
}
|
||
featuresBlocked = false;
|
||
},
|
||
"post_idconnect": ({ status }) => {
|
||
superWorker.sendMessage({ "action": "fetch_profile" });
|
||
superWorker.sendMessage({ "action": "fetch_routes" });
|
||
if (Plasmoid.configuration.BIpostcountry) {
|
||
isLoadingItems -= 1
|
||
}
|
||
}
|
||
})
|
||
|
||
onMessage: (msg) => {
|
||
if (handlers[msg.action]) {
|
||
handlers[msg.action](msg);
|
||
}
|
||
}
|
||
}
|
||
|
||
// init fetch
|
||
Component.onCompleted: {
|
||
isLoadingItems += Plasmoid.configuration.BIinit
|
||
isBlocked = true
|
||
meowRelayWatchdog.start()
|
||
superWorker.sendMessage({ "action": "fetch_routes" })
|
||
superWorker.sendMessage({ "action": "fetch_stats" })
|
||
superWorker.sendMessage({ "action": "fetch_profile" })
|
||
fetchRoutesTimer.start()
|
||
fetchStatsTimer.start()
|
||
fetchProfileTimer.start()
|
||
meowRelayPing.start()
|
||
}
|
||
|
||
// autoupdate fetch
|
||
Timer {
|
||
id: fetchRoutesTimer
|
||
interval: (Plasmoid.configuration.RoutesUpInt * 60000)
|
||
running: Plasmoid.configuration.RoutesAutoUp
|
||
repeat: true
|
||
triggeredOnStart: false
|
||
onTriggered: {
|
||
refreshBlocked = true
|
||
isLoadingItems += Plasmoid.configuration.BIautoupdate
|
||
superWorker.sendMessage({ "action": "fetch_routes" })
|
||
}
|
||
}
|
||
Timer {
|
||
id: fetchStatsTimer
|
||
interval: (Plasmoid.configuration.StatsUpInt * 60000)
|
||
running: Plasmoid.configuration.StatsAutoUp
|
||
repeat: true
|
||
triggeredOnStart: false
|
||
onTriggered: {
|
||
refreshBlocked = true
|
||
isLoadingItems += Plasmoid.configuration.BIautoupdate
|
||
meowRelayWatchdogStats.start()
|
||
superWorker.sendMessage({ "action": "fetch_stats" })
|
||
}
|
||
}
|
||
Timer {
|
||
id: fetchProfileTimer
|
||
interval: (Plasmoid.configuration.ProfileUpInt * 60000)
|
||
running: Plasmoid.configuration.ProfileAutoUp
|
||
repeat: true
|
||
triggeredOnStart: false
|
||
onTriggered: {
|
||
refreshBlocked = true
|
||
isLoadingItems += Plasmoid.configuration.BIautoupdate
|
||
meowRelayWatchdog.start()
|
||
superWorker.sendMessage({ "action": "fetch_profile" })
|
||
}
|
||
}
|
||
|
||
compactRepresentation: Item {
|
||
Layout.minimumWidth: govnoLayout.implicitWidth
|
||
Layout.minimumHeight: Kirigami.Units.iconSizes.medium
|
||
|
||
Layout.maximumWidth: govnoLayout.implicitWidth
|
||
Layout.maximumHeight: Layout.minimumHeight
|
||
|
||
Layout.preferredWidth: govnoLayout.implicitWidth
|
||
Layout.preferredHeight: Layout.minimumHeight
|
||
|
||
MouseArea {
|
||
id: mouseArea
|
||
//property bool wasExpanded
|
||
|
||
Accessible.name: Plasmoid.title
|
||
Accessible.role: Accessible.Button
|
||
//Accessible.description: desc
|
||
|
||
//onPressed: wasExpanded = root.expanded
|
||
//onClicked: root.expanded = !wasExpanded
|
||
|
||
onClicked: Plasmoid.activated();
|
||
|
||
Keys.onPressed: {
|
||
switch (event.key) {
|
||
case Qt.Key_Space:
|
||
case Qt.Key_Enter:
|
||
case Qt.Key_Return:
|
||
case Qt.Key_Select:
|
||
Plasmoid.activated();
|
||
break;
|
||
}
|
||
}
|
||
|
||
// иконки не будет без этой залупы
|
||
anchors.fill: parent
|
||
anchors.leftMargin: 0
|
||
|
||
activeFocusOnTab: true
|
||
hoverEnabled: true
|
||
|
||
Component {
|
||
id: meowIconComponent
|
||
Kirigami.Icon {
|
||
Layout.preferredWidth: Kirigami.Units.gridUnit * 1.5
|
||
Layout.preferredHeight: Kirigami.Units.gridUnit * 1.5
|
||
Layout.alignment: Qt.AlignVCenter
|
||
source: Qt.resolvedUrl("../images/dogfood.svg")
|
||
isMask: true
|
||
active: mouseArea.containsMouse
|
||
}
|
||
}
|
||
Component {
|
||
id: genericLabelComponent
|
||
Label {
|
||
property string labelText: "yaebalrot"
|
||
text: labelText === "yaebalrot" ? "" : labelText
|
||
color: text === "error" ? "red" : Kirigami.Theme.textColor
|
||
font.pointSize: Kirigami.Theme.mediumFont.pointSize
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
}
|
||
|
||
property var configArray: Plasmoid.configuration.ExtraLayout === true ? Plasmoid.configuration.StringLayoutPlacement.split(" ") : ["meow_icon"]
|
||
RowLayout {
|
||
id: govnoLayout
|
||
anchors.fill: parent
|
||
spacing: Kirigami.Units.smallSpacing
|
||
|
||
Repeater {
|
||
model: mouseArea.configArray
|
||
|
||
Loader {
|
||
id: govnoebanoe
|
||
// Logic to choose WHICH component to spawn
|
||
sourceComponent: (modelData === "meow_icon") ? meowIconComponent : genericLabelComponent
|
||
|
||
// Logic to pass DATA to that component
|
||
Binding {
|
||
target: govnoebanoe.item // The Label we just created
|
||
property: "labelText" // The property on the Label
|
||
value: root[modelData] // The live variable in root
|
||
when: govnoebanoe.status === Loader.Ready && modelData !== "meow_icon"
|
||
}
|
||
Layout.fillHeight: true
|
||
}
|
||
}
|
||
}
|
||
// Kirigami.Icon {
|
||
// anchors.fill: parent
|
||
// source: Qt.resolvedUrl("../images/dogfood.svg")
|
||
// isMask: true
|
||
// active: mouseArea.containsMouse
|
||
// }
|
||
}
|
||
}
|
||
|
||
fullRepresentation: PlasmaExtras.Representation {
|
||
//id: fullRoot
|
||
Layout.minimumWidth: Kirigami.Units.gridUnit * 25
|
||
Layout.minimumHeight: Kirigami.Units.gridUnit * 30
|
||
Layout.preferredWidth: Kirigami.Units.gridUnit * 25
|
||
Layout.preferredHeight: Kirigami.Units.gridUnit * 30
|
||
//spacing: 0
|
||
|
||
header: PlasmaExtras.PlasmoidHeading {
|
||
contentItem: ColumnLayout {
|
||
spacing: Kirigami.Units.smallSpacing
|
||
|
||
// row 1 (name)
|
||
RowLayout {
|
||
Layout.fillWidth: true
|
||
|
||
PlasmaExtras.Heading {
|
||
text: " " + plasmoid.title
|
||
level: 1
|
||
Layout.fillWidth: false
|
||
elide: Text.ElideRight
|
||
}
|
||
Rectangle {
|
||
height: Kirigami.Units.gridUnit
|
||
Layout.alignment: AlignVCenter
|
||
width: 1
|
||
color: PlasmaCore.Theme.dividerColor
|
||
opacity: 0.7
|
||
}
|
||
PlasmaExtras.Heading {
|
||
text: (user ? user : "unknown")
|
||
opacity: 0.7
|
||
level: 1
|
||
Layout.fillWidth: true
|
||
elide: Text.ElideRight
|
||
}
|
||
|
||
// config button
|
||
PlasmaComponents.ToolButton {
|
||
id: configButton
|
||
icon.name: "configure"
|
||
display: ToolButton.IconOnly
|
||
onClicked: plasmoid.internalAction("configure").trigger()
|
||
ToolTip.text: i18n("Configure")
|
||
ToolTip.visible: hovered
|
||
ToolTip.delay: Kirigami.Units.toolTipDelay
|
||
KeyNavigation.right: pinButton
|
||
}
|
||
|
||
// pin button
|
||
PlasmaComponents.ToolButton {
|
||
id: pinButton
|
||
icon.name: "window-pin"
|
||
display: ToolButton.IconOnly
|
||
checkable: true
|
||
checked: plasmoid.configuration.isPinned
|
||
down: checked
|
||
onToggled: plasmoid.configuration.isPinned = checked
|
||
ToolTip.text: i18n("Keep Open")
|
||
ToolTip.visible: hovered
|
||
ToolTip.delay: Kirigami.Units.toolTipDelay
|
||
KeyNavigation.left: configButton
|
||
visible: plasmoid.formFactor === 2 || plasmoid.formFactor === 3
|
||
enabled: visible
|
||
}
|
||
}
|
||
|
||
// row 2 (tabs)
|
||
PlasmaComponents.TabBar {
|
||
id: mainTabBar
|
||
Layout.fillWidth: true
|
||
|
||
Repeater {
|
||
model: ["Route", "Devices", "Stats", "Features"]
|
||
delegate: PlasmaComponents.TabButton {
|
||
text: modelData
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Footer
|
||
footer: PlasmaExtras.PlasmoidHeading {
|
||
id: footerItem
|
||
ColumnLayout {
|
||
anchors.fill: parent
|
||
|
||
PlasmaComponents.ProgressBar {
|
||
indeterminate: true
|
||
//visible: isLoading
|
||
visible: false
|
||
Layout.fillWidth: true
|
||
}
|
||
|
||
RowLayout {
|
||
spacing: Kirigami.Units.smallSpacing
|
||
PlasmaComponents.Label {
|
||
text: "Up:"
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: (Math.floor(uptime / 86400)) + "d " + (Math.floor((uptime % 86400) / 3600)) + "h " + (Math.floor(((uptime % 86400) % 3600) / 60)) + "m"
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
Item {
|
||
Layout.fillWidth: true
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: getFlag(current) + current
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: provider
|
||
opacity: 0.7
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
Rectangle {
|
||
height: Kirigami.Units.gridUnit
|
||
Layout.alignment: AlignVCenter
|
||
width: 1
|
||
color: PlasmaCore.Theme.dividerColor
|
||
opacity: 0.2
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: "Device:"
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: current_device
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
Rectangle {
|
||
height: Kirigami.Units.gridUnit
|
||
Layout.alignment: AlignVCenter
|
||
width: 1
|
||
color: PlasmaCore.Theme.dividerColor
|
||
opacity: 0.2
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: "Ip:"
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: ip
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
}
|
||
|
||
RowLayout {
|
||
|
||
PlasmaComponents.Button {
|
||
text: "Refresh"
|
||
icon.name: "view-refresh"
|
||
onClicked: {
|
||
meowRelayWatchdog.running ? meowRelayWatchdog.stop() : null
|
||
meowRelayWatchdog.start()
|
||
isLoadingItems += Plasmoid.configuration.BIrefresh
|
||
isBlocked = true
|
||
superWorker.sendMessage({ "action": "fetch_routes" })
|
||
superWorker.sendMessage({ "action": "fetch_profile" })
|
||
superWorker.sendMessage({ "action": "fetch_stats" })
|
||
fetchRoutesTimer.restart()
|
||
fetchProfileTimer.restart()
|
||
fetchStatsTimer.restart()
|
||
}
|
||
enabled: !(isBlocked || refreshBlocked)
|
||
Layout.fillWidth: false
|
||
}
|
||
PlasmaComponents.BusyIndicator {
|
||
running: isLoadingItems //isLoading
|
||
implicitWidth: 28
|
||
implicitHeight: 28
|
||
}
|
||
Item {
|
||
Layout.fillWidth: true
|
||
}
|
||
PlasmaComponents.Switch {
|
||
text: "Share"
|
||
checked: share
|
||
enabled: !(isBlocked || shareBlocked)
|
||
onClicked: {
|
||
isLoadingItems += Plasmoid.configuration.BIpostshare
|
||
shareBlocked = true
|
||
superWorker.sendMessage({ "action": "post_share", "bool": !share })
|
||
share = !share
|
||
}
|
||
}
|
||
Rectangle {
|
||
height: Kirigami.Units.gridUnit
|
||
Layout.alignment: AlignVCenter
|
||
width: 1
|
||
color: PlasmaCore.Theme.dividerColor
|
||
opacity: 0.2
|
||
}
|
||
PlasmaComponents.Switch {
|
||
text: "80% loss"
|
||
checked: ebalka
|
||
enabled: !(isBlocked || ebalkaBlocked)
|
||
onClicked: {
|
||
isLoadingItems += Plasmoid.configuration.BIpostebalka
|
||
ebalkaBlocked = true
|
||
superWorker.sendMessage({ "action": "post_ebalka", "bool": !ebalka, "ip": null })
|
||
ebalka = !ebalka
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
// Content
|
||
contentItem: Item {
|
||
StackLayout {
|
||
id: tabStack
|
||
anchors.fill: parent
|
||
currentIndex: mainTabBar.currentIndex
|
||
|
||
// Tab 1 Routes
|
||
PlasmaComponents.ScrollView {
|
||
id: routeScroll
|
||
anchors.fill: parent
|
||
ScrollBar.vertical.policy: scrollbartype
|
||
|
||
Column {
|
||
id: listContainer
|
||
width: routeScroll.availableWidth
|
||
spacing: 0
|
||
|
||
// Countries
|
||
Repeater {
|
||
model: routeModel
|
||
delegate: PlasmaComponents.RadioDelegate {
|
||
width: listContainer.width
|
||
height: Kirigami.Units.gridUnit * 3
|
||
enabled: !countriesBlocked
|
||
checked: (model.code === current && model.provider === provider)
|
||
|
||
contentItem: RowLayout {
|
||
spacing: Kirigami.Units.largeSpacing
|
||
PlasmaComponents.Label {
|
||
horizontalAlignment: Text.AlignLeft
|
||
verticalAlignment: Text.AlignVCenter
|
||
wrapMode: Text.Wrap
|
||
font.pixelSize: 24
|
||
text: getFlag(model.code)
|
||
}
|
||
|
||
ColumnLayout {
|
||
spacing: 0
|
||
Layout.fillWidth: true
|
||
PlasmaComponents.Label {
|
||
text: model.name
|
||
font.bold: true
|
||
Layout.fillWidth: true
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: model.provider
|
||
font.pointSize: Kirigami.Theme.smallFont.pointSize
|
||
opacity: 0.7
|
||
Layout.fillWidth: true
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
}
|
||
}
|
||
onClicked: {
|
||
isLoadingItems += Plasmoid.configuration.BIpostcountry
|
||
superWorker.sendMessage({ "action": "post_country", "code": model.code, "provider": model.provider })
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
PlasmaComponents.ScrollView {
|
||
id: devicesScroll
|
||
anchors.fill: parent
|
||
ScrollBar.vertical.policy: scrollbartype
|
||
|
||
Column {
|
||
id: deviceListContainer
|
||
width: devicesScroll.availableWidth
|
||
spacing: Kirigami.Units.smallSpacing
|
||
Item {
|
||
width: deviceListContainer.width
|
||
height: Kirigami.Units.smallSpacing/2
|
||
}
|
||
|
||
// devices
|
||
Repeater {
|
||
model: devicesModel
|
||
delegate: PlasmaComponents.Button {
|
||
id: devicesButton
|
||
width: deviceListContainer.width
|
||
height: Kirigami.Units.gridUnit * 4
|
||
|
||
contentItem: RowLayout {
|
||
x: Kirigami.Units.largeSpacing
|
||
y: Kirigami.Units.largeSpacing
|
||
width: devicesButton.availableWidth
|
||
spacing: Kirigami.Units.smallSpacing
|
||
ColumnLayout {
|
||
spacing: 0
|
||
RowLayout {
|
||
Layout.fillWidth: true
|
||
PlasmaComponents.Label {
|
||
text: model.name
|
||
font.bold: true
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: "(LOSS 80%)"
|
||
color: "#f38ba8"
|
||
visible: model.ebalka
|
||
Layout.fillWidth: true
|
||
}
|
||
}
|
||
RowLayout {
|
||
PlasmaComponents.Label {
|
||
text: model.ip
|
||
font.pointSize: Kirigami.Theme.smallFont.pointSize
|
||
opacity: 0.7
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: "↓"
|
||
color: "#00ff00"
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: formatTraffic(model.rx)
|
||
font.pointSize: Kirigami.Theme.smallFont.pointSize
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: "↑"
|
||
color: "#00aaff"
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: formatTraffic(model.tx)
|
||
font.pointSize: Kirigami.Theme.smallFont.pointSize
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
}
|
||
RowLayout {
|
||
PlasmaComponents.Label {
|
||
text: getFlag(model.country)
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: model.country + " " + model.provider
|
||
opacity: 0.7
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: (model.online ? "online" : "offline")
|
||
color: (model.online ? "#a6e3a1" : "#f38ba8")
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
}
|
||
}
|
||
Item {
|
||
Layout.fillWidth: true
|
||
}
|
||
ColumnLayout {
|
||
RowLayout {
|
||
Item {
|
||
Layout.fillWidth: true
|
||
}
|
||
PlasmaComponents.Switch {
|
||
text: "80% loss"
|
||
checked: model.ebalka
|
||
enabled: !(isBlocked || devicesBlocked)
|
||
onClicked: {
|
||
isLoadingItems += Plasmoid.configuration.BIdevicesupdate
|
||
devicesBlocked = true
|
||
superWorker.sendMessage({ "action": "post_ebalka", "bool": !model.ebalka, "ip": model.ip })
|
||
// ebalka = !ebalka
|
||
}
|
||
}
|
||
}
|
||
RowLayout {
|
||
Item {
|
||
Layout.fillWidth: true
|
||
}
|
||
PlasmaComponents.Button {
|
||
id: menuButton
|
||
text: "Rename"
|
||
PlasmaComponents.Menu {
|
||
id: inputMenu
|
||
padding: Kirigami.Units.largeSpacing
|
||
|
||
function confirmAction() {
|
||
superWorker.sendMessage({ "action": "post_name", "ip": model.ip, "name": textInput.text })
|
||
inputMenu.close();
|
||
textInput.text = "";
|
||
}
|
||
|
||
ColumnLayout {
|
||
spacing: Kirigami.Units.smallSpacing
|
||
RowLayout {
|
||
PlasmaComponents.Label {
|
||
text: "Enter new name:"
|
||
font.pixelSize: Kirigami.Units.gridUnit * 0.8
|
||
}
|
||
}
|
||
RowLayout {
|
||
PlasmaComponents.TextField {
|
||
id: textInput
|
||
placeholderText: (model.name).split(" ").slice(2).join(" ")
|
||
focus: true
|
||
onAccepted: inputMenu.confirmAction()
|
||
}
|
||
PlasmaComponents.Button {
|
||
icon.name: "dialog-ok-apply"
|
||
onClicked: inputMenu.confirmAction()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
onClicked: {
|
||
inputMenu.open();
|
||
textInput.forceActiveFocus();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//onClicked: {
|
||
//}
|
||
}
|
||
}
|
||
Item {
|
||
width: deviceListContainer.width
|
||
height: Kirigami.Units.smallSpacing/2
|
||
}
|
||
}
|
||
}
|
||
|
||
PlasmaComponents.ScrollView {
|
||
id: statsScroll
|
||
anchors.fill: parent
|
||
ScrollBar.vertical.policy: scrollbartype
|
||
|
||
Column {
|
||
id: statsListContainer
|
||
width: statsScroll.availableWidth
|
||
spacing: Kirigami.Units.smallSpacing
|
||
Item {
|
||
width: statsListContainer.width
|
||
height: Kirigami.Units.smallSpacing/2
|
||
}
|
||
|
||
// stats
|
||
Repeater {
|
||
model: statsModel
|
||
delegate: PlasmaComponents.Button {
|
||
id: statsButton
|
||
width: statsListContainer.width
|
||
height: Kirigami.Units.gridUnit * 4
|
||
enabled: !(isBlocked || countriesBlocked)
|
||
|
||
contentItem: RowLayout {
|
||
x: Kirigami.Units.largeSpacing
|
||
y: Kirigami.Units.largeSpacing
|
||
width: statsButton.availableWidth
|
||
spacing: Kirigami.Units.smallSpacing
|
||
ColumnLayout {
|
||
spacing: 0
|
||
RowLayout {
|
||
Layout.fillWidth: true
|
||
PlasmaComponents.Label {
|
||
text: getFlag(model.country)
|
||
elide: Text.ElideRight
|
||
font.pixelSize: 16
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: model.name
|
||
font.bold: true
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: "Up: " + (Math.floor(model.uptime / 86400)) + "d " + (Math.floor((model.uptime % 86400) / 3600)) + "h " + (Math.floor(((model.uptime % 86400) % 3600) / 60)) + "m"
|
||
}
|
||
}
|
||
Item {
|
||
Layout.fillWidth: true
|
||
}
|
||
ColumnLayout {
|
||
spacing: 0
|
||
RowLayout {
|
||
Item {
|
||
Layout.fillWidth: true
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: model.connected + " peers (online: " + model.online + ")"
|
||
color: "#a6e3a1"
|
||
font.bold: true
|
||
}
|
||
}
|
||
RowLayout {
|
||
Item {
|
||
Layout.fillWidth: true
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: "↓"
|
||
color: "#00ff00"
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: formatTraffic(model.trafficString.split(" ")[0])
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: "(" + formatTraffic(model.speedString.split(" ")[0]) + ")"
|
||
opacity: 0.7
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: "↑"
|
||
color: "#00aaff"
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: formatTraffic(model.trafficString.split(" ")[1])
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: "(" + formatTraffic(model.speedString.split(" ")[1]) + ")"
|
||
opacity: 0.7
|
||
}
|
||
}
|
||
RowLayout {
|
||
Item {
|
||
Layout.fillWidth: true
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: model.pingString.split(" ").join(", ") + " ms"
|
||
color: "#a6e3a1"
|
||
font.bold: true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
onClicked: {
|
||
isLoadingItems += Plasmoid.configuration.BIpostcountry
|
||
superWorker.sendMessage({ "action": "post_idconnect", "iface": model.name })
|
||
}
|
||
}
|
||
}
|
||
Item {
|
||
width: statsListContainer.width
|
||
height: Kirigami.Units.smallSpacing/2
|
||
}
|
||
}
|
||
}
|
||
|
||
PlasmaComponents.ScrollView {
|
||
id: featuresScroll
|
||
anchors.fill: parent
|
||
ScrollBar.vertical.policy: scrollbartype
|
||
|
||
Column {
|
||
id: featuresListContainer
|
||
width: featuresScroll.availableWidth
|
||
spacing: Kirigami.Units.smallSpacing
|
||
Item {
|
||
width: featuresListContainer.width
|
||
height: Kirigami.Units.smallSpacing/2
|
||
}
|
||
|
||
// features
|
||
Repeater {
|
||
model: featuresModel
|
||
delegate: PlasmaComponents.Button {
|
||
id: featuresButton
|
||
width: featuresListContainer.width
|
||
height: Kirigami.Units.gridUnit * 4
|
||
|
||
contentItem: RowLayout {
|
||
x: Kirigami.Units.largeSpacing
|
||
y: Kirigami.Units.largeSpacing
|
||
width: featuresButton.availableWidth
|
||
spacing: Kirigami.Units.smallSpacing
|
||
ColumnLayout {
|
||
spacing: 2
|
||
Layout.fillWidth: true
|
||
PlasmaComponents.Label {
|
||
text: model.name
|
||
elide: Text.ElideRight
|
||
//font.pixelSize: 16
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
PlasmaComponents.Label {
|
||
text: model.desc
|
||
wrapMode: Text.Wrap
|
||
opacity: 0.7
|
||
//font.bold: true
|
||
elide: Text.ElideRight
|
||
verticalAlignment: Text.AlignVCenter
|
||
Layout.fillWidth: true
|
||
}
|
||
}
|
||
PlasmaComponents.Switch {
|
||
checked: model.value
|
||
enabled: !(isBlocked || featuresBlocked)
|
||
onClicked: {
|
||
isLoadingItems += Plasmoid.configuration.BIfeaturesupdate
|
||
//featuresBlocked = true
|
||
superWorker.sendMessage({ "action": "post_feature", "name": model.name, "value": !model.value })
|
||
}
|
||
}
|
||
}
|
||
//onClicked: {
|
||
//}
|
||
}
|
||
}
|
||
Item {
|
||
width: featuresListContainer.width
|
||
height: Kirigami.Units.smallSpacing/2
|
||
}
|
||
}
|
||
}
|
||
|
||
// Placeholder for other tabs
|
||
// PlasmaExtras.PlaceholderMessage { text: "Chairy Support" } // да в пизду крч нахуй надо
|
||
}
|
||
}
|
||
}
|
||
}
|