refactor: Updated Bluetooth, Ethernet, and Wireless lists to use DeviceList component and improved layout structure

This commit is contained in:
ATMDA 2025-11-19 19:51:28 -05:00
parent 2d26626643
commit ff4e9bbdfd
6 changed files with 454 additions and 334 deletions

View file

@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
import ".." import ".."
import "../components" import "../components"
import "."
import qs.components import qs.components
import qs.components.controls import qs.components.controls
import qs.components.containers import qs.components.containers

View file

@ -1,6 +1,7 @@
pragma ComponentBehavior: Bound pragma ComponentBehavior: Bound
import ".." import ".."
import "../components"
import qs.components import qs.components
import qs.components.controls import qs.components.controls
import qs.components.containers import qs.components.containers
@ -12,165 +13,144 @@ import Quickshell.Bluetooth
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
ColumnLayout { DeviceList {
id: root id: root
required property Session session required property Session session
readonly property bool smallDiscoverable: width <= 540 readonly property bool smallDiscoverable: width <= 540
readonly property bool smallPairable: width <= 480 readonly property bool smallPairable: width <= 480
spacing: Appearance.spacing.small title: qsTr("Devices (%1)").arg(Bluetooth.devices.values.length)
description: qsTr("All available bluetooth devices")
activeItem: session.bt.active
RowLayout { model: ScriptModel {
spacing: Appearance.spacing.smaller id: deviceModel
StyledText { values: [...Bluetooth.devices.values].sort((a, b) => (b.connected - a.connected) || (b.paired - a.paired))
text: qsTr("Bluetooth")
font.pointSize: Appearance.font.size.large
font.weight: 500
}
Item {
Layout.fillWidth: true
}
ToggleButton {
toggled: Bluetooth.defaultAdapter?.enabled ?? false
icon: "power"
accent: "Tertiary"
function onClicked(): void {
const adapter = Bluetooth.defaultAdapter;
if (adapter)
adapter.enabled = !adapter.enabled;
}
}
ToggleButton {
toggled: Bluetooth.defaultAdapter?.discoverable ?? false
icon: root.smallDiscoverable ? "group_search" : ""
label: root.smallDiscoverable ? "" : qsTr("Discoverable")
function onClicked(): void {
const adapter = Bluetooth.defaultAdapter;
if (adapter)
adapter.discoverable = !adapter.discoverable;
}
}
ToggleButton {
toggled: Bluetooth.defaultAdapter?.pairable ?? false
icon: "missing_controller"
label: root.smallPairable ? "" : qsTr("Pairable")
function onClicked(): void {
const adapter = Bluetooth.defaultAdapter;
if (adapter)
adapter.pairable = !adapter.pairable;
}
}
ToggleButton {
toggled: !root.session.bt.active
icon: "settings"
accent: "Primary"
function onClicked(): void {
if (root.session.bt.active)
root.session.bt.active = null;
else {
root.session.bt.active = deviceModel.values[0] ?? null;
}
}
}
} }
RowLayout { headerComponent: Component {
Layout.topMargin: Appearance.spacing.large RowLayout {
Layout.fillWidth: true spacing: Appearance.spacing.smaller
spacing: Appearance.spacing.normal
ColumnLayout {
Layout.fillWidth: true
spacing: Appearance.spacing.small
StyledText { StyledText {
Layout.fillWidth: true text: qsTr("Bluetooth")
text: qsTr("Devices (%1)").arg(Bluetooth.devices.values.length) font.pointSize: Appearance.font.size.large
font.pointSize: Appearance.font.size.normal
font.weight: 500 font.weight: 500
} }
StyledText { Item {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("All available bluetooth devices")
color: Colours.palette.m3outline
} }
}
StyledRect { ToggleButton {
implicitWidth: implicitHeight toggled: Bluetooth.defaultAdapter?.enabled ?? false
implicitHeight: scanIcon.implicitHeight + Appearance.padding.normal * 2 icon: "power"
accent: "Tertiary"
radius: Bluetooth.defaultAdapter?.discovering ? Appearance.rounding.normal : implicitHeight / 2 * Math.min(1, Appearance.rounding.scale)
color: Bluetooth.defaultAdapter?.discovering ? Colours.palette.m3secondary : Colours.palette.m3secondaryContainer
StateLayer {
color: Bluetooth.defaultAdapter?.discovering ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer
function onClicked(): void { function onClicked(): void {
const adapter = Bluetooth.defaultAdapter; const adapter = Bluetooth.defaultAdapter;
if (adapter) if (adapter)
adapter.discovering = !adapter.discovering; adapter.enabled = !adapter.enabled;
} }
} }
MaterialIcon { ToggleButton {
id: scanIcon toggled: Bluetooth.defaultAdapter?.discoverable ?? false
icon: root.smallDiscoverable ? "group_search" : ""
label: root.smallDiscoverable ? "" : qsTr("Discoverable")
anchors.centerIn: parent function onClicked(): void {
animate: true const adapter = Bluetooth.defaultAdapter;
text: "bluetooth_searching" if (adapter)
color: Bluetooth.defaultAdapter?.discovering ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer adapter.discoverable = !adapter.discoverable;
fill: Bluetooth.defaultAdapter?.discovering ? 1 : 0 }
} }
Behavior on radius { ToggleButton {
Anim {} toggled: Bluetooth.defaultAdapter?.pairable ?? false
icon: "missing_controller"
label: root.smallPairable ? "" : qsTr("Pairable")
function onClicked(): void {
const adapter = Bluetooth.defaultAdapter;
if (adapter)
adapter.pairable = !adapter.pairable;
}
}
ToggleButton {
toggled: !root.session.bt.active
icon: "settings"
accent: "Primary"
function onClicked(): void {
if (root.session.bt.active)
root.session.bt.active = null;
else {
root.session.bt.active = root.model.values[0] ?? null;
}
}
} }
} }
} }
StyledListView { titleSuffix: Component {
id: view RowLayout {
spacing: Appearance.spacing.normal
model: ScriptModel { Item {
id: deviceModel Layout.fillWidth: true
}
values: [...Bluetooth.devices.values].sort((a, b) => (b.connected - a.connected) || (b.paired - a.paired)) StyledRect {
implicitWidth: implicitHeight
implicitHeight: scanIcon.implicitHeight + Appearance.padding.normal * 2
radius: Bluetooth.defaultAdapter?.discovering ? Appearance.rounding.normal : implicitHeight / 2 * Math.min(1, Appearance.rounding.scale)
color: Bluetooth.defaultAdapter?.discovering ? Colours.palette.m3secondary : Colours.palette.m3secondaryContainer
StateLayer {
color: Bluetooth.defaultAdapter?.discovering ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer
function onClicked(): void {
const adapter = Bluetooth.defaultAdapter;
if (adapter)
adapter.discovering = !adapter.discovering;
}
}
MaterialIcon {
id: scanIcon
anchors.centerIn: parent
animate: true
text: "bluetooth_searching"
color: Bluetooth.defaultAdapter?.discovering ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer
fill: Bluetooth.defaultAdapter?.discovering ? 1 : 0
}
Behavior on radius {
Anim {}
}
}
} }
}
Layout.fillWidth: true delegate: Component {
Layout.fillHeight: true StyledRect {
clip: true
spacing: Appearance.spacing.small / 2
StyledScrollBar.vertical: StyledScrollBar {
flickable: view
}
delegate: StyledRect {
id: device id: device
required property BluetoothDevice modelData required property BluetoothDevice modelData
readonly property bool loading: modelData && (modelData.state === BluetoothDeviceState.Connecting || modelData.state === BluetoothDeviceState.Disconnecting) readonly property bool loading: modelData && (modelData.state === BluetoothDeviceState.Connecting || modelData.state === BluetoothDeviceState.Disconnecting)
readonly property bool connected: modelData && modelData.state === BluetoothDeviceState.Connected readonly property bool connected: modelData && modelData.state === BluetoothDeviceState.Connected
anchors.left: view.contentItem.left anchors.left: parent.left
anchors.right: view.contentItem.right anchors.right: parent.right
implicitHeight: deviceInner.implicitHeight + Appearance.padding.normal * 2 implicitHeight: deviceInner.implicitHeight + Appearance.padding.normal * 2
color: Qt.alpha(Colours.tPalette.m3surfaceContainer, root.session.bt.active === 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
StateLayer { StateLayer {
@ -257,8 +237,18 @@ ColumnLayout {
disabled: device.loading disabled: device.loading
function onClicked(): void { function onClicked(): void {
if (device.modelData) if (device.loading)
device.modelData.connected = !device.modelData.connected; return;
if (device.connected) {
device.modelData.connected = false;
} else {
if (device.modelData.bonded) {
device.modelData.connected = true;
} else {
device.modelData.pair();
}
}
} }
} }
@ -267,7 +257,7 @@ ColumnLayout {
anchors.centerIn: parent anchors.centerIn: parent
animate: true animate: true
text: (device.modelData && device.modelData.connected) ? "link_off" : "link" text: device.connected ? "link_off" : "link"
color: device.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface color: device.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface
opacity: device.loading ? 0 : 1 opacity: device.loading ? 0 : 1
@ -281,78 +271,7 @@ ColumnLayout {
} }
} }
component ToggleButton: StyledRect { onItemSelected: function(item) {
id: toggleBtn session.bt.active = item;
required property bool toggled
property string icon
property string label
property string accent: "Secondary"
function onClicked(): void {
}
Layout.preferredWidth: implicitWidth + (toggleStateLayer.pressed ? Appearance.padding.normal * 2 : toggled ? Appearance.padding.small * 2 : 0)
implicitWidth: toggleBtnInner.implicitWidth + Appearance.padding.large * 2
implicitHeight: toggleBtnIcon.implicitHeight + Appearance.padding.normal * 2
radius: toggled || toggleStateLayer.pressed ? Appearance.rounding.small : Math.min(width, height) / 2 * Math.min(1, Appearance.rounding.scale)
color: toggled ? Colours.palette[`m3${accent.toLowerCase()}`] : Colours.palette[`m3${accent.toLowerCase()}Container`]
StateLayer {
id: toggleStateLayer
color: toggleBtn.toggled ? Colours.palette[`m3on${toggleBtn.accent}`] : Colours.palette[`m3on${toggleBtn.accent}Container`]
function onClicked(): void {
toggleBtn.onClicked();
}
}
RowLayout {
id: toggleBtnInner
anchors.centerIn: parent
spacing: Appearance.spacing.normal
MaterialIcon {
id: toggleBtnIcon
visible: !!text
fill: toggleBtn.toggled ? 1 : 0
text: toggleBtn.icon
color: toggleBtn.toggled ? Colours.palette[`m3on${toggleBtn.accent}`] : Colours.palette[`m3on${toggleBtn.accent}Container`]
font.pointSize: Appearance.font.size.large
Behavior on fill {
Anim {}
}
}
Loader {
asynchronous: true
active: !!toggleBtn.label
visible: active
sourceComponent: StyledText {
text: toggleBtn.label
color: toggleBtn.toggled ? Colours.palette[`m3on${toggleBtn.accent}`] : Colours.palette[`m3on${toggleBtn.accent}Container`]
}
}
}
Behavior on radius {
Anim {
duration: Appearance.anim.durations.expressiveFastSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
}
}
Behavior on Layout.preferredWidth {
Anim {
duration: Appearance.anim.durations.expressiveFastSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
}
}
} }
} }

View file

@ -0,0 +1,108 @@
pragma ComponentBehavior: Bound
import ".."
import qs.components
import qs.components.controls
import qs.components.effects
import qs.components.containers
import qs.config
import QtQuick
import QtQuick.Layouts
/**
* DeviceDetails
*
* A reusable base component for displaying device/network details with a standardized
* structure. Provides a header, connection status section, and flexible sections for
* device-specific information.
*
* This component eliminates duplication across WirelessDetails, EthernetDetails, and Bluetooth Details
* by providing a common structure while allowing full customization of sections.
*
* Usage:
* ```qml
* DeviceDetails {
* session: root.session
* device: session.network.active
* headerComponent: Component {
* ConnectionHeader {
* icon: "wifi"
* title: device?.ssid ?? ""
* }
* }
* sections: [
* Component {
* // Connection status section
* },
* Component {
* // Properties section
* }
* ]
* }
* ```
*/
Item {
id: root
required property Session session
property var device: null
property Component headerComponent: null
property list<Component> sections: []
// Optional: Custom content to insert after header but before sections
property Component topContent: null
// Optional: Custom content to insert after all sections
property Component bottomContent: null
implicitWidth: layout.implicitWidth
implicitHeight: layout.implicitHeight
ColumnLayout {
id: layout
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
spacing: Appearance.spacing.normal
// Header component (e.g., ConnectionHeader or SettingsHeader)
Loader {
id: headerLoader
Layout.fillWidth: true
sourceComponent: root.headerComponent
visible: root.headerComponent !== null
}
// Top content (optional)
Loader {
id: topContentLoader
Layout.fillWidth: true
sourceComponent: root.topContent
visible: root.topContent !== null
}
// Sections
Repeater {
model: root.sections
Loader {
Layout.fillWidth: true
sourceComponent: modelData
}
}
// Bottom content (optional)
Loader {
id: bottomContentLoader
Layout.fillWidth: true
sourceComponent: root.bottomContent
visible: root.bottomContent !== null
}
}
}

View file

@ -0,0 +1,125 @@
pragma ComponentBehavior: Bound
import ".."
import qs.components
import qs.components.controls
import qs.components.containers
import qs.services
import qs.config
import QtQuick
import QtQuick.Layouts
/**
* DeviceList
*
* A reusable base component for displaying lists of devices/networks with a standardized
* structure. Provides a header with action buttons, title/subtitle, and a scrollable list
* with customizable delegates.
*
* This component eliminates duplication across WirelessList, EthernetList, and Bluetooth DeviceList
* by providing a common structure while allowing full customization of headers and delegates.
*
* Usage:
* ```qml
* DeviceList {
* session: root.session
* title: qsTr("Networks (%1)").arg(Nmcli.networks.length)
* description: qsTr("All available WiFi networks")
* model: ScriptModel {
* values: [...Nmcli.networks].sort(...)
* }
* activeItem: session.network.active
* onItemSelected: (item) => {
* session.network.active = item;
* }
* headerComponent: Component {
* RowLayout {
* // Custom header buttons
* }
* }
* delegate: Component {
* // Custom delegate for each item
* }
* }
* ```
*/
ColumnLayout {
id: root
property Session session: null
property var model: null
property Component delegate: null
property string title: ""
property string description: ""
property var activeItem: null
property Component headerComponent: null
property Component titleSuffix: null
signal itemSelected(var item)
spacing: Appearance.spacing.small
// Header with action buttons (optional)
Loader {
id: headerLoader
Layout.fillWidth: true
sourceComponent: root.headerComponent
visible: root.headerComponent !== null
}
// Title and description row
RowLayout {
Layout.fillWidth: true
Layout.topMargin: root.headerComponent ? 0 : 0
spacing: Appearance.spacing.small
visible: root.title !== "" || root.description !== ""
StyledText {
visible: root.title !== ""
text: root.title
font.pointSize: Appearance.font.size.large
font.weight: 500
}
Loader {
sourceComponent: root.titleSuffix
visible: root.titleSuffix !== null
}
Item {
Layout.fillWidth: true
}
}
// Expose view for access from parent components
property alias view: view
// Description text
StyledText {
visible: root.description !== ""
Layout.fillWidth: true
text: root.description
color: Colours.palette.m3outline
}
// List view
StyledListView {
id: view
Layout.fillWidth: true
Layout.fillHeight: true
model: root.model
delegate: root.delegate
spacing: Appearance.spacing.small / 2
clip: true
StyledScrollBar.vertical: StyledScrollBar {
flickable: view
}
}
}

View file

@ -1,6 +1,7 @@
pragma ComponentBehavior: Bound pragma ComponentBehavior: Bound
import ".." import ".."
import "../components"
import qs.components import qs.components
import qs.components.controls import qs.components.controls
import qs.components.containers import qs.components.containers
@ -9,81 +10,57 @@ import qs.config
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
ColumnLayout { DeviceList {
id: root id: root
required property Session session required property Session session
spacing: Appearance.spacing.small title: qsTr("Devices (%1)").arg(Nmcli.ethernetDevices.length)
description: qsTr("All available ethernet devices")
activeItem: session.ethernet.active
RowLayout { model: Nmcli.ethernetDevices
spacing: Appearance.spacing.smaller
StyledText { headerComponent: Component {
text: qsTr("Settings") RowLayout {
font.pointSize: Appearance.font.size.large spacing: Appearance.spacing.smaller
font.weight: 500
}
Item { StyledText {
Layout.fillWidth: true text: qsTr("Settings")
} font.pointSize: Appearance.font.size.large
font.weight: 500
}
ToggleButton { Item {
toggled: !root.session.ethernet.active Layout.fillWidth: true
icon: "settings" }
accent: "Primary"
onClicked: { ToggleButton {
if (root.session.ethernet.active) toggled: !root.session.ethernet.active
root.session.ethernet.active = null; icon: "settings"
else { accent: "Primary"
root.session.ethernet.active = view.model.get(0)?.modelData ?? null;
onClicked: {
if (root.session.ethernet.active)
root.session.ethernet.active = null;
else {
root.session.ethernet.active = root.view.model.get(0)?.modelData ?? null;
}
} }
} }
} }
} }
RowLayout { delegate: Component {
Layout.fillWidth: true StyledRect {
spacing: Appearance.spacing.small
StyledText {
text: qsTr("Devices (%1)").arg(Nmcli.ethernetDevices.length)
font.pointSize: Appearance.font.size.large
font.weight: 500
}
}
StyledText {
text: qsTr("All available ethernet devices")
color: Colours.palette.m3outline
}
StyledListView {
id: view
Layout.fillWidth: true
Layout.fillHeight: true
model: Nmcli.ethernetDevices
spacing: Appearance.spacing.small / 2
clip: true
StyledScrollBar.vertical: StyledScrollBar {
flickable: view
}
delegate: StyledRect {
required property var modelData required property var modelData
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
color: Qt.alpha(Colours.tPalette.m3surfaceContainer, root.session.ethernet.active === 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
border.width: root.session.ethernet.active === modelData ? 1 : 0 border.width: root.activeItem === modelData ? 1 : 0
border.color: Colours.palette.m3primary border.color: Colours.palette.m3primary
StateLayer { StateLayer {
@ -165,4 +142,8 @@ ColumnLayout {
implicitHeight: rowLayout.implicitHeight + Appearance.padding.normal * 2 implicitHeight: rowLayout.implicitHeight + Appearance.padding.normal * 2
} }
} }
}
onItemSelected: function(item) {
session.ethernet.active = item;
}
}

View file

@ -1,6 +1,7 @@
pragma ComponentBehavior: Bound pragma ComponentBehavior: Bound
import ".." import ".."
import "../components"
import "." import "."
import qs.components import qs.components
import qs.components.controls import qs.components.controls
@ -11,71 +12,16 @@ import qs.utils
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
ColumnLayout { DeviceList {
id: root id: root
required property Session session required property Session session
spacing: Appearance.spacing.small title: qsTr("Networks (%1)").arg(Nmcli.networks.length)
description: qsTr("All available WiFi networks")
RowLayout { activeItem: session.network.active
spacing: Appearance.spacing.smaller
titleSuffix: Component {
StyledText {
text: qsTr("Settings")
font.pointSize: Appearance.font.size.large
font.weight: 500
}
Item {
Layout.fillWidth: true
}
ToggleButton {
toggled: Nmcli.wifiEnabled
icon: "wifi"
accent: "Tertiary"
onClicked: {
Nmcli.toggleWifi(null);
}
}
ToggleButton {
toggled: Nmcli.scanning
icon: "wifi_find"
accent: "Secondary"
onClicked: {
Nmcli.rescanWifi();
}
}
ToggleButton {
toggled: !root.session.network.active
icon: "settings"
accent: "Primary"
onClicked: {
if (root.session.network.active)
root.session.network.active = null;
else {
root.session.network.active = view.model.get(0)?.modelData ?? null;
}
}
}
}
RowLayout {
Layout.fillWidth: true
spacing: Appearance.spacing.small
StyledText {
text: qsTr("Networks (%1)").arg(Nmcli.networks.length)
font.pointSize: Appearance.font.size.large
font.weight: 500
}
StyledText { StyledText {
visible: Nmcli.scanning visible: Nmcli.scanning
text: qsTr("Scanning...") text: qsTr("Scanning...")
@ -84,43 +30,76 @@ ColumnLayout {
} }
} }
StyledText { model: ScriptModel {
text: qsTr("All available WiFi networks") values: [...Nmcli.networks].sort((a, b) => {
color: Colours.palette.m3outline // Put active/connected network first
if (a.active !== b.active)
return b.active - a.active;
// Then sort by signal strength
return b.strength - a.strength;
})
} }
StyledListView { headerComponent: Component {
id: view RowLayout {
spacing: Appearance.spacing.smaller
Layout.fillWidth: true StyledText {
Layout.fillHeight: true text: qsTr("Settings")
font.pointSize: Appearance.font.size.large
font.weight: 500
}
model: ScriptModel { Item {
values: [...Nmcli.networks].sort((a, b) => { Layout.fillWidth: true
// Put active/connected network first }
if (a.active !== b.active)
return b.active - a.active; ToggleButton {
// Then sort by signal strength toggled: Nmcli.wifiEnabled
return b.strength - a.strength; icon: "wifi"
}) accent: "Tertiary"
onClicked: {
Nmcli.toggleWifi(null);
}
}
ToggleButton {
toggled: Nmcli.scanning
icon: "wifi_find"
accent: "Secondary"
onClicked: {
Nmcli.rescanWifi();
}
}
ToggleButton {
toggled: !root.session.network.active
icon: "settings"
accent: "Primary"
onClicked: {
if (root.session.network.active)
root.session.network.active = null;
else {
root.session.network.active = root.view.model.get(0)?.modelData ?? null;
}
}
}
} }
}
spacing: Appearance.spacing.small / 2 delegate: Component {
clip: true StyledRect {
StyledScrollBar.vertical: StyledScrollBar {
flickable: view
}
delegate: StyledRect {
required property var modelData required property var modelData
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
color: Qt.alpha(Colours.tPalette.m3surfaceContainer, root.session.network.active === 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
border.width: root.session.network.active === modelData ? 1 : 0 border.width: root.activeItem === modelData ? 1 : 0
border.color: Colours.palette.m3primary border.color: Colours.palette.m3primary
StateLayer { StateLayer {
@ -213,9 +192,16 @@ ColumnLayout {
} }
} }
onItemSelected: function(item) {
session.network.active = item;
if (item && item.ssid) {
checkSavedProfileForNetwork(item.ssid);
}
}
function checkSavedProfileForNetwork(ssid: string): void { function checkSavedProfileForNetwork(ssid: string): void {
if (ssid && ssid.length > 0) { if (ssid && ssid.length > 0) {
Nmcli.loadSavedConnections(() => {}); Nmcli.loadSavedConnections(() => {});
} }
} }
} }