Minor: Refactor the code-base for better organization and compartmentalization. (#934)

* Clean up unused code

* Fix media player formatting issue for labels with new line characteres.

* Refactor the media player handlers into a class.

* More code cleanup and organize shared weather utils into distinct classes.

* Flatten some nesting.

* Move weather manager in dedicated class and build HTTP Utility class for Rest API calling.

* Remove logs

* Rebase master merge

* Reorg code (WIP)

* More reorg

* Delete utility scripts

* Reorg options

* Finish moving all options over

* Fix typescript issues

* Update options imports to default

* missed update

* Screw barrel files honestly, work of the devil.

* Only initialize power profiles if power-profiles-daemon is running.

* Fix window positioning and weather service naming

* style dir

* More organization

* Restructure types to be closer to their source

* Remove lib types and constants

* Update basic weather object to be saner with extensibility.

* Service updates

* Fix initialization strategy for services.

* Fix Config Manager to only emit changed objects and added missing temp converters.

* Update storage service to handle unit changes.

* Added cpu temp sensor auto-discovery

* Added missing JSDocs to services

* remove unused

* Migrate to network service.

* Fix network password issue.

* Move out password input into helper

* Rename password mask constant to be less double-negativey.

* Dropdown menu rename

* Added a component to edit JSON in the settings dialog (rough/WIP)

* Align settings

* Add and style JSON Editor.

* Adjust padding

* perf(shortcuts):  avoid unnecessary polling when shortcuts are disabled

Stops the recording poller when shortcuts are disabled, preventing redundant polling and reducing resource usage.

* Fix types and return value if shortcut not enabled.

* Move the swww daemon checking process outside of the wallpaper service into a dedicated deamon lifecyle processor.

* Add more string formatters and use title case for weather status (as it was).

* Fix startup errors.

* Rgba fix

* Remove zod from dependencies

---------

Co-authored-by: KernelDiego <gonzalezdiego.contact@gmail.com>
This commit is contained in:
Jas Singh
2025-05-26 19:45:11 -07:00
committed by GitHub
parent 436dcbfcf2
commit 8cf5806766
532 changed files with 13134 additions and 8669 deletions

View File

@@ -0,0 +1,102 @@
import { bind, Variable } from 'astal';
import AstalNetwork from 'gi://AstalNetwork?version=0.1';
/**
* EthernetManager handles ethernet-related functionality for dropdowns
*/
export class EthernetManager {
private _astalNetwork: AstalNetwork.Network;
public wiredState: Variable<AstalNetwork.DeviceState> = Variable(AstalNetwork.DeviceState.UNKNOWN);
public wiredInternet: Variable<AstalNetwork.Internet> = Variable(AstalNetwork.Internet.DISCONNECTED);
public wiredIcon: Variable<string> = Variable('');
public wiredSpeed: Variable<number> = Variable(0);
private _wiredStateBinding: Variable<void> | undefined;
private _wiredInternetBinding: Variable<void> | undefined;
private _wiredIconBinding: Variable<void> | undefined;
private _wiredSpeedBinding: Variable<void> | undefined;
constructor(networkService: AstalNetwork.Network) {
this._astalNetwork = networkService;
}
/**
* Called when the wired service changes to update bindings
*/
public onWiredServiceChanged(): void {
this._getWiredState();
this._getWiredInternet();
this._getWiredIcon();
this._getWiredSpeed();
}
/**
* Retrieves the current state of the wired network.
*/
private _getWiredState(): void {
this._wiredStateBinding?.drop();
this._wiredStateBinding = undefined;
if (this._astalNetwork.wired === null) {
this.wiredState.set(AstalNetwork.DeviceState.UNAVAILABLE);
return;
}
this._wiredStateBinding = Variable.derive([bind(this._astalNetwork.wired, 'state')], (state) => {
this.wiredState.set(state);
});
}
/**
* Retrieves the current internet status of the wired network.
*/
private _getWiredInternet(): void {
this._wiredInternetBinding?.drop();
this._wiredInternetBinding = undefined;
if (this._astalNetwork.wired === null) {
return;
}
this._wiredInternetBinding = Variable.derive(
[bind(this._astalNetwork.wired, 'internet')],
(internet) => {
this.wiredInternet.set(internet);
},
);
}
/**
* Retrieves the current icon for the wired network.
*/
private _getWiredIcon(): void {
this._wiredIconBinding?.drop();
this._wiredIconBinding = undefined;
if (this._astalNetwork.wired === null) {
this.wiredIcon.set('network-wired-symbolic');
return;
}
this._wiredIconBinding = Variable.derive([bind(this._astalNetwork.wired, 'iconName')], (icon) => {
this.wiredIcon.set(icon);
});
}
/**
* Retrieves the current speed of the wired network.
*/
private _getWiredSpeed(): void {
this._wiredSpeedBinding?.drop();
this._wiredSpeedBinding = undefined;
if (this._astalNetwork.wired === null) {
return;
}
this._wiredSpeedBinding = Variable.derive([bind(this._astalNetwork.wired, 'speed')], (speed) => {
this.wiredSpeed.set(speed);
});
}
}

View File

@@ -0,0 +1,70 @@
import { bind, Variable } from 'astal';
import AstalNetwork from 'gi://AstalNetwork?version=0.1';
import { WifiManager } from './wifi';
import { EthernetManager } from './ethernet';
import { WifiIcon, wifiIconMap } from './types';
/**
* NetworkService consolidates all network-related functionality from various components
* into a single service for better organization and maintainability.
*/
export class NetworkService {
private static _instance: NetworkService;
private _astalNetwork: AstalNetwork.Network;
public wifi: WifiManager;
public ethernet: EthernetManager;
private constructor() {
this._astalNetwork = AstalNetwork.get_default();
this.wifi = new WifiManager(this._astalNetwork);
this.ethernet = new EthernetManager(this._astalNetwork);
this._setupBindings();
}
/**
* Gets the singleton instance of NetworkService
*
* @returns The NetworkService instance
*/
public static getInstance(): NetworkService {
if (!this._instance) {
this._instance = new NetworkService();
}
return this._instance;
}
/**
* Sets up bindings to monitor network service changes
*/
private _setupBindings(): void {
Variable.derive([bind(this._astalNetwork, 'wifi')], () => {
this.wifi.onWifiServiceChanged();
});
Variable.derive([bind(this._astalNetwork, 'wired')], () => {
this.ethernet.onWiredServiceChanged();
});
}
/**
* Retrieves the appropriate WiFi icon based on the provided icon name.
*
* @param iconName - The name of the icon to look up. If not provided, a default icon is returned.
* @returns The corresponding WiFi icon as a string.
*/
public getWifiIcon(iconName?: string): WifiIcon {
if (iconName === undefined) {
return '󰤫';
}
const wifiIcon = wifiIconMap.get(iconName.toLowerCase());
if (wifiIcon) {
return wifiIcon;
}
return '󰤨';
}
}

View File

@@ -0,0 +1,43 @@
import AstalNetwork from 'gi://AstalNetwork?version=0.1';
export type WifiIcon = '󰤩' | '󰤨' | '󰤪' | '󰤨' | '󰤩' | '󰤮' | '󰤨' | '󰤥' | '󰤢' | '󰤟' | '󰤯' | '󰤫';
type DeviceSate = AstalNetwork.DeviceState;
type DevceStates = {
[key in DeviceSate]: string;
};
export const DEVICE_STATES: DevceStates = {
[AstalNetwork.DeviceState.UNKNOWN]: 'Unknown',
[AstalNetwork.DeviceState.UNMANAGED]: 'Unmanaged',
[AstalNetwork.DeviceState.UNAVAILABLE]: 'Unavailable',
[AstalNetwork.DeviceState.DISCONNECTED]: 'Disconnected',
[AstalNetwork.DeviceState.PREPARE]: 'Prepare',
[AstalNetwork.DeviceState.CONFIG]: 'Config',
[AstalNetwork.DeviceState.NEED_AUTH]: 'Need Authentication',
[AstalNetwork.DeviceState.IP_CONFIG]: 'IP Configuration',
[AstalNetwork.DeviceState.IP_CHECK]: 'IP Check',
[AstalNetwork.DeviceState.SECONDARIES]: 'Secondaries',
[AstalNetwork.DeviceState.ACTIVATED]: 'Activated',
[AstalNetwork.DeviceState.DEACTIVATING]: 'Deactivating',
[AstalNetwork.DeviceState.FAILED]: 'Failed',
} as const;
export const wifiIconMap = new Map<string, WifiIcon>([
['network-wireless-acquiring', '󰤩'],
['network-wireless-connected', '󰤨'],
['network-wireless-encrypted', '󰤪'],
['network-wireless-hotspot', '󰤨'],
['network-wireless-no-route', '󰤩'],
['network-wireless-offline', '󰤮'],
['network-wireless-signal-excellent', '󰤨'],
['network-wireless-signal-good', '󰤥'],
['network-wireless-signal-ok', '󰤢'],
['network-wireless-signal-weak', '󰤟'],
['network-wireless-signal-none', '󰤯'],
]);
export const AP_FLAGS = {
NONE: 0,
PRIVACY: 1,
} as const;

View File

@@ -0,0 +1,351 @@
import { bind, execAsync, Variable } from 'astal';
import { Astal } from 'astal/gtk3';
import AstalNetwork from 'gi://AstalNetwork?version=0.1';
import { SystemUtilities } from 'src/core/system/SystemUtilities';
import { isPrimaryClick } from 'src/lib/events/mouse';
import { AP_FLAGS, DEVICE_STATES } from './types';
/**
* WifiManager handles all WiFi-related functionality for staging and connecting to
* wireless networks
*/
export class WifiManager {
private _astalNetwork: AstalNetwork.Network;
public isWifiEnabled: Variable<boolean> = Variable(false);
public isScanning: Variable<boolean> = Variable(false);
public wifiAccessPoints: Variable<AstalNetwork.AccessPoint[]> = Variable([]);
public staging = Variable<AstalNetwork.AccessPoint | undefined>(undefined);
public connecting = Variable<string>('');
private _wifiEnabledBinding: Variable<void> | undefined;
private _scanningBinding: Variable<void> | undefined;
private _accessPointBinding: Variable<void> | undefined;
constructor(networkService: AstalNetwork.Network) {
this._astalNetwork = networkService;
}
/**
* Called when the WiFi service changes to update bindings
*/
public onWifiServiceChanged(): void {
this._wifiEnabled();
this._scanningStatus();
this._accessPoints();
}
/**
* Checks if WiFi is enabled and updates the `isWifiEnabled` variable.
*/
private _wifiEnabled(): void {
this._wifiEnabledBinding?.drop();
this._wifiEnabledBinding = undefined;
if (this._astalNetwork.wifi === null) {
return;
}
this._wifiEnabledBinding = Variable.derive(
[bind(this._astalNetwork.wifi, 'enabled')],
(isEnabled) => {
this.isWifiEnabled.set(isEnabled);
},
);
}
/**
* Updates the WiFi scanning status.
*/
private _scanningStatus(): void {
this._scanningBinding?.drop();
this._scanningBinding = undefined;
if (this._astalNetwork.wifi === null) {
return;
}
this._scanningBinding = Variable.derive([bind(this._astalNetwork.wifi, 'scanning')], (scanning) => {
this.isScanning.set(scanning);
});
}
/**
* Updates the list of WiFi access points.
*/
private _accessPoints(): void {
this._accessPointBinding?.drop();
this._accessPointBinding = undefined;
if (this._astalNetwork.wifi === null) {
return;
}
Variable.derive([bind(this._astalNetwork.wifi, 'accessPoints')], (axsPoints) => {
this.wifiAccessPoints.set(axsPoints);
});
}
/**
* Removes duplicate access points based on their SSID.
*
* @returns An array of deduplicated access points.
*/
private _dedupeWAPs(): AstalNetwork.AccessPoint[] {
if (this._astalNetwork.wifi === null) {
return [];
}
const WAPs = this._astalNetwork.wifi.get_access_points();
const dedupMap: Record<string, AstalNetwork.AccessPoint> = {};
WAPs.forEach((item: AstalNetwork.AccessPoint) => {
if (item.ssid !== null && !Object.prototype.hasOwnProperty.call(dedupMap, item.ssid)) {
dedupMap[item.ssid] = item;
}
});
return Object.keys(dedupMap).map((itm) => dedupMap[itm]);
}
/**
* Determines if a given access point is currently in the staging area.
*
* @param wap - The access point to check.
* @returns True if the access point is in staging; otherwise, false.
*/
private _isInStaging(wap: AstalNetwork.AccessPoint): boolean {
const wapInStaging = this.staging.get();
if (wapInStaging === undefined) {
return false;
}
return wap.bssid === wapInStaging.bssid;
}
/**
* Retrieves a list of filtered wireless access points by removing duplicates and excluding specific entries.
*
* @returns A filtered array of wireless access points.
*/
public getFilteredWirelessAPs(): AstalNetwork.AccessPoint[] {
const dedupedWAPs = this._dedupeWAPs();
const filteredWAPs = dedupedWAPs
.filter((ap: AstalNetwork.AccessPoint) => {
return ap.ssid !== 'Unknown' && !this._isInStaging(ap);
})
.sort((a: AstalNetwork.AccessPoint, b: AstalNetwork.AccessPoint) => {
if (this.isApActive(a)) {
return -1;
}
if (this.isApActive(b)) {
return 1;
}
return b.strength - a.strength;
});
return filteredWAPs;
}
/**
* Determines whether the device is in an active state.
*
* @param state - The current state of the device.
* @returns True if the device is in an active state; otherwise, false.
*/
public isApEnabled(state: AstalNetwork.DeviceState | undefined): boolean {
if (state === null) {
return false;
}
return !(
state === AstalNetwork.DeviceState.DISCONNECTED ||
state === AstalNetwork.DeviceState.UNAVAILABLE ||
state === AstalNetwork.DeviceState.FAILED
);
}
/**
* Checks if the given access point is the currently active one.
*
* @param accessPoint - The access point to check.
* @returns True if the access point is active; otherwise, false.
*/
public isApActive(accessPoint: AstalNetwork.AccessPoint): boolean {
return accessPoint.ssid === this._astalNetwork.wifi?.activeAccessPoint?.ssid;
}
/**
* Checks if the specified access point is in the process of disconnecting.
*
* @param accessPoint - The access point to check.
* @returns True if the access point is disconnecting; otherwise, false.
*/
public isDisconnecting(accessPoint: AstalNetwork.AccessPoint): boolean {
if (this.isApActive(accessPoint)) {
return this._astalNetwork.wifi?.state === AstalNetwork.DeviceState.DEACTIVATING;
}
return false;
}
/**
* Retrieves the current Wi-Fi status based on the network service state.
*
* @returns A string representing the current Wi-Fi status.
*/
public getWifiStatus(): string {
const wifiState = this._astalNetwork.wifi?.state;
if (wifiState !== null) {
return DEVICE_STATES[wifiState];
}
return DEVICE_STATES[AstalNetwork.DeviceState.UNKNOWN];
}
/**
* Initiates a connection to the specified access point.
*
* @param accessPoint - The access point to connect to.
* @param event - The click event triggering the connection.
*/
public connectToAP(accessPoint: AstalNetwork.AccessPoint, event: Astal.ClickEvent): void {
if (
accessPoint.bssid === this.connecting.get() ||
this.isApActive(accessPoint) ||
!isPrimaryClick(event)
) {
return;
}
if (!accessPoint.flags || accessPoint.flags === AP_FLAGS.NONE) {
this.connecting.set(accessPoint.bssid ?? '');
execAsync(`nmcli device wifi connect ${accessPoint.bssid}`)
.then(() => {
this.connecting.set('');
this.staging.set({} as AstalNetwork.AccessPoint);
})
.catch((err: Error) => {
this.connecting.set('');
SystemUtilities.notify({
summary: 'Network',
body: err.message,
});
});
} else {
this.staging.set(accessPoint);
}
}
/**
* Connects to a secured access point with a password.
*
* @param accessPoint - The access point to connect to.
* @param password - The password for the network.
*/
public async connectToAPWithPassword(
accessPoint: AstalNetwork.AccessPoint,
password: string,
): Promise<void> {
if (!accessPoint.ssid || !password) {
return Promise.reject(new Error('SSID and password are required'));
}
this.connecting.set(accessPoint.bssid || '');
const connectCommand = `nmcli device wifi connect "${accessPoint.ssid}" password "${password}"`;
return execAsync(connectCommand)
.then(() => {
this.connecting.set('');
this.staging.set(undefined);
})
.catch((err: Error) => {
this.connecting.set('');
throw err;
});
}
/**
* Disconnects from the specified access point.
*
* @param accessPoint - The access point to disconnect from.
* @param event - The click event triggering the disconnection.
*/
public disconnectFromAP(accessPoint: AstalNetwork.AccessPoint, event: Astal.ClickEvent): void {
if (!isPrimaryClick(event)) {
return;
}
this.connecting.set(accessPoint.bssid || '');
execAsync('nmcli connection show --active').then((res: string) => {
const connectionId = this._getIdFromSsid(accessPoint.ssid || '', res);
if (connectionId === undefined) {
console.error(`Error while disconnecting "${accessPoint.ssid}": Connection ID not found`);
return;
}
execAsync(`nmcli connection down ${connectionId} "${accessPoint.ssid}"`)
.then(() => {
this.connecting.set('');
})
.catch((err: unknown) => {
this.connecting.set('');
console.error(`Error while disconnecting "${accessPoint.ssid}": ${err}`);
});
});
}
/**
* Forgets the specified access point by deleting its connection.
*
* @param accessPoint - The access point to forget.
* @param event - The click event triggering the forget action.
*/
public forgetAP(accessPoint: AstalNetwork.AccessPoint, event: Astal.ClickEvent): void {
if (!isPrimaryClick(event)) {
return;
}
this.connecting.set(accessPoint.bssid || '');
execAsync('nmcli connection show --active').then((res: string) => {
const connectionId = this._getIdFromSsid(accessPoint.ssid || '', res);
if (connectionId === undefined) {
console.error(`Error while forgetting "${accessPoint.ssid}": Connection ID not found`);
return;
}
execAsync(`nmcli connection delete ${connectionId} "${accessPoint.ssid}"`)
.then(() => {
this.connecting.set('');
})
.catch((err: unknown) => {
this.connecting.set('');
console.error(`Error while forgetting "${accessPoint.ssid}": ${err}`);
});
});
}
/**
* Extracts the connection ID associated with a given SSID from the `nmcli` command output.
*
* @param ssid - The SSID of the network.
* @param nmcliOutput - The output string from the `nmcli` command.
* @returns The connection ID if found; otherwise, undefined.
*/
private _getIdFromSsid(ssid: string, nmcliOutput: string): string | undefined {
const lines = nmcliOutput.trim().split('\n');
for (const line of lines) {
const columns = line.trim().split(/\s{2,}/);
if (columns[0].includes(ssid)) {
return columns[1];
}
}
}
}