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
|
||||
enabled: root.enabled
|
||||
|
||||
Binding {
|
||||
target: inputField
|
||||
property: "text"
|
||||
value: root.text
|
||||
when: !inputField.activeFocus
|
||||
}
|
||||
|
||||
onTextChanged: {
|
||||
root.text = text;
|
||||
root.textEdited(text);
|
||||
|
|
@ -76,6 +69,13 @@ Item {
|
|||
onEditingFinished: {
|
||||
root.editingFinished();
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: inputField
|
||||
property: "text"
|
||||
value: root.text
|
||||
when: !inputField.activeFocus
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,21 +15,6 @@ JsonObject {
|
|||
property UseFuzzy useFuzzy: UseFuzzy {}
|
||||
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: [
|
||||
{
|
||||
name: "Calculator",
|
||||
|
|
@ -144,4 +129,19 @@ JsonObject {
|
|||
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 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: [
|
||||
{
|
||||
id: "wifi",
|
||||
|
|
@ -63,4 +38,29 @@ JsonObject {
|
|||
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 {
|
||||
id: pillComp
|
||||
|
||||
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 {
|
||||
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 {}
|
||||
popExit: NoAnim {}
|
||||
|
||||
Component {
|
||||
id: subMenuComp
|
||||
|
||||
SubMenu {}
|
||||
}
|
||||
|
||||
component NoAnim: Transition {
|
||||
NumberAnimation {
|
||||
duration: 0
|
||||
|
|
@ -221,10 +227,4 @@ StackView {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: subMenuComp
|
||||
|
||||
SubMenu {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -267,6 +267,13 @@ ColumnLayout {
|
|||
focus: true
|
||||
activeFocusOnTab: true
|
||||
|
||||
Component.onCompleted: {
|
||||
if (root.shouldBeVisible) {
|
||||
// Use Timer for actual delay to ensure focus works correctly
|
||||
passwordFocusTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: event => {
|
||||
// Ensure we have focus when receiving keyboard input
|
||||
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 {
|
||||
anchors.fill: parent
|
||||
radius: Appearance.rounding.normal
|
||||
|
|
|
|||
|
|
@ -10,17 +10,11 @@ import qs.config
|
|||
Item {
|
||||
id: model
|
||||
|
||||
visible: false
|
||||
|
||||
ListModel {
|
||||
id: _visibleModel
|
||||
}
|
||||
|
||||
property alias visibleModel: _visibleModel
|
||||
|
||||
property string activeLabel: ""
|
||||
|
||||
property int activeIndex: -1
|
||||
property var _xkbMap: ({})
|
||||
property bool _notifiedLimit: false
|
||||
|
||||
function start() {
|
||||
_xkbXmlBase.running = true;
|
||||
|
|
@ -127,14 +121,16 @@ Item {
|
|||
return code.toUpperCase() + " - " + code;
|
||||
}
|
||||
|
||||
visible: false
|
||||
|
||||
ListModel {
|
||||
id: _visibleModel
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: _layoutsModel
|
||||
}
|
||||
|
||||
property var _xkbMap: ({})
|
||||
|
||||
property bool _notifiedLimit: false
|
||||
|
||||
Process {
|
||||
id: _xkbXmlBase
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ CollapsibleSection {
|
|||
radius: Appearance.rounding.normal
|
||||
border.width: isCurrent ? 1 : 0
|
||||
border.color: Colours.palette.m3primary
|
||||
implicitHeight: schemeRow.implicitHeight + Appearance.padding.normal * 2
|
||||
|
||||
StateLayer {
|
||||
function onClicked(): void {
|
||||
|
|
@ -140,8 +141,6 @@ CollapsibleSection {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
implicitHeight: schemeRow.implicitHeight + Appearance.padding.normal * 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ CollapsibleSection {
|
|||
radius: Appearance.rounding.normal
|
||||
border.width: modelData.variant === Schemes.currentVariant ? 1 : 0
|
||||
border.color: Colours.palette.m3primary
|
||||
implicitHeight: variantRow.implicitHeight + Appearance.padding.normal * 2
|
||||
|
||||
StateLayer {
|
||||
function onClicked(): void {
|
||||
|
|
@ -84,8 +85,6 @@ CollapsibleSection {
|
|||
font.pointSize: Appearance.font.size.large
|
||||
}
|
||||
}
|
||||
|
||||
implicitHeight: variantRow.implicitHeight + Appearance.padding.normal * 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ CollapsibleSection {
|
|||
radius: Appearance.rounding.normal
|
||||
border.width: isCurrent ? 1 : 0
|
||||
border.color: Colours.palette.m3primary
|
||||
implicitHeight: fontFamilySansRow.implicitHeight + Appearance.padding.normal * 2
|
||||
|
||||
StateLayer {
|
||||
function onClicked(): void {
|
||||
|
|
@ -93,8 +94,6 @@ CollapsibleSection {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
implicitHeight: fontFamilySansRow.implicitHeight + Appearance.padding.normal * 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -137,6 +136,7 @@ CollapsibleSection {
|
|||
radius: Appearance.rounding.normal
|
||||
border.width: isCurrent ? 1 : 0
|
||||
border.color: Colours.palette.m3primary
|
||||
implicitHeight: fontFamilyMonoRow.implicitHeight + Appearance.padding.normal * 2
|
||||
|
||||
StateLayer {
|
||||
function onClicked(): void {
|
||||
|
|
@ -175,8 +175,6 @@ CollapsibleSection {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
implicitHeight: fontFamilyMonoRow.implicitHeight + Appearance.padding.normal * 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -221,6 +219,7 @@ CollapsibleSection {
|
|||
radius: Appearance.rounding.normal
|
||||
border.width: isCurrent ? 1 : 0
|
||||
border.color: Colours.palette.m3primary
|
||||
implicitHeight: fontFamilyMaterialRow.implicitHeight + Appearance.padding.normal * 2
|
||||
|
||||
StateLayer {
|
||||
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"
|
||||
radius: Appearance.rounding.normal
|
||||
implicitHeight: outputRowLayout.implicitHeight + Appearance.padding.normal * 2
|
||||
|
||||
StateLayer {
|
||||
function onClicked(): void {
|
||||
|
|
@ -126,8 +127,6 @@ Item {
|
|||
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"
|
||||
radius: Appearance.rounding.normal
|
||||
implicitHeight: inputRowLayout.implicitHeight + Appearance.padding.normal * 2
|
||||
|
||||
StateLayer {
|
||||
function onClicked(): void {
|
||||
|
|
@ -204,8 +204,6 @@ Item {
|
|||
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();
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onVolumeChanged() {
|
||||
if (!outputVolumeInput.hasFocus) {
|
||||
outputVolumeInput.text = Math.round(Audio.volume * 100).toString();
|
||||
}
|
||||
}
|
||||
|
||||
target: Audio
|
||||
}
|
||||
|
||||
onTextEdited: text => {
|
||||
if (hasFocus) {
|
||||
const val = parseInt(text);
|
||||
|
|
@ -303,6 +291,16 @@ Item {
|
|||
text = Math.round(Audio.volume * 100).toString();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onVolumeChanged() {
|
||||
if (!outputVolumeInput.hasFocus) {
|
||||
outputVolumeInput.text = Math.round(Audio.volume * 100).toString();
|
||||
}
|
||||
}
|
||||
|
||||
target: Audio
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
|
|
@ -396,16 +394,6 @@ Item {
|
|||
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 => {
|
||||
if (hasFocus) {
|
||||
const val = parseInt(text);
|
||||
|
|
@ -421,6 +409,16 @@ Item {
|
|||
text = Math.round(Audio.sourceVolume * 100).toString();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onSourceVolumeChanged() {
|
||||
if (!inputVolumeInput.hasFocus) {
|
||||
inputVolumeInput.text = Math.round(Audio.sourceVolume * 100).toString();
|
||||
}
|
||||
}
|
||||
|
||||
target: Audio
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
|
|
@ -530,16 +528,6 @@ Item {
|
|||
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 => {
|
||||
if (hasFocus) {
|
||||
const val = parseInt(text);
|
||||
|
|
@ -555,6 +543,16 @@ Item {
|
|||
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 {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ ColumnLayout {
|
|||
property Component headerComponent: null
|
||||
property Component titleSuffix: null
|
||||
property bool showHeader: true
|
||||
property alias view: view
|
||||
|
||||
signal itemSelected(var item)
|
||||
|
||||
|
|
@ -61,8 +62,6 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
property alias view: view
|
||||
|
||||
StyledText {
|
||||
visible: root.description !== ""
|
||||
Layout.fillWidth: true
|
||||
|
|
|
|||
|
|
@ -152,14 +152,6 @@ ColumnLayout {
|
|||
to: root.to
|
||||
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: {
|
||||
// Update input field text in real-time as slider moves during dragging
|
||||
// Always update when slider value changes (during dragging or external updates)
|
||||
|
|
@ -176,5 +168,13 @@ ColumnLayout {
|
|||
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;
|
||||
}
|
||||
|
||||
onPaneChanged: {
|
||||
nextComponent = getComponentForPane();
|
||||
paneId = root.paneIdGenerator(pane);
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: rightLoader
|
||||
|
||||
|
|
@ -74,11 +79,6 @@ Item {
|
|||
]
|
||||
}
|
||||
}
|
||||
|
||||
onPaneChanged: {
|
||||
nextComponent = getComponentForPane();
|
||||
paneId = root.paneIdGenerator(pane);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,16 +154,16 @@ GridView {
|
|||
|
||||
opacity: 0
|
||||
|
||||
Component.onCompleted: {
|
||||
opacity = 1;
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 1000
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
opacity = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -219,16 +219,16 @@ GridView {
|
|||
|
||||
opacity: 0
|
||||
|
||||
Component.onCompleted: {
|
||||
opacity = 1;
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 1000
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
opacity = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -317,6 +317,10 @@ Item {
|
|||
|
||||
opacity: 0
|
||||
|
||||
Component.onCompleted: {
|
||||
opacity = 1;
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 1000
|
||||
|
|
@ -324,10 +328,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
opacity = 1;
|
||||
}
|
||||
|
||||
StateLayer {
|
||||
function onClicked(): void {
|
||||
root.session.launcher.active = modelData;
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ ColumnLayout {
|
|||
required property int index
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
width: ListView.view ? ListView.view.width : undefined
|
||||
implicitHeight: 60
|
||||
color: Colours.tPalette.m3surfaceContainerHigh
|
||||
radius: Appearance.rounding.normal
|
||||
|
||||
|
|
@ -147,8 +148,6 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
implicitHeight: 60
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ DeviceList {
|
|||
required property var modelData
|
||||
|
||||
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)
|
||||
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
|
||||
opacity: root.session.network.showPasswordDialog && !root.isClosing ? 1 : 0
|
||||
scale: root.session.network.showPasswordDialog && !root.isClosing ? 1 : 0.7
|
||||
Keys.onEscapePressed: closeDialog()
|
||||
|
||||
Behavior on opacity {
|
||||
Anim {}
|
||||
|
|
@ -135,8 +136,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Keys.onEscapePressed: closeDialog()
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
|
||||
|
|
|
|||
|
|
@ -38,96 +38,6 @@ Singleton {
|
|||
"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() {
|
||||
if (!player || !player.metadata)
|
||||
return null;
|
||||
|
|
@ -345,4 +255,95 @@ Singleton {
|
|||
|
||||
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 {
|
||||
required property var lastIpcObject
|
||||
readonly property string ssid: lastIpcObject.ssid
|
||||
|
|
@ -323,10 +329,4 @@ Singleton {
|
|||
readonly property string security: lastIpcObject.security
|
||||
readonly property bool isSecure: security.length > 0
|
||||
}
|
||||
|
||||
Component {
|
||||
id: apComp
|
||||
|
||||
AccessPoint {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -872,78 +872,222 @@ Singleton {
|
|||
return false;
|
||||
}
|
||||
|
||||
component CommandProcess: Process {
|
||||
id: proc
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
function cidrToSubnetMask(cidr: string): string {
|
||||
const cidrNum = parseInt(cidr, 10);
|
||||
if (isNaN(cidrNum) || cidrNum < 0 || cidrNum > 32) {
|
||||
return "";
|
||||
}
|
||||
|
||||
stderr: StdioCollector {
|
||||
id: stderrCollector
|
||||
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;
|
||||
|
||||
onStreamFinished: {
|
||||
const error = text.trim();
|
||||
if (error && error.length > 0) {
|
||||
const output = (stdoutCollector && stdoutCollector.text) ? stdoutCollector.text : "";
|
||||
root.handlePasswordRequired(proc, error, output, -1);
|
||||
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
|
||||
exitCode = code;
|
||||
return details;
|
||||
}
|
||||
|
||||
Qt.callLater(() => {
|
||||
if (callbackCalled) {
|
||||
processFinished();
|
||||
return;
|
||||
}
|
||||
function refreshOnConnectionChange(): void {
|
||||
getNetworks(networks => {
|
||||
const newActive = root.active;
|
||||
|
||||
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;
|
||||
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, () => {});
|
||||
}
|
||||
}
|
||||
|
||||
const needsPassword = cmdIsConnection && root.detectPasswordRequired(error);
|
||||
|
||||
if (!success && cmdIsConnection && root.pendingConnection) {
|
||||
const failedSsid = root.pendingConnection.ssid;
|
||||
root.connectionFailed(failedSsid);
|
||||
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;
|
||||
}
|
||||
|
||||
callbackCalled = true;
|
||||
callback({
|
||||
success: success,
|
||||
output: output,
|
||||
error: error,
|
||||
exitCode: proc.exitCode,
|
||||
needsPassword: needsPassword || false
|
||||
});
|
||||
processFinished();
|
||||
} else {
|
||||
processFinished();
|
||||
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) {
|
||||
const activeEthernet = root.ethernetInterfaces.find(iface => {
|
||||
return isConnectedState(iface.state);
|
||||
});
|
||||
if (activeEthernet && activeEthernet.device) {
|
||||
getEthernetDeviceDetails(activeEthernet.device, () => {});
|
||||
}
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
Component {
|
||||
|
|
@ -952,17 +1096,6 @@ Singleton {
|
|||
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 {
|
||||
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 {
|
||||
id: rescanProc
|
||||
|
||||
|
|
@ -1295,70 +1277,88 @@ Singleton {
|
|||
}
|
||||
}
|
||||
|
||||
function refreshOnConnectionChange(): void {
|
||||
getNetworks(networks => {
|
||||
const newActive = root.active;
|
||||
component CommandProcess: Process {
|
||||
id: proc
|
||||
|
||||
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, () => {});
|
||||
}
|
||||
}
|
||||
property var callback: null
|
||||
property list<string> command: []
|
||||
property bool callbackCalled: false
|
||||
property int exitCode: 0
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getWirelessInterfaces(() => {});
|
||||
getEthernetInterfaces(() => {
|
||||
if (root.activeEthernet && root.activeEthernet.connected) {
|
||||
Qt.callLater(() => {
|
||||
getEthernetDeviceDetails(root.activeEthernet.interface, () => {});
|
||||
}, 500);
|
||||
onExited: code => { // qmllint disable signal-handler-parameters
|
||||
exitCode = code;
|
||||
|
||||
Qt.callLater(() => {
|
||||
if (callbackCalled) {
|
||||
processFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
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();
|
||||
} else {
|
||||
processFinished();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
const activeEthernet = root.ethernetInterfaces.find(iface => {
|
||||
return isConnectedState(iface.state);
|
||||
});
|
||||
if (activeEthernet && activeEthernet.device) {
|
||||
getEthernetDeviceDetails(activeEthernet.device, () => {});
|
||||
}
|
||||
}
|
||||
}, 2000);
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue