Upgrade to Agsv2 + Astal (#533)

* migrate to astal

* Reorganize project structure.

* progress

* Migrate Dashboard and Window Title modules.

* Migrate clock and notification bar modules.

* Remove unused code

* Media menu

* Rework network and volume modules

* Finish custom modules.

* Migrate battery bar module.

* Update battery module and organize helpers.

* Migrate workspace module.

* Wrap up bar modules.

* Checkpoint before I inevitbly blow something up.

* Updates

* Fix event propagation logic.

* Type fixes

* More type fixes

* Fix padding for event boxes.

* Migrate volume menu and refactor scroll event handlers.

* network module WIP

* Migrate network service.

* Migrate bluetooth menu

* Updates

* Migrate notifications

* Update scrolling behavior for custom modules.

* Improve popup notifications and add timer functionality.

* Migration notifications menu header/controls.

* Migrate notifications menu and consolidate notifications menu code.

* Migrate power menu.

* Dashboard progress

* Migrate dashboard

* Migrate media menu.

* Reduce media menu nesting.

* Finish updating media menu bindings to navigate active player.

* Migrate battery menu

* Consolidate code

* Migrate calendar menu

* Fix workspace logic to update on client add/change/remove and consolidate code.

* Migrate osd

* Consolidate hyprland service connections.

* Implement startup dropdown menu position allocation.

* Migrate settings menu (WIP)

* Settings dialo menu fixes

* Finish Dashboard menu

* Type updates

* update submoldule for types

* update github ci

* ci

* Submodule update

* Ci updates

* Remove type checking for now.

* ci fix

* Fix a bunch of stuff, losing track... need rest. Brb coffee

* Validate dropdown menu before render.

* Consolidate code and add auto-hide functionality.

* Improve auto-hide behavior.

* Consolidate audio menu code

* Organize bluetooth code

* Improve active player logic

* Properly dismiss a notification on action button resolution.

* Implement CLI command engine and migrate CLI commands.

* Handle variable disposal

* Bar component fixes and add hyprland startup rules.

* Handle potentially null bindings network and bluetooth bindings.

* Handle potentially null wired adapter.

* Fix GPU stats

* Handle poller for GPU

* Fix gpu bar logic.

* Clean up logic for stat bars.

* Handle wifi and wired bar icon bindings.

* Fix battery percentages

* Fix switch behavior

* Wifi staging fixes

* Reduce redundant hyprland service calls.

* Code cleanup

* Document the option code and reduce redundant calls to optimize performance.

* Remove outdated comment.

* Add JSDocs

* Add meson to build hyprpanel

* Consistency updates

* Organize commands

* Fix images not showing up on notifications.

* Remove todo

* Move hyprpanel configuration to the ~/.config/hyprpanel directory and add utility commands.

* Handle SRC directory for the bundled/built hyprpanel.

* Add namespaces to all windows

* Migrate systray

* systray updates

* Update meson to include ts, tsx and scss files.

* Remove log from meson

* Fix file choose path and make it float.

* Added a command to check the dependency status

* Update dep names.

* Get scale directly from env

* Add todo
This commit is contained in:
Jas Singh
2024-12-20 18:10:10 -08:00
committed by GitHub
parent 955eed6c60
commit 2ffd602910
605 changed files with 19543 additions and 15999 deletions

View File

@@ -0,0 +1,90 @@
import { Bind } from 'src/lib/types/variable';
import { GenericFunction } from 'src/lib/types/customModules/generic';
import { BarModule } from 'src/lib/types/options';
import { Poller } from './Poller';
import { execAsync, Variable } from 'astal';
/**
* A class that manages polling of a variable by executing a bash command at specified intervals.
*/
export class BashPoller<Value, Parameters extends unknown[]> {
private poller: Poller;
private params: Parameters;
/**
* Creates an instance of BashPoller.
*
* @param targetVariable - The target variable to poll.
* @param trackers - An array of trackers to monitor.
* @param pollingInterval - The interval at which polling occurs.
* @param updateCommand - The command to update the target variable.
* @param pollingFunction - The function to execute during each poll.
* @param params - Additional parameters for the polling function.
*
* @example
*
* ```ts
* //##################### EXAMPLE ##########################
* const updatesPoller = new BashPoller<string, []>(
* pendingUpdates,
* [bind(padZero), bind(postInputUpdater)],
* bind(pollingInterval),
* updateCommand.value,
* processUpdateCount,
* );
* //#######################################################
*
* ```
*/
constructor(
private targetVariable: Variable<Value>,
private trackers: Bind[],
private pollingInterval: Bind,
private updateCommand: string,
private pollingFunction: GenericFunction<Value, [string, ...Parameters]>,
...params: Parameters
) {
this.params = params;
this.poller = new Poller(this.pollingInterval, this.trackers, this.execute);
}
/**
* Executes the bash command specified in the updateCommand property.
*
* The result of the command is processed by the pollingFunction and
* assigned to the targetVariable.
*/
public execute = async (): Promise<void> => {
try {
const res = await execAsync(`bash -c "${this.updateCommand}"`);
this.targetVariable.set(await this.pollingFunction(res, ...this.params));
} catch (error) {
console.error(`Error executing bash command "${this.updateCommand}":`, error);
}
};
/**
* Starts the polling process.
*/
public start(): void {
this.poller.start();
}
/**
* Stops the polling process.
*/
public stop(): void {
this.poller.stop();
}
/**
* Initializes the poller with the specified module.
*
* @param moduleName - The name of the module to initialize.
*/
public initialize(moduleName?: BarModule): void {
this.poller.initialize(moduleName);
}
}

View File

@@ -0,0 +1,86 @@
import { Bind } from 'src/lib/types/variable';
import { GenericFunction } from 'src/lib/types/customModules/generic';
import { BarModule } from 'src/lib/types/options';
import { Poller } from './Poller';
import { Variable } from 'astal';
/**
* A class that manages polling of a variable by executing a generic function at specified intervals.
*/
export class FunctionPoller<Value, Parameters extends unknown[] = []> {
private poller: Poller;
private params: Parameters;
/**
* Creates an instance of FunctionPoller.
*
* @param targetVariable - The target variable to poll.
* @param trackers - An array of trackers to monitor.
* @param pollingInterval - The interval at which polling occurs.
* @param pollingFunction - The function to execute during each poll.
* @param params - Additional parameters for the polling function.
*
* @example
*
* ```ts
* //##################### EXAMPLE ##########################
* const cpuPoller = new FunctionPoller<number, []>(
* cpuUsage,
* [bind(round)],
* bind(pollingInterval),
* computeCPU,
* );
* //#######################################################
*
* ```
*/
constructor(
private targetVariable: Variable<Value>,
private trackers: Bind[],
private pollingInterval: Bind,
private pollingFunction: GenericFunction<Value, Parameters>,
...params: Parameters
) {
this.params = params;
this.poller = new Poller(this.pollingInterval, this.trackers, this.execute);
}
/**
* Executes the polling function with the provided parameters.
*
* The result of the function is assigned to the target variable.
*/
private execute = async (): Promise<void> => {
try {
const result = await this.pollingFunction(...this.params);
this.targetVariable.set(result);
} catch (error) {
console.error('Error executing polling function:', error);
}
};
/**
* Starts the polling process.
*/
public start(): void {
this.poller.start();
}
/**
* Stops the polling process.
*/
public stop(): void {
this.poller.stop();
}
/**
* Initializes the poller with the specified module.
*
* @param moduleName - The name of the module to initialize.
*/
public initialize(moduleName?: BarModule): void {
this.poller.initialize(moduleName);
}
}

107
src/lib/poller/Poller.ts Normal file
View File

@@ -0,0 +1,107 @@
import { Bind } from 'src/lib/types/variable';
import { BarModule } from 'src/lib/types/options';
import { getLayoutItems } from 'src/lib/utils';
import { AstalIO, interval, Variable } from 'astal';
const { layouts } = options.bar;
/**
* A class that manages the polling lifecycle, including interval management and execution state.
*/
export class Poller {
private intervalInstance: AstalIO.Time | null = null;
private isExecuting: boolean = false;
private pollingFunction: () => Promise<void>;
/**
* Creates an instance of Poller.
* @param pollingInterval - The interval at which polling occurs.
* @param trackers - An array of trackers to monitor.
* @param pollingFunction - The function to execute during each poll.
*/
constructor(
private pollingInterval: Bind,
private trackers: Bind[],
pollingFunction: () => Promise<void>,
) {
this.pollingFunction = pollingFunction;
}
/**
* Starts the polling process by setting up the interval.
*/
public start(): void {
Variable.derive([this.pollingInterval, ...this.trackers], (intervalMs: number) => {
this.executePolling(intervalMs);
})();
}
/**
* Stops the polling process and cleans up resources.
*/
public stop(): void {
if (this.intervalInstance !== null) {
this.intervalInstance.cancel();
this.intervalInstance = null;
}
}
/**
* Initializes the polling based on module usage.
*
* If not module is provided then we can safely assume that we want
* to always run the pollig interval.
*
* @param moduleName - The name of the module to initialize.
*/
public initialize(moduleName?: BarModule): void {
if (moduleName === undefined) {
return this.start();
}
const initialModules = getLayoutItems();
if (initialModules.includes(moduleName)) {
this.start();
} else {
this.stop();
}
layouts.subscribe(() => {
const usedModules = getLayoutItems();
if (usedModules.includes(moduleName)) {
this.start();
} else {
this.stop();
}
});
}
/**
* Executes the polling function at the specified interval.
*
* @param intervalMs - The polling interval in milliseconds.
*/
private executePolling(intervalMs: number): void {
if (this.intervalInstance !== null) {
this.intervalInstance.cancel();
}
this.intervalInstance = interval(intervalMs, async () => {
if (this.isExecuting) {
return;
}
this.isExecuting = true;
try {
await this.pollingFunction();
} catch (error) {
console.error('Error during polling execution:', error);
} finally {
this.isExecuting = false;
}
});
}
}