Switched to qmlformat.

This commit is contained in:
ItsLemmy
2025-11-16 17:07:03 -05:00
parent 32905224b9
commit 3ff5b7639f
223 changed files with 9970 additions and 9658 deletions
+94 -95
View File
@@ -21,30 +21,30 @@ Singleton {
readonly property var devices: adapter ? adapter.devices : null
readonly property var pairedDevices: {
if (!adapter || !adapter.devices) {
return []
return [];
}
return adapter.devices.values.filter(dev => {
return dev && (dev.paired || dev.trusted)
})
return dev && (dev.paired || dev.trusted);
});
}
readonly property var connectedDevices: {
if (!adapter || !adapter.devices) {
return []
return [];
}
return adapter.devices.values.filter(dev => dev && dev.connected)
return adapter.devices.values.filter(dev => dev && dev.connected);
}
readonly property var allDevicesWithBattery: {
if (!adapter || !adapter.devices) {
return []
return [];
}
return adapter.devices.values.filter(dev => {
return dev && dev.batteryAvailable && dev.battery > 0
})
return dev && dev.batteryAvailable && dev.battery > 0;
});
}
function init() {
Logger.i("Bluetooth", "Service started")
Logger.i("Bluetooth", "Service started");
}
Timer {
@@ -58,198 +58,197 @@ Singleton {
target: adapter
function onStateChanged() {
if (!adapter) {
Logger.w("Bluetooth", "onStateChanged", "No adapter available")
return
Logger.w("Bluetooth", "onStateChanged", "No adapter available");
return;
}
if (adapter.state === BluetoothAdapterState.Enabling || adapter.state === BluetoothAdapterState.Disabling) {
return
return;
}
Logger.d("Bluetooth", "onStateChanged", adapter.state)
const bluetoothBlockedToggled = (root.blocked !== lastBluetoothBlocked)
root.lastBluetoothBlocked = root.blocked
Logger.d("Bluetooth", "onStateChanged", adapter.state);
const bluetoothBlockedToggled = (root.blocked !== lastBluetoothBlocked);
root.lastBluetoothBlocked = root.blocked;
if (bluetoothBlockedToggled) {
checkWifiBlocked.running = true
checkWifiBlocked.running = true;
} else if (adapter.enabled) {
ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.enabled"), "bluetooth")
discoveryTimer.running = true
ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.enabled"), "bluetooth");
discoveryTimer.running = true;
} else {
ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.disabled"), "bluetooth-off")
ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.disabled"), "bluetooth-off");
}
}
}
function sortDevices(devices) {
return devices.sort((a, b) => {
var aName = a.name || a.deviceName || ""
var bName = b.name || b.deviceName || ""
var aName = a.name || a.deviceName || "";
var bName = b.name || b.deviceName || "";
var aHasRealName = aName.includes(" ") && aName.length > 3
var bHasRealName = bName.includes(" ") && bName.length > 3
var aHasRealName = aName.includes(" ") && aName.length > 3;
var bHasRealName = bName.includes(" ") && bName.length > 3;
if (aHasRealName && !bHasRealName)
return -1
return -1;
if (!aHasRealName && bHasRealName)
return 1
return 1;
var aSignal = (a.signalStrength !== undefined && a.signalStrength > 0) ? a.signalStrength : 0
var bSignal = (b.signalStrength !== undefined && b.signalStrength > 0) ? b.signalStrength : 0
return bSignal - aSignal
})
var aSignal = (a.signalStrength !== undefined && a.signalStrength > 0) ? a.signalStrength : 0;
var bSignal = (b.signalStrength !== undefined && b.signalStrength > 0) ? b.signalStrength : 0;
return bSignal - aSignal;
});
}
function getDeviceIcon(device) {
if (!device) {
return "bt-device-generic"
return "bt-device-generic";
}
var name = (device.name || device.deviceName || "").toLowerCase()
var icon = (device.icon || "").toLowerCase()
var name = (device.name || device.deviceName || "").toLowerCase();
var icon = (device.icon || "").toLowerCase();
if (icon.includes("headset") || icon.includes("audio") || name.includes("headphone") || name.includes("airpod") || name.includes("headset") || name.includes("arctis")) {
return "bt-device-headphones"
return "bt-device-headphones";
}
if (icon.includes("mouse") || name.includes("mouse")) {
return "bt-device-mouse"
return "bt-device-mouse";
}
if (icon.includes("keyboard") || name.includes("keyboard")) {
return "bt-device-keyboard"
return "bt-device-keyboard";
}
if (icon.includes("phone") || name.includes("phone") || name.includes("iphone") || name.includes("android") || name.includes("samsung")) {
return "bt-device-phone"
return "bt-device-phone";
}
if (icon.includes("watch") || name.includes("watch")) {
return "bt-device-watch"
return "bt-device-watch";
}
if (icon.includes("speaker") || name.includes("speaker")) {
return "bt-device-speaker"
return "bt-device-speaker";
}
if (icon.includes("display") || name.includes("tv")) {
return "bt-device-tv"
return "bt-device-tv";
}
return "bt-device-generic"
return "bt-device-generic";
}
function canConnect(device) {
if (!device)
return false
return false;
/*
Paired
Means youve successfully exchanged keys with the device.
The devices remember each other and can authenticate without repeating the pairing process.
Example: once your headphones are paired, you dont need to type a PIN every time.
Hence, instead of !device.paired, should be device.connected
Paired
Means youve successfully exchanged keys with the device.
The devices remember each other and can authenticate without repeating the pairing process.
Example: once your headphones are paired, you dont need to type a PIN every time.
Hence, instead of !device.paired, should be device.connected
*/
return !device.connected && !device.pairing && !device.blocked
return !device.connected && !device.pairing && !device.blocked;
}
function canDisconnect(device) {
if (!device)
return false
return device.connected && !device.pairing && !device.blocked
return false;
return device.connected && !device.pairing && !device.blocked;
}
function getStatusString(device) {
if (device.state === BluetoothDeviceState.Connecting) {
return "Connecting..."
return "Connecting...";
}
if (device.pairing) {
return "Pairing..."
return "Pairing...";
}
if (device.blocked) {
return "Blocked"
return "Blocked";
}
return ""
return "";
}
function getSignalStrength(device) {
if (!device || device.signalStrength === undefined || device.signalStrength <= 0) {
return "Signal: Unknown"
return "Signal: Unknown";
}
var signal = device.signalStrength
var signal = device.signalStrength;
if (signal >= 80) {
return "Signal: Excellent"
return "Signal: Excellent";
}
if (signal >= 60) {
return "Signal: Good"
return "Signal: Good";
}
if (signal >= 40) {
return "Signal: Fair"
return "Signal: Fair";
}
if (signal >= 20) {
return "Signal: Poor"
return "Signal: Poor";
}
return "Signal: Very poor"
return "Signal: Very poor";
}
function getBattery(device) {
return `Battery: ${Math.round(device.battery * 100)}%`
return `Battery: ${Math.round(device.battery * 100)}%`;
}
function getSignalIcon(device) {
if (!device || device.signalStrength === undefined || device.signalStrength <= 0) {
return "antenna-bars-off"
return "antenna-bars-off";
}
var signal = device.signalStrength
var signal = device.signalStrength;
if (signal >= 80) {
return "antenna-bars-5"
return "antenna-bars-5";
}
if (signal >= 60) {
return "antenna-bars-4"
return "antenna-bars-4";
}
if (signal >= 40) {
return "antenna-bars-3"
return "antenna-bars-3";
}
if (signal >= 20) {
return "antenna-bars-2"
return "antenna-bars-2";
}
return "antenna-bars-1"
return "antenna-bars-1";
}
function isDeviceBusy(device) {
if (!device) {
return false
return false;
}
return device.pairing || device.state === BluetoothDeviceState.Disconnecting || device.state === BluetoothDeviceState.Connecting
return device.pairing || device.state === BluetoothDeviceState.Disconnecting || device.state === BluetoothDeviceState.Connecting;
}
function connectDeviceWithTrust(device) {
if (!device) {
return
return;
}
device.trusted = true
device.connect()
device.trusted = true;
device.connect();
}
function disconnectDevice(device) {
if (!device) {
return
return;
}
device.disconnect()
device.disconnect();
}
function forgetDevice(device) {
if (!device) {
return
return;
}
device.trusted = false
device.forget()
device.trusted = false;
device.forget();
}
function setBluetoothEnabled(state) {
if (!adapter) {
Logger.w("Bluetooth", "No adapter available")
return
Logger.w("Bluetooth", "No adapter available");
return;
}
Logger.i("Bluetooth", "SetBluetoothEnabled", state)
adapter.enabled = state
Logger.i("Bluetooth", "SetBluetoothEnabled", state);
adapter.enabled = state;
}
Process {
@@ -259,25 +258,25 @@ Singleton {
stdout: StdioCollector {
onStreamFinished: {
const wifiBlocked = text && text.trim().includes("Soft blocked: yes")
Logger.d("Network", "Wi-Fi adapter was detected as blocked:", blocked)
const wifiBlocked = text && text.trim().includes("Soft blocked: yes");
Logger.d("Network", "Wi-Fi adapter was detected as blocked:", blocked);
// Check if airplane mode has been toggled
if (wifiBlocked && wifiBlocked === root.blocked) {
root.airplaneModeToggled = true
NetworkService.setWifiEnabled(false)
ToastService.showNotice(I18n.tr("toast.airplane-mode.title"), I18n.tr("toast.airplane-mode.enabled"), "plane")
root.airplaneModeToggled = true;
NetworkService.setWifiEnabled(false);
ToastService.showNotice(I18n.tr("toast.airplane-mode.title"), I18n.tr("toast.airplane-mode.enabled"), "plane");
} else if (!wifiBlocked && wifiBlocked === root.blocked) {
root.airplaneModeToggled = true
NetworkService.setWifiEnabled(true)
ToastService.showNotice(I18n.tr("toast.airplane-mode.title"), I18n.tr("toast.airplane-mode.disabled"), "plane-off")
root.airplaneModeToggled = true;
NetworkService.setWifiEnabled(true);
ToastService.showNotice(I18n.tr("toast.airplane-mode.title"), I18n.tr("toast.airplane-mode.disabled"), "plane-off");
} else if (adapter.enabled) {
ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.enabled"), "bluetooth")
discoveryTimer.running = true
ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.enabled"), "bluetooth");
discoveryTimer.running = true;
} else {
ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.disabled"), "bluetooth-off")
ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.disabled"), "bluetooth-off");
}
root.airplaneModeToggled = false
root.airplaneModeToggled = false;
}
}
}
+204 -206
View File
@@ -41,8 +41,8 @@ Singleton {
}
onLoadFailed: {
cacheAdapter.knownNetworks = ({})
cacheAdapter.lastConnected = ""
cacheAdapter.knownNetworks = ({});
cacheAdapter.lastConnected = "";
}
}
@@ -51,25 +51,25 @@ Singleton {
function onWifiEnabledChanged() {
if (Settings.data.network.wifiEnabled) {
if (!BluetoothService.airplaneModeToggled) {
ToastService.showNotice(I18n.tr("wifi.panel.title"), I18n.tr("toast.wifi.enabled"), "wifi")
ToastService.showNotice(I18n.tr("wifi.panel.title"), I18n.tr("toast.wifi.enabled"), "wifi");
}
// Perform a scan to update the UI
delayedScanTimer.interval = 3000
delayedScanTimer.restart()
delayedScanTimer.interval = 3000;
delayedScanTimer.restart();
} else {
if (!BluetoothService.airplaneModeToggled) {
ToastService.showNotice(I18n.tr("wifi.panel.title"), I18n.tr("toast.wifi.disabled"), "wifi-off")
ToastService.showNotice(I18n.tr("wifi.panel.title"), I18n.tr("toast.wifi.disabled"), "wifi-off");
}
// Clear networks so the widget icon changes
root.networks = ({})
root.networks = ({});
}
}
}
Component.onCompleted: {
Logger.i("Network", "Service started")
syncWifiState()
scan()
Logger.i("Network", "Service started");
syncWifiState();
scan();
}
// Save cache with debounce
@@ -80,7 +80,7 @@ Singleton {
}
function saveCache() {
saveDebounce.restart()
saveDebounce.restart();
}
// Delayed scan timer
@@ -112,98 +112,96 @@ Singleton {
// Core functions
function syncWifiState() {
wifiStateProcess.running = true
wifiStateProcess.running = true;
}
function setWifiEnabled(enabled) {
Settings.data.network.wifiEnabled = enabled
wifiStateEnableProcess.running = true
Settings.data.network.wifiEnabled = enabled;
wifiStateEnableProcess.running = true;
}
function scan() {
if (!Settings.data.network.wifiEnabled)
return
return;
if (scanning) {
// Mark current scan results to be ignored and schedule a new scan
Logger.d("Network", "Scan already in progress, will ignore results and rescan")
ignoreScanResults = true
scanPending = true
return
Logger.d("Network", "Scan already in progress, will ignore results and rescan");
ignoreScanResults = true;
scanPending = true;
return;
}
scanning = true
lastError = ""
ignoreScanResults = false
scanning = true;
lastError = "";
ignoreScanResults = false;
// Get existing profiles first, then scan
profileCheckProcess.running = true
Logger.d("Network", "Wi-Fi scan in progress...")
profileCheckProcess.running = true;
Logger.d("Network", "Wi-Fi scan in progress...");
}
function connect(ssid, password = "") {
if (connecting)
return
connecting = true
connectingTo = ssid
lastError = ""
return;
connecting = true;
connectingTo = ssid;
lastError = "";
// Check if we have a saved connection
if (networks[ssid]?.existing || cachedNetworks[ssid]) {
connectProcess.mode = "saved"
connectProcess.ssid = ssid
connectProcess.password = ""
connectProcess.mode = "saved";
connectProcess.ssid = ssid;
connectProcess.password = "";
} else {
connectProcess.mode = "new"
connectProcess.ssid = ssid
connectProcess.password = password
connectProcess.mode = "new";
connectProcess.ssid = ssid;
connectProcess.password = password;
}
connectProcess.running = true
connectProcess.running = true;
}
function disconnect(ssid) {
disconnectingFrom = ssid
disconnectProcess.ssid = ssid
disconnectProcess.running = true
disconnectingFrom = ssid;
disconnectProcess.ssid = ssid;
disconnectProcess.running = true;
}
function forget(ssid) {
forgettingNetwork = ssid
forgettingNetwork = ssid;
// Remove from cache
let known = cacheAdapter.knownNetworks
delete known[ssid]
cacheAdapter.knownNetworks = known
let known = cacheAdapter.knownNetworks;
delete known[ssid];
cacheAdapter.knownNetworks = known;
if (cacheAdapter.lastConnected === ssid) {
cacheAdapter.lastConnected = ""
cacheAdapter.lastConnected = "";
}
saveCache()
saveCache();
// Remove from system
forgetProcess.ssid = ssid
forgetProcess.running = true
forgetProcess.ssid = ssid;
forgetProcess.running = true;
}
// Helper function to immediately update network status
function updateNetworkStatus(ssid, connected) {
let nets = networks
let nets = networks;
// Update all networks connected status
for (let key in nets) {
if (nets[key].connected && key !== ssid) {
nets[key].connected = false
nets[key].connected = false;
}
}
// Update the target network if it exists
if (nets[ssid]) {
nets[ssid].connected = connected
nets[ssid].existing = true
nets[ssid].cached = true
nets[ssid].connected = connected;
nets[ssid].existing = true;
nets[ssid].cached = true;
} else if (connected) {
// Create a temporary entry if network doesn't exist yet
nets[ssid] = {
@@ -213,29 +211,29 @@ Singleton {
"connected": true,
"existing": true,
"cached": true
}
};
}
// Trigger property change notification
networks = ({})
networks = nets
networks = ({});
networks = nets;
}
// Helper functions
function signalIcon(signal, isConnected = false) {
if (isConnected && !root.internetConnectivity)
return "world-off"
return "world-off";
if (signal >= 80)
return "wifi"
return "wifi";
if (signal >= 50)
return "wifi-2"
return "wifi-2";
if (signal >= 20)
return "wifi-1"
return "wifi-0"
return "wifi-1";
return "wifi-0";
}
function isSecured(security) {
return security && security !== "--" && security.trim() !== ""
return security && security !== "--" && security.trim() !== "";
}
// Processes
@@ -247,12 +245,12 @@ Singleton {
stdout: StdioCollector {
onStreamFinished: {
const connected = text.split("\n").some(line => {
const parts = line.split(":")
return parts[1] === "ethernet" && parts[2] === "connected"
})
const parts = line.split(":");
return parts[1] === "ethernet" && parts[2] === "connected";
});
if (root.ethernetConnected !== connected) {
root.ethernetConnected = connected
Logger.d("Network", "Ethernet connected:", root.ethernetConnected)
root.ethernetConnected = connected;
Logger.d("Network", "Ethernet connected:", root.ethernetConnected);
}
}
}
@@ -267,10 +265,10 @@ Singleton {
stdout: StdioCollector {
onStreamFinished: {
const enabled = text.trim() === "enabled"
Logger.d("Network", "Wi-Fi adapter was detect as enabled:", enabled)
const enabled = text.trim() === "enabled";
Logger.d("Network", "Wi-Fi adapter was detect as enabled:", enabled);
if (Settings.data.network.wifiEnabled !== enabled) {
Settings.data.network.wifiEnabled = enabled
Settings.data.network.wifiEnabled = enabled;
}
}
}
@@ -284,16 +282,16 @@ Singleton {
stdout: StdioCollector {
onStreamFinished: {
Logger.i("Network", "Wi-Fi state change command executed.")
Logger.i("Network", "Wi-Fi state change command executed.");
// Re-check the state to ensure it's in sync
syncWifiState()
syncWifiState();
}
}
stderr: StdioCollector {
onStreamFinished: {
if (text.trim()) {
Logger.w("Network", "Error changing Wi-Fi state: " + text)
Logger.w("Network", "Error changing Wi-Fi state: " + text);
}
}
}
@@ -309,35 +307,35 @@ Singleton {
stdout: StdioCollector {
onStreamFinished: {
const result = text.trim()
const result = text.trim();
if (!result) {
return
return;
}
if (result === "none" && root.networkConnectivity !== result) {
root.networkConnectivity = result
connectivityCheckProcess.failedChecks = 0
root.scan()
root.networkConnectivity = result;
connectivityCheckProcess.failedChecks = 0;
root.scan();
}
if (result === "full" && root.networkConnectivity !== result) {
root.networkConnectivity = result
root.internetConnectivity = true
connectivityCheckProcess.failedChecks = 0
root.scan()
root.networkConnectivity = result;
root.internetConnectivity = true;
connectivityCheckProcess.failedChecks = 0;
root.scan();
}
if ((result === "limited" || result === "portal") && root.networkConnectivity !== result) {
connectivityCheckProcess.failedChecks++
connectivityCheckProcess.failedChecks++;
if (connectivityCheckProcess.failedChecks === 3) {
root.networkConnectivity = result
pingCheckProcess.running = true
root.networkConnectivity = result;
pingCheckProcess.running = true;
}
}
if (result === "unknown" && root.networkConnectivity !== result) {
root.networkConnectivity = result
connectivityCheckProcess.failedChecks = 0
root.networkConnectivity = result;
connectivityCheckProcess.failedChecks = 0;
}
}
}
@@ -345,7 +343,7 @@ Singleton {
stderr: StdioCollector {
onStreamFinished: {
if (text.trim()) {
Logger.w("Network", "Connectivity check error: " + text)
Logger.w("Network", "Connectivity check error: " + text);
}
}
}
@@ -357,14 +355,14 @@ Singleton {
onExited: (exitCode, exitStatus) => {
if (exitCode === 0) {
connectivityCheckProcess.failedChecks = 0
connectivityCheckProcess.failedChecks = 0;
} else {
root.internetConnectivity = false
Logger.i("Network", "No internet connectivity")
ToastService.showWarning(root.cachedLastConnected, I18n.tr("toast.internet.limited"))
connectivityCheckProcess.failedChecks = 0
root.internetConnectivity = false;
Logger.i("Network", "No internet connectivity");
ToastService.showWarning(root.cachedLastConnected, I18n.tr("toast.internet.limited"));
connectivityCheckProcess.failedChecks = 0;
}
root.scan()
root.scan();
}
}
@@ -377,25 +375,25 @@ Singleton {
stdout: StdioCollector {
onStreamFinished: {
if (root.ignoreScanResults) {
Logger.d("Network", "Ignoring profile check results (new scan requested)")
root.scanning = false
Logger.d("Network", "Ignoring profile check results (new scan requested)");
root.scanning = false;
// Check if we need to start a new scan
if (root.scanPending) {
root.scanPending = false
delayedScanTimer.interval = 100
delayedScanTimer.restart()
root.scanPending = false;
delayedScanTimer.interval = 100;
delayedScanTimer.restart();
}
return
return;
}
const profiles = {}
const lines = text.split("\n").filter(l => l.trim())
const profiles = {};
const lines = text.split("\n").filter(l => l.trim());
for (const line of lines) {
profiles[line.trim()] = true
profiles[line.trim()] = true;
}
scanProcess.existingProfiles = profiles
scanProcess.running = true
scanProcess.existingProfiles = profiles;
scanProcess.running = true;
}
}
}
@@ -410,65 +408,65 @@ Singleton {
stdout: StdioCollector {
onStreamFinished: {
if (root.ignoreScanResults) {
Logger.d("Network", "Ignoring scan results (new scan requested)")
root.scanning = false
Logger.d("Network", "Ignoring scan results (new scan requested)");
root.scanning = false;
// Check if we need to start a new scan
if (root.scanPending) {
root.scanPending = false
delayedScanTimer.interval = 100
delayedScanTimer.restart()
root.scanPending = false;
delayedScanTimer.interval = 100;
delayedScanTimer.restart();
}
return
return;
}
// Process the scan results as before...
const lines = text.split("\n")
const networksMap = {}
const lines = text.split("\n");
const networksMap = {};
for (var i = 0; i < lines.length; ++i) {
const line = lines[i].trim()
const line = lines[i].trim();
if (!line)
continue
continue;
// Parse from the end to handle SSIDs with colons
// Format is SSID:SECURITY:SIGNAL:IN-USE
// We know the last 3 fields, so everything else is SSID
const lastColonIdx = line.lastIndexOf(":")
const lastColonIdx = line.lastIndexOf(":");
if (lastColonIdx === -1) {
Logger.w("Network", "Malformed nmcli output line:", line)
continue
Logger.w("Network", "Malformed nmcli output line:", line);
continue;
}
const inUse = line.substring(lastColonIdx + 1)
const remainingLine = line.substring(0, lastColonIdx)
const inUse = line.substring(lastColonIdx + 1);
const remainingLine = line.substring(0, lastColonIdx);
const secondLastColonIdx = remainingLine.lastIndexOf(":")
const secondLastColonIdx = remainingLine.lastIndexOf(":");
if (secondLastColonIdx === -1) {
Logger.w("Network", "Malformed nmcli output line:", line)
continue
Logger.w("Network", "Malformed nmcli output line:", line);
continue;
}
const signal = remainingLine.substring(secondLastColonIdx + 1)
const remainingLine2 = remainingLine.substring(0, secondLastColonIdx)
const signal = remainingLine.substring(secondLastColonIdx + 1);
const remainingLine2 = remainingLine.substring(0, secondLastColonIdx);
const thirdLastColonIdx = remainingLine2.lastIndexOf(":")
const thirdLastColonIdx = remainingLine2.lastIndexOf(":");
if (thirdLastColonIdx === -1) {
Logger.w("Network", "Malformed nmcli output line:", line)
continue
Logger.w("Network", "Malformed nmcli output line:", line);
continue;
}
const security = remainingLine2.substring(thirdLastColonIdx + 1)
const ssid = remainingLine2.substring(0, thirdLastColonIdx)
const security = remainingLine2.substring(thirdLastColonIdx + 1);
const ssid = remainingLine2.substring(0, thirdLastColonIdx);
if (ssid) {
const signalInt = parseInt(signal) || 0
const connected = inUse === "*"
const signalInt = parseInt(signal) || 0;
const connected = inUse === "*";
// Track connected network in cache
if (connected && cacheAdapter.lastConnected !== ssid) {
cacheAdapter.lastConnected = ssid
saveCache()
cacheAdapter.lastConnected = ssid;
saveCache();
}
if (!networksMap[ssid]) {
@@ -479,59 +477,59 @@ Singleton {
"connected": connected,
"existing": ssid in scanProcess.existingProfiles,
"cached": ssid in cacheAdapter.knownNetworks
}
};
} else {
// Keep the best signal for duplicate SSIDs
const existingNet = networksMap[ssid]
const existingNet = networksMap[ssid];
if (connected) {
existingNet.connected = true
existingNet.connected = true;
}
if (signalInt > existingNet.signal) {
existingNet.signal = signalInt
existingNet.security = security || "--"
existingNet.signal = signalInt;
existingNet.security = security || "--";
}
}
}
}
// Logging
const oldSSIDs = Object.keys(root.networks)
const newSSIDs = Object.keys(networksMap)
const newNetworks = newSSIDs.filter(ssid => !oldSSIDs.includes(ssid))
const lostNetworks = oldSSIDs.filter(ssid => !newSSIDs.includes(ssid))
const oldSSIDs = Object.keys(root.networks);
const newSSIDs = Object.keys(networksMap);
const newNetworks = newSSIDs.filter(ssid => !oldSSIDs.includes(ssid));
const lostNetworks = oldSSIDs.filter(ssid => !newSSIDs.includes(ssid));
if (newNetworks.length > 0 || lostNetworks.length > 0) {
if (newNetworks.length > 0) {
Logger.d("Network", "New Wi-Fi SSID discovered:", newNetworks.join(", "))
Logger.d("Network", "New Wi-Fi SSID discovered:", newNetworks.join(", "));
}
if (lostNetworks.length > 0) {
Logger.d("Network", "Wi-Fi SSID disappeared:", lostNetworks.join(", "))
Logger.d("Network", "Wi-Fi SSID disappeared:", lostNetworks.join(", "));
}
Logger.d("Network", "Total Wi-Fi SSIDs:", Object.keys(networksMap).length)
Logger.d("Network", "Total Wi-Fi SSIDs:", Object.keys(networksMap).length);
}
Logger.d("Network", "Wi-Fi scan completed")
root.networks = networksMap
root.scanning = false
Logger.d("Network", "Wi-Fi scan completed");
root.networks = networksMap;
root.scanning = false;
// Check if we need to start a new scan
if (root.scanPending) {
root.scanPending = false
delayedScanTimer.interval = 100
delayedScanTimer.restart()
root.scanPending = false;
delayedScanTimer.interval = 100;
delayedScanTimer.restart();
}
}
}
stderr: StdioCollector {
onStreamFinished: {
root.scanning = false
root.scanning = false;
if (text.trim()) {
Logger.w("Network", "Scan error: " + text)
Logger.w("Network", "Scan error: " + text);
// If scan fails, retry
delayedScanTimer.interval = 5000
delayedScanTimer.restart()
delayedScanTimer.interval = 5000;
delayedScanTimer.restart();
}
}
}
@@ -545,13 +543,13 @@ Singleton {
command: {
if (mode === "saved") {
return ["nmcli", "connection", "up", "id", ssid]
return ["nmcli", "connection", "up", "id", ssid];
} else {
const cmd = ["nmcli", "device", "wifi", "connect", ssid]
const cmd = ["nmcli", "device", "wifi", "connect", ssid];
if (password) {
cmd.push("password", password)
cmd.push("password", password);
}
return cmd
return cmd;
}
}
environment: ({
@@ -563,59 +561,59 @@ Singleton {
// Check if the output actually indicates success
// nmcli outputs "Device '...' successfully activated" or "Connection successfully activated"
// on success. Empty output or other messages indicate failure.
const output = text.trim()
const output = text.trim();
if (!output || (!output.includes("successfully activated") && !output.includes("Connection successfully"))) {
// No success message - likely an error occurred
// Don't update anything, let stderr handler deal with it
return
return;
}
// Success - update cache
let known = cacheAdapter.knownNetworks
let known = cacheAdapter.knownNetworks;
known[connectProcess.ssid] = {
"profileName": connectProcess.ssid,
"lastConnected": Date.now()
}
cacheAdapter.knownNetworks = known
cacheAdapter.lastConnected = connectProcess.ssid
saveCache()
};
cacheAdapter.knownNetworks = known;
cacheAdapter.lastConnected = connectProcess.ssid;
saveCache();
// Immediately update the UI before scanning
root.updateNetworkStatus(connectProcess.ssid, true)
root.updateNetworkStatus(connectProcess.ssid, true);
root.connecting = false
root.connectingTo = ""
Logger.i("Network", `Connected to network: '${connectProcess.ssid}'`)
root.connecting = false;
root.connectingTo = "";
Logger.i("Network", `Connected to network: '${connectProcess.ssid}'`);
ToastService.showNotice(I18n.tr("wifi.panel.title"), I18n.tr("toast.wifi.connected", {
"ssid": connectProcess.ssid
}), "wifi")
}), "wifi");
// Still do a scan to get accurate signal and security info
delayedScanTimer.interval = 5000
delayedScanTimer.restart()
delayedScanTimer.interval = 5000;
delayedScanTimer.restart();
}
}
stderr: StdioCollector {
onStreamFinished: {
root.connecting = false
root.connectingTo = ""
root.connecting = false;
root.connectingTo = "";
if (text.trim()) {
// Parse common errors
if (text.includes("Secrets were required") || text.includes("no secrets provided")) {
root.lastError = "Incorrect password"
forget(connectProcess.ssid)
root.lastError = "Incorrect password";
forget(connectProcess.ssid);
} else if (text.includes("No network with SSID")) {
root.lastError = "Network not found"
root.lastError = "Network not found";
} else if (text.includes("Timeout")) {
root.lastError = "Connection timeout"
root.lastError = "Connection timeout";
} else {
root.lastError = text.split("\n")[0].trim()
root.lastError = text.split("\n")[0].trim();
}
Logger.w("Network", "Connect error: " + text)
Logger.w("Network", "Connect error: " + text);
}
}
}
@@ -629,30 +627,30 @@ Singleton {
stdout: StdioCollector {
onStreamFinished: {
Logger.i("Network", `Disconnected from network: '${disconnectProcess.ssid}'`)
Logger.i("Network", `Disconnected from network: '${disconnectProcess.ssid}'`);
ToastService.showNotice(I18n.tr("wifi.panel.title"), I18n.tr("toast.wifi.disconnected", {
"ssid": disconnectProcess.ssid
}), "wifi-off")
}), "wifi-off");
// Immediately update UI on successful disconnect
root.updateNetworkStatus(disconnectProcess.ssid, false)
root.disconnectingFrom = ""
root.updateNetworkStatus(disconnectProcess.ssid, false);
root.disconnectingFrom = "";
// Do a scan to refresh the list
delayedScanTimer.interval = 1000
delayedScanTimer.restart()
delayedScanTimer.interval = 1000;
delayedScanTimer.restart();
}
}
stderr: StdioCollector {
onStreamFinished: {
root.disconnectingFrom = ""
root.disconnectingFrom = "";
if (text.trim()) {
Logger.w("Network", "Disconnect error: " + text)
Logger.w("Network", "Disconnect error: " + text);
}
// Still trigger a scan even on error
delayedScanTimer.interval = 5000
delayedScanTimer.restart()
delayedScanTimer.interval = 5000;
delayedScanTimer.restart();
}
}
}
@@ -694,36 +692,36 @@ Singleton {
stdout: StdioCollector {
onStreamFinished: {
Logger.i("Network", `Forget network: "${forgetProcess.ssid}"`)
Logger.d("Network", text.trim().replace(/[\r\n]/g, " "))
Logger.i("Network", `Forget network: "${forgetProcess.ssid}"`);
Logger.d("Network", text.trim().replace(/[\r\n]/g, " "));
// Update both cached and existing status immediately
let nets = root.networks
let nets = root.networks;
if (nets[forgetProcess.ssid]) {
nets[forgetProcess.ssid].cached = false
nets[forgetProcess.ssid].existing = false
nets[forgetProcess.ssid].cached = false;
nets[forgetProcess.ssid].existing = false;
// Trigger property change
root.networks = ({})
root.networks = nets
root.networks = ({});
root.networks = nets;
}
root.forgettingNetwork = ""
root.forgettingNetwork = "";
// Scan to verify the profile is gone
delayedScanTimer.interval = 5000
delayedScanTimer.restart()
delayedScanTimer.interval = 5000;
delayedScanTimer.restart();
}
}
stderr: StdioCollector {
onStreamFinished: {
root.forgettingNetwork = ""
root.forgettingNetwork = "";
if (text.trim() && !text.includes("No profiles found")) {
Logger.w("Network", "Forget error: " + text)
Logger.w("Network", "Forget error: " + text);
}
// Still Trigger a scan even on error
delayedScanTimer.interval = 5000
delayedScanTimer.restart()
delayedScanTimer.interval = 5000;
delayedScanTimer.restart();
}
}
}