chore: fix rest of formatting issues
This commit is contained in:
parent
f46764fd5d
commit
25515fd32b
24 changed files with 582 additions and 597 deletions
|
|
@ -61,13 +61,6 @@ Item {
|
||||||
readOnly: root.readOnly
|
readOnly: root.readOnly
|
||||||
enabled: root.enabled
|
enabled: root.enabled
|
||||||
|
|
||||||
Binding {
|
|
||||||
target: inputField
|
|
||||||
property: "text"
|
|
||||||
value: root.text
|
|
||||||
when: !inputField.activeFocus
|
|
||||||
}
|
|
||||||
|
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
root.text = text;
|
root.text = text;
|
||||||
root.textEdited(text);
|
root.textEdited(text);
|
||||||
|
|
@ -76,6 +69,13 @@ Item {
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
root.editingFinished();
|
root.editingFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: inputField
|
||||||
|
property: "text"
|
||||||
|
value: root.text
|
||||||
|
when: !inputField.activeFocus
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,21 +15,6 @@ JsonObject {
|
||||||
property UseFuzzy useFuzzy: UseFuzzy {}
|
property UseFuzzy useFuzzy: UseFuzzy {}
|
||||||
property Sizes sizes: Sizes {}
|
property Sizes sizes: Sizes {}
|
||||||
|
|
||||||
component UseFuzzy: JsonObject {
|
|
||||||
property bool apps: false
|
|
||||||
property bool actions: false
|
|
||||||
property bool schemes: false
|
|
||||||
property bool variants: false
|
|
||||||
property bool wallpapers: false
|
|
||||||
}
|
|
||||||
|
|
||||||
component Sizes: JsonObject {
|
|
||||||
property int itemWidth: 600
|
|
||||||
property int itemHeight: 57
|
|
||||||
property int wallpaperWidth: 280
|
|
||||||
property int wallpaperHeight: 200
|
|
||||||
}
|
|
||||||
|
|
||||||
property list<var> actions: [
|
property list<var> actions: [
|
||||||
{
|
{
|
||||||
name: "Calculator",
|
name: "Calculator",
|
||||||
|
|
@ -144,4 +129,19 @@ JsonObject {
|
||||||
dangerous: false
|
dangerous: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
component UseFuzzy: JsonObject {
|
||||||
|
property bool apps: false
|
||||||
|
property bool actions: false
|
||||||
|
property bool schemes: false
|
||||||
|
property bool variants: false
|
||||||
|
property bool wallpapers: false
|
||||||
|
}
|
||||||
|
|
||||||
|
component Sizes: JsonObject {
|
||||||
|
property int itemWidth: 600
|
||||||
|
property int itemHeight: 57
|
||||||
|
property int wallpaperWidth: 280
|
||||||
|
property int wallpaperHeight: 200
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,31 +8,6 @@ JsonObject {
|
||||||
property Toasts toasts: Toasts {}
|
property Toasts toasts: Toasts {}
|
||||||
property Vpn vpn: Vpn {}
|
property Vpn vpn: Vpn {}
|
||||||
|
|
||||||
component Sizes: JsonObject {
|
|
||||||
property int width: 430
|
|
||||||
property int toastWidth: 430
|
|
||||||
}
|
|
||||||
|
|
||||||
component Toasts: JsonObject {
|
|
||||||
property bool configLoaded: true
|
|
||||||
property bool chargingChanged: true
|
|
||||||
property bool gameModeChanged: true
|
|
||||||
property bool dndChanged: true
|
|
||||||
property bool audioOutputChanged: true
|
|
||||||
property bool audioInputChanged: true
|
|
||||||
property bool capsLockChanged: true
|
|
||||||
property bool numLockChanged: true
|
|
||||||
property bool kbLayoutChanged: true
|
|
||||||
property bool kbLimit: true
|
|
||||||
property bool vpnChanged: true
|
|
||||||
property bool nowPlaying: false
|
|
||||||
}
|
|
||||||
|
|
||||||
component Vpn: JsonObject {
|
|
||||||
property bool enabled: false
|
|
||||||
property list<var> provider: ["netbird"]
|
|
||||||
}
|
|
||||||
|
|
||||||
property list<var> quickToggles: [
|
property list<var> quickToggles: [
|
||||||
{
|
{
|
||||||
id: "wifi",
|
id: "wifi",
|
||||||
|
|
@ -63,4 +38,29 @@ JsonObject {
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
component Sizes: JsonObject {
|
||||||
|
property int width: 430
|
||||||
|
property int toastWidth: 430
|
||||||
|
}
|
||||||
|
|
||||||
|
component Toasts: JsonObject {
|
||||||
|
property bool configLoaded: true
|
||||||
|
property bool chargingChanged: true
|
||||||
|
property bool gameModeChanged: true
|
||||||
|
property bool dndChanged: true
|
||||||
|
property bool audioOutputChanged: true
|
||||||
|
property bool audioInputChanged: true
|
||||||
|
property bool capsLockChanged: true
|
||||||
|
property bool numLockChanged: true
|
||||||
|
property bool kbLayoutChanged: true
|
||||||
|
property bool kbLimit: true
|
||||||
|
property bool vpnChanged: true
|
||||||
|
property bool nowPlaying: false
|
||||||
|
}
|
||||||
|
|
||||||
|
component Vpn: JsonObject {
|
||||||
|
property bool enabled: false
|
||||||
|
property list<var> provider: ["netbird"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,14 +90,14 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
component Pill: QtObject {
|
|
||||||
property int start
|
|
||||||
property int end
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: pillComp
|
id: pillComp
|
||||||
|
|
||||||
Pill {}
|
Pill {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
component Pill: QtObject {
|
||||||
|
property int start
|
||||||
|
property int end
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,76 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
asynchronous: true
|
||||||
|
active: Config.bar.workspaces.activeIndicator
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
sourceComponent: Item {
|
||||||
|
StyledClippingRect {
|
||||||
|
id: indicator
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
y: (view.currentItem?.y ?? 0) - view.contentY
|
||||||
|
implicitHeight: (view.currentItem as SpecialWsDelegate)?.size ?? 0
|
||||||
|
|
||||||
|
color: Colours.palette.m3tertiary
|
||||||
|
radius: Appearance.rounding.full
|
||||||
|
|
||||||
|
Colouriser {
|
||||||
|
source: view
|
||||||
|
sourceColor: Colours.palette.m3onSurface
|
||||||
|
colorizationColor: Colours.palette.m3onTertiary
|
||||||
|
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
x: 0
|
||||||
|
y: -indicator.y
|
||||||
|
implicitWidth: view.width
|
||||||
|
implicitHeight: view.height
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on y {
|
||||||
|
Anim {
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.emphasized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
Anim {
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.emphasized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
property real startY
|
||||||
|
|
||||||
|
anchors.fill: view
|
||||||
|
|
||||||
|
drag.target: view.contentItem
|
||||||
|
drag.axis: Drag.YAxis
|
||||||
|
drag.maximumY: 0
|
||||||
|
drag.minimumY: Math.min(0, view.height - view.contentHeight - Appearance.padding.small)
|
||||||
|
|
||||||
|
onPressed: event => startY = event.y
|
||||||
|
|
||||||
|
onClicked: event => {
|
||||||
|
if (Math.abs(event.y - startY) > drag.threshold)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ws = view.itemAt(event.x, event.y) as SpecialWsDelegate;
|
||||||
|
if (ws?.modelData)
|
||||||
|
Hypr.dispatch(`togglespecialworkspace ${ws.modelData.name.slice(8)}`);
|
||||||
|
else
|
||||||
|
Hypr.dispatch("togglespecialworkspace special");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
component SpecialWsDelegate: ColumnLayout {
|
component SpecialWsDelegate: ColumnLayout {
|
||||||
id: ws
|
id: ws
|
||||||
|
|
||||||
|
|
@ -297,74 +367,4 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
|
||||||
asynchronous: true
|
|
||||||
active: Config.bar.workspaces.activeIndicator
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
sourceComponent: Item {
|
|
||||||
StyledClippingRect {
|
|
||||||
id: indicator
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
y: (view.currentItem?.y ?? 0) - view.contentY
|
|
||||||
implicitHeight: (view.currentItem as SpecialWsDelegate)?.size ?? 0
|
|
||||||
|
|
||||||
color: Colours.palette.m3tertiary
|
|
||||||
radius: Appearance.rounding.full
|
|
||||||
|
|
||||||
Colouriser {
|
|
||||||
source: view
|
|
||||||
sourceColor: Colours.palette.m3onSurface
|
|
||||||
colorizationColor: Colours.palette.m3onTertiary
|
|
||||||
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
x: 0
|
|
||||||
y: -indicator.y
|
|
||||||
implicitWidth: view.width
|
|
||||||
implicitHeight: view.height
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on y {
|
|
||||||
Anim {
|
|
||||||
easing.bezierCurve: Appearance.anim.curves.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on implicitHeight {
|
|
||||||
Anim {
|
|
||||||
easing.bezierCurve: Appearance.anim.curves.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
property real startY
|
|
||||||
|
|
||||||
anchors.fill: view
|
|
||||||
|
|
||||||
drag.target: view.contentItem
|
|
||||||
drag.axis: Drag.YAxis
|
|
||||||
drag.maximumY: 0
|
|
||||||
drag.minimumY: Math.min(0, view.height - view.contentHeight - Appearance.padding.small)
|
|
||||||
|
|
||||||
onPressed: event => startY = event.y
|
|
||||||
|
|
||||||
onClicked: event => {
|
|
||||||
if (Math.abs(event.y - startY) > drag.threshold)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const ws = view.itemAt(event.x, event.y) as SpecialWsDelegate;
|
|
||||||
if (ws?.modelData)
|
|
||||||
Hypr.dispatch(`togglespecialworkspace ${ws.modelData.name.slice(8)}`);
|
|
||||||
else
|
|
||||||
Hypr.dispatch("togglespecialworkspace special");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,12 @@ StackView {
|
||||||
popEnter: NoAnim {}
|
popEnter: NoAnim {}
|
||||||
popExit: NoAnim {}
|
popExit: NoAnim {}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: subMenuComp
|
||||||
|
|
||||||
|
SubMenu {}
|
||||||
|
}
|
||||||
|
|
||||||
component NoAnim: Transition {
|
component NoAnim: Transition {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: 0
|
duration: 0
|
||||||
|
|
@ -221,10 +227,4 @@ StackView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
|
||||||
id: subMenuComp
|
|
||||||
|
|
||||||
SubMenu {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -267,6 +267,13 @@ ColumnLayout {
|
||||||
focus: true
|
focus: true
|
||||||
activeFocusOnTab: true
|
activeFocusOnTab: true
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (root.shouldBeVisible) {
|
||||||
|
// Use Timer for actual delay to ensure focus works correctly
|
||||||
|
passwordFocusTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Keys.onPressed: event => {
|
Keys.onPressed: event => {
|
||||||
// Ensure we have focus when receiving keyboard input
|
// Ensure we have focus when receiving keyboard input
|
||||||
if (!activeFocus) {
|
if (!activeFocus) {
|
||||||
|
|
@ -318,13 +325,6 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
if (root.shouldBeVisible) {
|
|
||||||
// Use Timer for actual delay to ensure focus works correctly
|
|
||||||
passwordFocusTimer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,11 @@ import qs.config
|
||||||
Item {
|
Item {
|
||||||
id: model
|
id: model
|
||||||
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: _visibleModel
|
|
||||||
}
|
|
||||||
|
|
||||||
property alias visibleModel: _visibleModel
|
property alias visibleModel: _visibleModel
|
||||||
|
|
||||||
property string activeLabel: ""
|
property string activeLabel: ""
|
||||||
|
|
||||||
property int activeIndex: -1
|
property int activeIndex: -1
|
||||||
|
property var _xkbMap: ({})
|
||||||
|
property bool _notifiedLimit: false
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
_xkbXmlBase.running = true;
|
_xkbXmlBase.running = true;
|
||||||
|
|
@ -127,14 +121,16 @@ Item {
|
||||||
return code.toUpperCase() + " - " + code;
|
return code.toUpperCase() + " - " + code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: _visibleModel
|
||||||
|
}
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
id: _layoutsModel
|
id: _layoutsModel
|
||||||
}
|
}
|
||||||
|
|
||||||
property var _xkbMap: ({})
|
|
||||||
|
|
||||||
property bool _notifiedLimit: false
|
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: _xkbXmlBase
|
id: _xkbXmlBase
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ CollapsibleSection {
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
border.width: isCurrent ? 1 : 0
|
border.width: isCurrent ? 1 : 0
|
||||||
border.color: Colours.palette.m3primary
|
border.color: Colours.palette.m3primary
|
||||||
|
implicitHeight: schemeRow.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
|
|
@ -140,8 +141,6 @@ CollapsibleSection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: schemeRow.implicitHeight + Appearance.padding.normal * 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ CollapsibleSection {
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
border.width: modelData.variant === Schemes.currentVariant ? 1 : 0
|
border.width: modelData.variant === Schemes.currentVariant ? 1 : 0
|
||||||
border.color: Colours.palette.m3primary
|
border.color: Colours.palette.m3primary
|
||||||
|
implicitHeight: variantRow.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
|
|
@ -84,8 +85,6 @@ CollapsibleSection {
|
||||||
font.pointSize: Appearance.font.size.large
|
font.pointSize: Appearance.font.size.large
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: variantRow.implicitHeight + Appearance.padding.normal * 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ CollapsibleSection {
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
border.width: isCurrent ? 1 : 0
|
border.width: isCurrent ? 1 : 0
|
||||||
border.color: Colours.palette.m3primary
|
border.color: Colours.palette.m3primary
|
||||||
|
implicitHeight: fontFamilySansRow.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
|
|
@ -93,8 +94,6 @@ CollapsibleSection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: fontFamilySansRow.implicitHeight + Appearance.padding.normal * 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -137,6 +136,7 @@ CollapsibleSection {
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
border.width: isCurrent ? 1 : 0
|
border.width: isCurrent ? 1 : 0
|
||||||
border.color: Colours.palette.m3primary
|
border.color: Colours.palette.m3primary
|
||||||
|
implicitHeight: fontFamilyMonoRow.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
|
|
@ -175,8 +175,6 @@ CollapsibleSection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: fontFamilyMonoRow.implicitHeight + Appearance.padding.normal * 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -221,6 +219,7 @@ CollapsibleSection {
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
border.width: isCurrent ? 1 : 0
|
border.width: isCurrent ? 1 : 0
|
||||||
border.color: Colours.palette.m3primary
|
border.color: Colours.palette.m3primary
|
||||||
|
implicitHeight: fontFamilyMaterialRow.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
|
|
@ -259,8 +258,6 @@ CollapsibleSection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: fontFamilyMaterialRow.implicitHeight + Appearance.padding.normal * 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,7 @@ Item {
|
||||||
|
|
||||||
color: Audio.sink?.id === modelData.id ? Colours.layer(Colours.palette.m3surfaceContainer, 2) : "transparent"
|
color: Audio.sink?.id === modelData.id ? Colours.layer(Colours.palette.m3surfaceContainer, 2) : "transparent"
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
|
implicitHeight: outputRowLayout.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
|
|
@ -126,8 +127,6 @@ Item {
|
||||||
font.weight: Audio.sink?.id === modelData.id ? 500 : 400
|
font.weight: Audio.sink?.id === modelData.id ? 500 : 400
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: outputRowLayout.implicitHeight + Appearance.padding.normal * 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -172,6 +171,7 @@ Item {
|
||||||
|
|
||||||
color: Audio.source?.id === modelData.id ? Colours.layer(Colours.palette.m3surfaceContainer, 2) : "transparent"
|
color: Audio.source?.id === modelData.id ? Colours.layer(Colours.palette.m3surfaceContainer, 2) : "transparent"
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
|
implicitHeight: inputRowLayout.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
|
|
@ -204,8 +204,6 @@ Item {
|
||||||
font.weight: Audio.source?.id === modelData.id ? 500 : 400
|
font.weight: Audio.source?.id === modelData.id ? 500 : 400
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: inputRowLayout.implicitHeight + Appearance.padding.normal * 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -278,16 +276,6 @@ Item {
|
||||||
text = Math.round(Audio.volume * 100).toString();
|
text = Math.round(Audio.volume * 100).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
function onVolumeChanged() {
|
|
||||||
if (!outputVolumeInput.hasFocus) {
|
|
||||||
outputVolumeInput.text = Math.round(Audio.volume * 100).toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
target: Audio
|
|
||||||
}
|
|
||||||
|
|
||||||
onTextEdited: text => {
|
onTextEdited: text => {
|
||||||
if (hasFocus) {
|
if (hasFocus) {
|
||||||
const val = parseInt(text);
|
const val = parseInt(text);
|
||||||
|
|
@ -303,6 +291,16 @@ Item {
|
||||||
text = Math.round(Audio.volume * 100).toString();
|
text = Math.round(Audio.volume * 100).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onVolumeChanged() {
|
||||||
|
if (!outputVolumeInput.hasFocus) {
|
||||||
|
outputVolumeInput.text = Math.round(Audio.volume * 100).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target: Audio
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|
@ -396,16 +394,6 @@ Item {
|
||||||
text = Math.round(Audio.sourceVolume * 100).toString();
|
text = Math.round(Audio.sourceVolume * 100).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
function onSourceVolumeChanged() {
|
|
||||||
if (!inputVolumeInput.hasFocus) {
|
|
||||||
inputVolumeInput.text = Math.round(Audio.sourceVolume * 100).toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
target: Audio
|
|
||||||
}
|
|
||||||
|
|
||||||
onTextEdited: text => {
|
onTextEdited: text => {
|
||||||
if (hasFocus) {
|
if (hasFocus) {
|
||||||
const val = parseInt(text);
|
const val = parseInt(text);
|
||||||
|
|
@ -421,6 +409,16 @@ Item {
|
||||||
text = Math.round(Audio.sourceVolume * 100).toString();
|
text = Math.round(Audio.sourceVolume * 100).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onSourceVolumeChanged() {
|
||||||
|
if (!inputVolumeInput.hasFocus) {
|
||||||
|
inputVolumeInput.text = Math.round(Audio.sourceVolume * 100).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target: Audio
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|
@ -530,16 +528,6 @@ Item {
|
||||||
text = Math.round(Audio.getStreamVolume(modelData) * 100).toString();
|
text = Math.round(Audio.getStreamVolume(modelData) * 100).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
function onAudioChanged() {
|
|
||||||
if (!streamVolumeInput.hasFocus && modelData?.audio) {
|
|
||||||
streamVolumeInput.text = Math.round(modelData.audio.volume * 100).toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
target: modelData
|
|
||||||
}
|
|
||||||
|
|
||||||
onTextEdited: text => {
|
onTextEdited: text => {
|
||||||
if (hasFocus) {
|
if (hasFocus) {
|
||||||
const val = parseInt(text);
|
const val = parseInt(text);
|
||||||
|
|
@ -555,6 +543,16 @@ Item {
|
||||||
text = Math.round(Audio.getStreamVolume(modelData) * 100).toString();
|
text = Math.round(Audio.getStreamVolume(modelData) * 100).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onAudioChanged() {
|
||||||
|
if (!streamVolumeInput.hasFocus && modelData?.audio) {
|
||||||
|
streamVolumeInput.text = Math.round(modelData.audio.volume * 100).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target: modelData
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ ColumnLayout {
|
||||||
property Component headerComponent: null
|
property Component headerComponent: null
|
||||||
property Component titleSuffix: null
|
property Component titleSuffix: null
|
||||||
property bool showHeader: true
|
property bool showHeader: true
|
||||||
|
property alias view: view
|
||||||
|
|
||||||
signal itemSelected(var item)
|
signal itemSelected(var item)
|
||||||
|
|
||||||
|
|
@ -61,8 +62,6 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property alias view: view
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
visible: root.description !== ""
|
visible: root.description !== ""
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
||||||
|
|
@ -152,14 +152,6 @@ ColumnLayout {
|
||||||
to: root.to
|
to: root.to
|
||||||
stepSize: root.stepSize
|
stepSize: root.stepSize
|
||||||
|
|
||||||
// Use Binding to allow slider to move freely during dragging
|
|
||||||
Binding {
|
|
||||||
target: slider
|
|
||||||
property: "value"
|
|
||||||
value: root.value
|
|
||||||
when: !slider.pressed
|
|
||||||
}
|
|
||||||
|
|
||||||
onValueChanged: {
|
onValueChanged: {
|
||||||
// Update input field text in real-time as slider moves during dragging
|
// Update input field text in real-time as slider moves during dragging
|
||||||
// Always update when slider value changes (during dragging or external updates)
|
// Always update when slider value changes (during dragging or external updates)
|
||||||
|
|
@ -176,5 +168,13 @@ ColumnLayout {
|
||||||
inputField.text = root.formatValue(newValue);
|
inputField.text = root.formatValue(newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use Binding to allow slider to move freely during dragging
|
||||||
|
Binding {
|
||||||
|
target: slider
|
||||||
|
property: "value"
|
||||||
|
value: root.value
|
||||||
|
when: !slider.pressed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,11 @@ Item {
|
||||||
nextComponent = targetComponent;
|
nextComponent = targetComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onPaneChanged: {
|
||||||
|
nextComponent = getComponentForPane();
|
||||||
|
paneId = root.paneIdGenerator(pane);
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: rightLoader
|
id: rightLoader
|
||||||
|
|
||||||
|
|
@ -74,11 +79,6 @@ Item {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onPaneChanged: {
|
|
||||||
nextComponent = getComponentForPane();
|
|
||||||
paneId = root.paneIdGenerator(pane);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -154,16 +154,16 @@ GridView {
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
opacity = 1;
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: 1000
|
duration: 1000
|
||||||
easing.type: Easing.OutCubic
|
easing.type: Easing.OutCubic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
opacity = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -219,16 +219,16 @@ GridView {
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
opacity = 1;
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: 1000
|
duration: 1000
|
||||||
easing.type: Easing.OutCubic
|
easing.type: Easing.OutCubic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
opacity = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -317,6 +317,10 @@ Item {
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
opacity = 1;
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: 1000
|
duration: 1000
|
||||||
|
|
@ -324,10 +328,6 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
opacity = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
root.session.launcher.active = modelData;
|
root.session.launcher.active = modelData;
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,7 @@ ColumnLayout {
|
||||||
required property int index
|
required property int index
|
||||||
|
|
||||||
width: ListView.view ? ListView.view.width : undefined
|
width: ListView.view ? ListView.view.width : undefined
|
||||||
|
implicitHeight: rowLayout.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
|
||||||
color: Qt.alpha(Colours.tPalette.m3surfaceContainer, (root.session && root.session.vpn && root.session.vpn.active === modelData) ? Colours.tPalette.m3surfaceContainer.a : 0)
|
color: Qt.alpha(Colours.tPalette.m3surfaceContainer, (root.session && root.session.vpn && root.session.vpn.active === modelData) ? Colours.tPalette.m3surfaceContainer.a : 0)
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
|
|
@ -258,8 +259,6 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: rowLayout.implicitHeight + Appearance.padding.normal * 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ ColumnLayout {
|
||||||
required property int index
|
required property int index
|
||||||
|
|
||||||
width: ListView.view ? ListView.view.width : undefined
|
width: ListView.view ? ListView.view.width : undefined
|
||||||
|
implicitHeight: 60
|
||||||
color: Colours.tPalette.m3surfaceContainerHigh
|
color: Colours.tPalette.m3surfaceContainerHigh
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
|
|
||||||
|
|
@ -147,8 +148,6 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: 60
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ DeviceList {
|
||||||
required property var modelData
|
required property var modelData
|
||||||
|
|
||||||
width: ListView.view ? ListView.view.width : undefined
|
width: ListView.view ? ListView.view.width : undefined
|
||||||
|
implicitHeight: rowLayout.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
|
||||||
color: Qt.alpha(Colours.tPalette.m3surfaceContainer, root.activeItem === modelData ? Colours.tPalette.m3surfaceContainer.a : 0)
|
color: Qt.alpha(Colours.tPalette.m3surfaceContainer, root.activeItem === modelData ? Colours.tPalette.m3surfaceContainer.a : 0)
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
|
|
@ -214,8 +215,6 @@ DeviceList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: rowLayout.implicitHeight + Appearance.padding.normal * 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ Item {
|
||||||
color: Colours.tPalette.m3surface
|
color: Colours.tPalette.m3surface
|
||||||
opacity: root.session.network.showPasswordDialog && !root.isClosing ? 1 : 0
|
opacity: root.session.network.showPasswordDialog && !root.isClosing ? 1 : 0
|
||||||
scale: root.session.network.showPasswordDialog && !root.isClosing ? 1 : 0.7
|
scale: root.session.network.showPasswordDialog && !root.isClosing ? 1 : 0.7
|
||||||
|
Keys.onEscapePressed: closeDialog()
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {}
|
Anim {}
|
||||||
|
|
@ -135,8 +136,6 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onEscapePressed: closeDialog()
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,96 +38,6 @@ Singleton {
|
||||||
"Referer": "https://music.163.com/"
|
"Referer": "https://music.163.com/"
|
||||||
})
|
})
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: lyricsModel
|
|
||||||
}
|
|
||||||
ListModel {
|
|
||||||
id: fetchedCandidatesModel
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: seekTimer
|
|
||||||
|
|
||||||
interval: 500
|
|
||||||
onTriggered: root.isManualSeeking = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no local lyrics were loaded within the interval, fall back to NetEase
|
|
||||||
Timer {
|
|
||||||
id: fallbackTimer
|
|
||||||
|
|
||||||
interval: 200
|
|
||||||
onTriggered: {
|
|
||||||
if (lyricsModel.count === 0) {
|
|
||||||
root.backend = "NetEase";
|
|
||||||
fallbackToOnline();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: loadDebounce
|
|
||||||
|
|
||||||
interval: 50
|
|
||||||
onTriggered: root._doLoadLyrics()
|
|
||||||
}
|
|
||||||
|
|
||||||
FileView {
|
|
||||||
id: lyricsMapFileView
|
|
||||||
|
|
||||||
path: root.lyricsMapFile
|
|
||||||
printErrors: false
|
|
||||||
onLoaded: {
|
|
||||||
try {
|
|
||||||
root.lyricsMap = JSON.parse(text());
|
|
||||||
} catch (e) {
|
|
||||||
root.lyricsMap = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FileView {
|
|
||||||
id: lrcFile
|
|
||||||
|
|
||||||
printErrors: false
|
|
||||||
onLoaded: {
|
|
||||||
fallbackTimer.stop();
|
|
||||||
let parsed = Lrc.parseLrc(text());
|
|
||||||
if (parsed.length > 0) {
|
|
||||||
root.backend = "Local";
|
|
||||||
updateModel(parsed);
|
|
||||||
loading = false;
|
|
||||||
} else {
|
|
||||||
root.backend = "NetEase";
|
|
||||||
fallbackToOnline();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
function onActiveChanged() {
|
|
||||||
root.player = Players.active;
|
|
||||||
loadLyrics();
|
|
||||||
}
|
|
||||||
|
|
||||||
target: Players
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
function onMetadataChanged() {
|
|
||||||
loadLyrics();
|
|
||||||
}
|
|
||||||
|
|
||||||
target: root.player
|
|
||||||
ignoreUnknownSignals: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
|
||||||
id: saveLyricsMap
|
|
||||||
|
|
||||||
command: ["sh", "-c", `mkdir -p "${root.lyricsDir}" && echo '${JSON.stringify(root.lyricsMap)}' > "${root.lyricsMapFile}"`]
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMetadata() {
|
function getMetadata() {
|
||||||
if (!player || !player.metadata)
|
if (!player || !player.metadata)
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -345,4 +255,95 @@ Singleton {
|
||||||
|
|
||||||
seekTimer.restart();
|
seekTimer.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: lyricsModel
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: fetchedCandidatesModel
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: seekTimer
|
||||||
|
|
||||||
|
interval: 500
|
||||||
|
onTriggered: root.isManualSeeking = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no local lyrics were loaded within the interval, fall back to NetEase
|
||||||
|
Timer {
|
||||||
|
id: fallbackTimer
|
||||||
|
|
||||||
|
interval: 200
|
||||||
|
onTriggered: {
|
||||||
|
if (lyricsModel.count === 0) {
|
||||||
|
root.backend = "NetEase";
|
||||||
|
fallbackToOnline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: loadDebounce
|
||||||
|
|
||||||
|
interval: 50
|
||||||
|
onTriggered: root._doLoadLyrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
FileView {
|
||||||
|
id: lyricsMapFileView
|
||||||
|
|
||||||
|
path: root.lyricsMapFile
|
||||||
|
printErrors: false
|
||||||
|
onLoaded: {
|
||||||
|
try {
|
||||||
|
root.lyricsMap = JSON.parse(text());
|
||||||
|
} catch (e) {
|
||||||
|
root.lyricsMap = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileView {
|
||||||
|
id: lrcFile
|
||||||
|
|
||||||
|
printErrors: false
|
||||||
|
onLoaded: {
|
||||||
|
fallbackTimer.stop();
|
||||||
|
let parsed = Lrc.parseLrc(text());
|
||||||
|
if (parsed.length > 0) {
|
||||||
|
root.backend = "Local";
|
||||||
|
updateModel(parsed);
|
||||||
|
loading = false;
|
||||||
|
} else {
|
||||||
|
root.backend = "NetEase";
|
||||||
|
fallbackToOnline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onActiveChanged() {
|
||||||
|
root.player = Players.active;
|
||||||
|
loadLyrics();
|
||||||
|
}
|
||||||
|
|
||||||
|
target: Players
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onMetadataChanged() {
|
||||||
|
loadLyrics();
|
||||||
|
}
|
||||||
|
|
||||||
|
target: root.player
|
||||||
|
ignoreUnknownSignals: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: saveLyricsMap
|
||||||
|
|
||||||
|
command: ["sh", "-c", `mkdir -p "${root.lyricsDir}" && echo '${JSON.stringify(root.lyricsMap)}' > "${root.lyricsMapFile}"`]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -313,6 +313,12 @@ Singleton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: apComp
|
||||||
|
|
||||||
|
AccessPoint {}
|
||||||
|
}
|
||||||
|
|
||||||
component AccessPoint: QtObject {
|
component AccessPoint: QtObject {
|
||||||
required property var lastIpcObject
|
required property var lastIpcObject
|
||||||
readonly property string ssid: lastIpcObject.ssid
|
readonly property string ssid: lastIpcObject.ssid
|
||||||
|
|
@ -323,10 +329,4 @@ Singleton {
|
||||||
readonly property string security: lastIpcObject.security
|
readonly property string security: lastIpcObject.security
|
||||||
readonly property bool isSecure: security.length > 0
|
readonly property bool isSecure: security.length > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
|
||||||
id: apComp
|
|
||||||
|
|
||||||
AccessPoint {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -872,79 +872,223 @@ Singleton {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
component CommandProcess: Process {
|
function checkPendingConnection(): void {
|
||||||
id: proc
|
if (root.pendingConnection) {
|
||||||
|
Qt.callLater(() => {
|
||||||
property var callback: null
|
const connected = root.active && root.active.ssid === root.pendingConnection.ssid;
|
||||||
property list<string> command: []
|
if (connected) {
|
||||||
property bool callbackCalled: false
|
connectionCheckTimer.stop();
|
||||||
property int exitCode: 0
|
immediateCheckTimer.stop();
|
||||||
|
immediateCheckTimer.checkCount = 0;
|
||||||
signal processFinished
|
if (root.pendingConnection.callback) {
|
||||||
|
root.pendingConnection.callback({
|
||||||
environment: ({
|
success: true,
|
||||||
LANG: "C.UTF-8",
|
output: "Connected",
|
||||||
LC_ALL: "C.UTF-8"
|
error: "",
|
||||||
})
|
exitCode: 0
|
||||||
|
});
|
||||||
stdout: StdioCollector {
|
}
|
||||||
id: stdoutCollector
|
root.pendingConnection = null;
|
||||||
|
} else {
|
||||||
|
if (!immediateCheckTimer.running) {
|
||||||
|
immediateCheckTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stderr: StdioCollector {
|
function cidrToSubnetMask(cidr: string): string {
|
||||||
id: stderrCollector
|
const cidrNum = parseInt(cidr, 10);
|
||||||
|
if (isNaN(cidrNum) || cidrNum < 0 || cidrNum > 32) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
onStreamFinished: {
|
const mask = (0xffffffff << (32 - cidrNum)) >>> 0;
|
||||||
const error = text.trim();
|
const octet1 = (mask >>> 24) & 0xff;
|
||||||
if (error && error.length > 0) {
|
const octet2 = (mask >>> 16) & 0xff;
|
||||||
const output = (stdoutCollector && stdoutCollector.text) ? stdoutCollector.text : "";
|
const octet3 = (mask >>> 8) & 0xff;
|
||||||
root.handlePasswordRequired(proc, error, output, -1);
|
const octet4 = mask & 0xff;
|
||||||
|
|
||||||
|
return `${octet1}.${octet2}.${octet3}.${octet4}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWirelessDeviceDetails(interfaceName: string, callback: var): void {
|
||||||
|
if (!interfaceName || interfaceName.length === 0) {
|
||||||
|
const activeInterface = root.wirelessInterfaces.find(iface => {
|
||||||
|
return isConnectedState(iface.state);
|
||||||
|
});
|
||||||
|
if (activeInterface && activeInterface.device) {
|
||||||
|
interfaceName = activeInterface.device;
|
||||||
|
} else {
|
||||||
|
if (callback)
|
||||||
|
callback(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
executeCommand(["device", "show", interfaceName], result => {
|
||||||
|
if (!result.success || !result.output) {
|
||||||
|
root.wirelessDeviceDetails = null;
|
||||||
|
if (callback)
|
||||||
|
callback(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const details = parseDeviceDetails(result.output, false);
|
||||||
|
root.wirelessDeviceDetails = details;
|
||||||
|
if (callback)
|
||||||
|
callback(details);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEthernetDeviceDetails(interfaceName: string, callback: var): void {
|
||||||
|
if (!interfaceName || interfaceName.length === 0) {
|
||||||
|
const activeInterface = root.ethernetInterfaces.find(iface => {
|
||||||
|
return isConnectedState(iface.state);
|
||||||
|
});
|
||||||
|
if (activeInterface && activeInterface.device) {
|
||||||
|
interfaceName = activeInterface.device;
|
||||||
|
} else {
|
||||||
|
if (callback)
|
||||||
|
callback(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
executeCommand(["device", "show", interfaceName], result => {
|
||||||
|
if (!result.success || !result.output) {
|
||||||
|
root.ethernetDeviceDetails = null;
|
||||||
|
if (callback)
|
||||||
|
callback(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const details = parseDeviceDetails(result.output, true);
|
||||||
|
root.ethernetDeviceDetails = details;
|
||||||
|
if (callback)
|
||||||
|
callback(details);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseDeviceDetails(output: string, isEthernet: bool): var {
|
||||||
|
const details = {
|
||||||
|
ipAddress: "",
|
||||||
|
gateway: "",
|
||||||
|
dns: [],
|
||||||
|
subnet: "",
|
||||||
|
macAddress: "",
|
||||||
|
speed: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!output || output.length === 0) {
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lines = output.trim().split("\n");
|
||||||
|
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const line = lines[i];
|
||||||
|
const parts = line.split(":");
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
const key = parts[0].trim();
|
||||||
|
const value = parts.slice(1).join(":").trim();
|
||||||
|
|
||||||
|
if (key.startsWith("IP4.ADDRESS")) {
|
||||||
|
const ipParts = value.split("/");
|
||||||
|
details.ipAddress = ipParts[0] || "";
|
||||||
|
if (ipParts[1]) {
|
||||||
|
details.subnet = cidrToSubnetMask(ipParts[1]);
|
||||||
|
} else {
|
||||||
|
details.subnet = "";
|
||||||
|
}
|
||||||
|
} else if (key === "IP4.GATEWAY") {
|
||||||
|
if (value !== "--") {
|
||||||
|
details.gateway = value;
|
||||||
|
}
|
||||||
|
} else if (key.startsWith("IP4.DNS")) {
|
||||||
|
if (value !== "--" && value.length > 0) {
|
||||||
|
details.dns.push(value);
|
||||||
|
}
|
||||||
|
} else if (isEthernet && key === "WIRED-PROPERTIES.MAC") {
|
||||||
|
details.macAddress = value;
|
||||||
|
} else if (isEthernet && key === "WIRED-PROPERTIES.SPEED") {
|
||||||
|
details.speed = value;
|
||||||
|
} else if (!isEthernet && key === "GENERAL.HWADDR") {
|
||||||
|
details.macAddress = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onExited: code => { // qmllint disable signal-handler-parameters
|
return details;
|
||||||
exitCode = code;
|
}
|
||||||
|
|
||||||
|
function refreshOnConnectionChange(): void {
|
||||||
|
getNetworks(networks => {
|
||||||
|
const newActive = root.active;
|
||||||
|
|
||||||
|
if (newActive && newActive.active) {
|
||||||
|
Qt.callLater(() => {
|
||||||
|
if (root.wirelessInterfaces.length > 0) {
|
||||||
|
const activeWireless = root.wirelessInterfaces.find(iface => {
|
||||||
|
return isConnectedState(iface.state);
|
||||||
|
});
|
||||||
|
if (activeWireless && activeWireless.device) {
|
||||||
|
getWirelessDeviceDetails(activeWireless.device, () => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root.ethernetInterfaces.length > 0) {
|
||||||
|
const activeEthernet = root.ethernetInterfaces.find(iface => {
|
||||||
|
return isConnectedState(iface.state);
|
||||||
|
});
|
||||||
|
if (activeEthernet && activeEthernet.device) {
|
||||||
|
getEthernetDeviceDetails(activeEthernet.device, () => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
} else {
|
||||||
|
root.wirelessDeviceDetails = null;
|
||||||
|
root.ethernetDeviceDetails = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getWirelessInterfaces(() => {});
|
||||||
|
getEthernetInterfaces(() => {
|
||||||
|
if (root.activeEthernet && root.activeEthernet.connected) {
|
||||||
|
Qt.callLater(() => {
|
||||||
|
getEthernetDeviceDetails(root.activeEthernet.interface, () => {});
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
getWifiStatus(() => {});
|
||||||
|
getNetworks(() => {});
|
||||||
|
loadSavedConnections(() => {});
|
||||||
|
getEthernetInterfaces(() => {});
|
||||||
|
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
if (callbackCalled) {
|
if (root.wirelessInterfaces.length > 0) {
|
||||||
processFinished();
|
const activeWireless = root.wirelessInterfaces.find(iface => {
|
||||||
return;
|
return isConnectedState(iface.state);
|
||||||
}
|
|
||||||
|
|
||||||
if (proc.callback) {
|
|
||||||
const output = (stdoutCollector && stdoutCollector.text) ? stdoutCollector.text : "";
|
|
||||||
const error = (stderrCollector && stderrCollector.text) ? stderrCollector.text : "";
|
|
||||||
const success = exitCode === 0;
|
|
||||||
const cmdIsConnection = isConnectionCommand(proc.command);
|
|
||||||
|
|
||||||
if (root.handlePasswordRequired(proc, error, output, exitCode)) {
|
|
||||||
processFinished();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const needsPassword = cmdIsConnection && root.detectPasswordRequired(error);
|
|
||||||
|
|
||||||
if (!success && cmdIsConnection && root.pendingConnection) {
|
|
||||||
const failedSsid = root.pendingConnection.ssid;
|
|
||||||
root.connectionFailed(failedSsid);
|
|
||||||
}
|
|
||||||
|
|
||||||
callbackCalled = true;
|
|
||||||
callback({
|
|
||||||
success: success,
|
|
||||||
output: output,
|
|
||||||
error: error,
|
|
||||||
exitCode: proc.exitCode,
|
|
||||||
needsPassword: needsPassword || false
|
|
||||||
});
|
});
|
||||||
processFinished();
|
if (activeWireless && activeWireless.device) {
|
||||||
} else {
|
getWirelessDeviceDetails(activeWireless.device, () => {});
|
||||||
processFinished();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root.ethernetInterfaces.length > 0) {
|
||||||
|
const activeEthernet = root.ethernetInterfaces.find(iface => {
|
||||||
|
return isConnectedState(iface.state);
|
||||||
});
|
});
|
||||||
|
if (activeEthernet && activeEthernet.device) {
|
||||||
|
getEthernetDeviceDetails(activeEthernet.device, () => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: commandProc
|
id: commandProc
|
||||||
|
|
@ -952,17 +1096,6 @@ Singleton {
|
||||||
CommandProcess {}
|
CommandProcess {}
|
||||||
}
|
}
|
||||||
|
|
||||||
component AccessPoint: QtObject {
|
|
||||||
required property var lastIpcObject
|
|
||||||
readonly property string ssid: lastIpcObject.ssid
|
|
||||||
readonly property string bssid: lastIpcObject.bssid
|
|
||||||
readonly property int strength: lastIpcObject.strength
|
|
||||||
readonly property int frequency: lastIpcObject.frequency
|
|
||||||
readonly property bool active: lastIpcObject.active
|
|
||||||
readonly property string security: lastIpcObject.security
|
|
||||||
readonly property bool isSecure: security.length > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: apComp
|
id: apComp
|
||||||
|
|
||||||
|
|
@ -1113,157 +1246,6 @@ Singleton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkPendingConnection(): void {
|
|
||||||
if (root.pendingConnection) {
|
|
||||||
Qt.callLater(() => {
|
|
||||||
const connected = root.active && root.active.ssid === root.pendingConnection.ssid;
|
|
||||||
if (connected) {
|
|
||||||
connectionCheckTimer.stop();
|
|
||||||
immediateCheckTimer.stop();
|
|
||||||
immediateCheckTimer.checkCount = 0;
|
|
||||||
if (root.pendingConnection.callback) {
|
|
||||||
root.pendingConnection.callback({
|
|
||||||
success: true,
|
|
||||||
output: "Connected",
|
|
||||||
error: "",
|
|
||||||
exitCode: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
root.pendingConnection = null;
|
|
||||||
} else {
|
|
||||||
if (!immediateCheckTimer.running) {
|
|
||||||
immediateCheckTimer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function cidrToSubnetMask(cidr: string): string {
|
|
||||||
const cidrNum = parseInt(cidr, 10);
|
|
||||||
if (isNaN(cidrNum) || cidrNum < 0 || cidrNum > 32) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const mask = (0xffffffff << (32 - cidrNum)) >>> 0;
|
|
||||||
const octet1 = (mask >>> 24) & 0xff;
|
|
||||||
const octet2 = (mask >>> 16) & 0xff;
|
|
||||||
const octet3 = (mask >>> 8) & 0xff;
|
|
||||||
const octet4 = mask & 0xff;
|
|
||||||
|
|
||||||
return `${octet1}.${octet2}.${octet3}.${octet4}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWirelessDeviceDetails(interfaceName: string, callback: var): void {
|
|
||||||
if (!interfaceName || interfaceName.length === 0) {
|
|
||||||
const activeInterface = root.wirelessInterfaces.find(iface => {
|
|
||||||
return isConnectedState(iface.state);
|
|
||||||
});
|
|
||||||
if (activeInterface && activeInterface.device) {
|
|
||||||
interfaceName = activeInterface.device;
|
|
||||||
} else {
|
|
||||||
if (callback)
|
|
||||||
callback(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
executeCommand(["device", "show", interfaceName], result => {
|
|
||||||
if (!result.success || !result.output) {
|
|
||||||
root.wirelessDeviceDetails = null;
|
|
||||||
if (callback)
|
|
||||||
callback(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const details = parseDeviceDetails(result.output, false);
|
|
||||||
root.wirelessDeviceDetails = details;
|
|
||||||
if (callback)
|
|
||||||
callback(details);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getEthernetDeviceDetails(interfaceName: string, callback: var): void {
|
|
||||||
if (!interfaceName || interfaceName.length === 0) {
|
|
||||||
const activeInterface = root.ethernetInterfaces.find(iface => {
|
|
||||||
return isConnectedState(iface.state);
|
|
||||||
});
|
|
||||||
if (activeInterface && activeInterface.device) {
|
|
||||||
interfaceName = activeInterface.device;
|
|
||||||
} else {
|
|
||||||
if (callback)
|
|
||||||
callback(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
executeCommand(["device", "show", interfaceName], result => {
|
|
||||||
if (!result.success || !result.output) {
|
|
||||||
root.ethernetDeviceDetails = null;
|
|
||||||
if (callback)
|
|
||||||
callback(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const details = parseDeviceDetails(result.output, true);
|
|
||||||
root.ethernetDeviceDetails = details;
|
|
||||||
if (callback)
|
|
||||||
callback(details);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseDeviceDetails(output: string, isEthernet: bool): var {
|
|
||||||
const details = {
|
|
||||||
ipAddress: "",
|
|
||||||
gateway: "",
|
|
||||||
dns: [],
|
|
||||||
subnet: "",
|
|
||||||
macAddress: "",
|
|
||||||
speed: ""
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!output || output.length === 0) {
|
|
||||||
return details;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lines = output.trim().split("\n");
|
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
|
||||||
const line = lines[i];
|
|
||||||
const parts = line.split(":");
|
|
||||||
if (parts.length >= 2) {
|
|
||||||
const key = parts[0].trim();
|
|
||||||
const value = parts.slice(1).join(":").trim();
|
|
||||||
|
|
||||||
if (key.startsWith("IP4.ADDRESS")) {
|
|
||||||
const ipParts = value.split("/");
|
|
||||||
details.ipAddress = ipParts[0] || "";
|
|
||||||
if (ipParts[1]) {
|
|
||||||
details.subnet = cidrToSubnetMask(ipParts[1]);
|
|
||||||
} else {
|
|
||||||
details.subnet = "";
|
|
||||||
}
|
|
||||||
} else if (key === "IP4.GATEWAY") {
|
|
||||||
if (value !== "--") {
|
|
||||||
details.gateway = value;
|
|
||||||
}
|
|
||||||
} else if (key.startsWith("IP4.DNS")) {
|
|
||||||
if (value !== "--" && value.length > 0) {
|
|
||||||
details.dns.push(value);
|
|
||||||
}
|
|
||||||
} else if (isEthernet && key === "WIRED-PROPERTIES.MAC") {
|
|
||||||
details.macAddress = value;
|
|
||||||
} else if (isEthernet && key === "WIRED-PROPERTIES.SPEED") {
|
|
||||||
details.speed = value;
|
|
||||||
} else if (!isEthernet && key === "GENERAL.HWADDR") {
|
|
||||||
details.macAddress = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return details;
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: rescanProc
|
id: rescanProc
|
||||||
|
|
||||||
|
|
@ -1295,70 +1277,88 @@ Singleton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshOnConnectionChange(): void {
|
component CommandProcess: Process {
|
||||||
getNetworks(networks => {
|
id: proc
|
||||||
const newActive = root.active;
|
|
||||||
|
property var callback: null
|
||||||
|
property list<string> command: []
|
||||||
|
property bool callbackCalled: false
|
||||||
|
property int exitCode: 0
|
||||||
|
|
||||||
|
signal processFinished
|
||||||
|
|
||||||
|
environment: ({
|
||||||
|
LANG: "C.UTF-8",
|
||||||
|
LC_ALL: "C.UTF-8"
|
||||||
|
})
|
||||||
|
|
||||||
|
stdout: StdioCollector {
|
||||||
|
id: stdoutCollector
|
||||||
|
}
|
||||||
|
|
||||||
|
stderr: StdioCollector {
|
||||||
|
id: stderrCollector
|
||||||
|
|
||||||
|
onStreamFinished: {
|
||||||
|
const error = text.trim();
|
||||||
|
if (error && error.length > 0) {
|
||||||
|
const output = (stdoutCollector && stdoutCollector.text) ? stdoutCollector.text : "";
|
||||||
|
root.handlePasswordRequired(proc, error, output, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onExited: code => { // qmllint disable signal-handler-parameters
|
||||||
|
exitCode = code;
|
||||||
|
|
||||||
if (newActive && newActive.active) {
|
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
if (root.wirelessInterfaces.length > 0) {
|
if (callbackCalled) {
|
||||||
const activeWireless = root.wirelessInterfaces.find(iface => {
|
processFinished();
|
||||||
return isConnectedState(iface.state);
|
return;
|
||||||
});
|
|
||||||
if (activeWireless && activeWireless.device) {
|
|
||||||
getWirelessDeviceDetails(activeWireless.device, () => {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root.ethernetInterfaces.length > 0) {
|
if (proc.callback) {
|
||||||
const activeEthernet = root.ethernetInterfaces.find(iface => {
|
const output = (stdoutCollector && stdoutCollector.text) ? stdoutCollector.text : "";
|
||||||
return isConnectedState(iface.state);
|
const error = (stderrCollector && stderrCollector.text) ? stderrCollector.text : "";
|
||||||
|
const success = exitCode === 0;
|
||||||
|
const cmdIsConnection = isConnectionCommand(proc.command);
|
||||||
|
|
||||||
|
if (root.handlePasswordRequired(proc, error, output, exitCode)) {
|
||||||
|
processFinished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const needsPassword = cmdIsConnection && root.detectPasswordRequired(error);
|
||||||
|
|
||||||
|
if (!success && cmdIsConnection && root.pendingConnection) {
|
||||||
|
const failedSsid = root.pendingConnection.ssid;
|
||||||
|
root.connectionFailed(failedSsid);
|
||||||
|
}
|
||||||
|
|
||||||
|
callbackCalled = true;
|
||||||
|
callback({
|
||||||
|
success: success,
|
||||||
|
output: output,
|
||||||
|
error: error,
|
||||||
|
exitCode: proc.exitCode,
|
||||||
|
needsPassword: needsPassword || false
|
||||||
});
|
});
|
||||||
if (activeEthernet && activeEthernet.device) {
|
processFinished();
|
||||||
getEthernetDeviceDetails(activeEthernet.device, () => {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
} else {
|
} else {
|
||||||
root.wirelessDeviceDetails = null;
|
processFinished();
|
||||||
root.ethernetDeviceDetails = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
getWirelessInterfaces(() => {});
|
|
||||||
getEthernetInterfaces(() => {
|
|
||||||
if (root.activeEthernet && root.activeEthernet.connected) {
|
|
||||||
Qt.callLater(() => {
|
|
||||||
getEthernetDeviceDetails(root.activeEthernet.interface, () => {});
|
|
||||||
}, 500);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
getWifiStatus(() => {});
|
|
||||||
getNetworks(() => {});
|
|
||||||
loadSavedConnections(() => {});
|
|
||||||
getEthernetInterfaces(() => {});
|
|
||||||
|
|
||||||
Qt.callLater(() => {
|
|
||||||
if (root.wirelessInterfaces.length > 0) {
|
|
||||||
const activeWireless = root.wirelessInterfaces.find(iface => {
|
|
||||||
return isConnectedState(iface.state);
|
|
||||||
});
|
|
||||||
if (activeWireless && activeWireless.device) {
|
|
||||||
getWirelessDeviceDetails(activeWireless.device, () => {});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root.ethernetInterfaces.length > 0) {
|
component AccessPoint: QtObject {
|
||||||
const activeEthernet = root.ethernetInterfaces.find(iface => {
|
required property var lastIpcObject
|
||||||
return isConnectedState(iface.state);
|
readonly property string ssid: lastIpcObject.ssid
|
||||||
});
|
readonly property string bssid: lastIpcObject.bssid
|
||||||
if (activeEthernet && activeEthernet.device) {
|
readonly property int strength: lastIpcObject.strength
|
||||||
getEthernetDeviceDetails(activeEthernet.device, () => {});
|
readonly property int frequency: lastIpcObject.frequency
|
||||||
}
|
readonly property bool active: lastIpcObject.active
|
||||||
}
|
readonly property string security: lastIpcObject.security
|
||||||
}, 2000);
|
readonly property bool isSecure: security.length > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue