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:
79
src/services/cli/commander/commands/appearance/index.ts
Normal file
79
src/services/cli/commander/commands/appearance/index.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { Command } from '../../types';
|
||||
import { setWallpaper } from 'src/services/cli/helpers/wallpaper';
|
||||
import { useTheme } from 'src/lib/theme/useTheme';
|
||||
import { BarLayouts } from 'src/lib/options/types';
|
||||
import { errorHandler } from 'src/core/errors/handler';
|
||||
import { setLayout } from 'src/lib/bar/helpers';
|
||||
|
||||
export const appearanceCommands: Command[] = [
|
||||
{
|
||||
name: 'setWallpaper',
|
||||
aliases: ['sw'],
|
||||
description: 'Sets the wallpaper based on the provided input.',
|
||||
category: 'Appearance',
|
||||
args: [
|
||||
{
|
||||
name: 'path',
|
||||
description: 'Path to the wallpaper image.',
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
handler: (args: Record<string, unknown>): string => {
|
||||
try {
|
||||
setWallpaper(args['path'] as string);
|
||||
return 'Wallpaper set successfully.';
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
return `Error setting wallpaper: ${error.message}`;
|
||||
}
|
||||
return `Error setting wallpaper: ${error}`;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'useTheme',
|
||||
aliases: ['ut'],
|
||||
description: 'Sets the theme based on the provided input.',
|
||||
category: 'Appearance',
|
||||
args: [
|
||||
{
|
||||
name: 'path',
|
||||
description: 'Path to the JSON file of the HyprPanel theme.',
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
handler: (args: Record<string, unknown>): string => {
|
||||
try {
|
||||
useTheme(args['path'] as string);
|
||||
return 'Theme set successfully.';
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'setLayout',
|
||||
aliases: ['slo'],
|
||||
description: 'Sets the layout of the modules on the bar.',
|
||||
category: 'Appearance',
|
||||
args: [
|
||||
{
|
||||
name: 'layout',
|
||||
description:
|
||||
'Bar layout to apply. Wiki: https://hyprpanel.com/configuration/panel.html#layouts',
|
||||
type: 'object',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
handler: (args: Record<string, unknown>): string => {
|
||||
try {
|
||||
setLayout(args['layout'] as BarLayouts);
|
||||
return 'Layout applied successfully.';
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
26
src/services/cli/commander/commands/modules/media/index.ts
Normal file
26
src/services/cli/commander/commands/modules/media/index.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { errorHandler } from 'src/core/errors/handler';
|
||||
import { Command } from '../../../types';
|
||||
import { MediaPlayerService } from 'src/services/media';
|
||||
|
||||
const mediaPlayerService = MediaPlayerService.getInstance();
|
||||
|
||||
export const mediaCommands: Command[] = [
|
||||
{
|
||||
name: 'Play/Pause active media player',
|
||||
aliases: ['pp'],
|
||||
description: 'Plays or Pauses the active media player.',
|
||||
category: 'Media',
|
||||
args: [],
|
||||
handler: (): string => {
|
||||
try {
|
||||
mediaPlayerService.activePlayer.get()?.play_pause();
|
||||
|
||||
const playbackStatus = mediaPlayerService.activePlayer.get()?.playback_status;
|
||||
|
||||
return playbackStatus === 0 ? 'Paused' : 'Playing';
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
257
src/services/cli/commander/commands/system/checkDependencies.ts
Normal file
257
src/services/cli/commander/commands/system/checkDependencies.ts
Normal file
@@ -0,0 +1,257 @@
|
||||
import { errorHandler } from 'src/core/errors/handler';
|
||||
import { SystemUtilities } from 'src/core/system/SystemUtilities';
|
||||
import { ServiceStatus } from 'src/core/system/types';
|
||||
|
||||
const RED = '\x1b[31m';
|
||||
const GREEN = '\x1b[32m';
|
||||
const YELLOW = '\x1b[33m';
|
||||
const RESET = '\x1b[0m';
|
||||
const BOLD = '\x1b[1m';
|
||||
|
||||
const STATUS_INSTALLED = '(INSTALLED)';
|
||||
const STATUS_ACTIVE = '(ACTIVE)';
|
||||
const STATUS_DISABLED = '(DISABLED)';
|
||||
const STATUS_MISSING = '(MISSING)';
|
||||
|
||||
/**
|
||||
* Colors a given text using ANSI color codes.
|
||||
*
|
||||
* @description Wraps the provided text with ANSI color codes.
|
||||
*
|
||||
* @param text - The text to color.
|
||||
* @param color - The ANSI color code to use.
|
||||
*/
|
||||
function colorText(text: string, color: string): string {
|
||||
return `${color}${text}${RESET}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the status string and color for a dependency based on its type and checks.
|
||||
*
|
||||
* @description Returns the formatted line indicating the status of the given dependency.
|
||||
*
|
||||
* @param dep - The dependency to check.
|
||||
*/
|
||||
function getDependencyStatus(dep: Dependency): string {
|
||||
let status: ServiceStatus | 'INSTALLED' | 'MISSING';
|
||||
|
||||
switch (dep.type) {
|
||||
case 'executable':
|
||||
status = SystemUtilities.checkExecutable(dep.check) ? 'INSTALLED' : 'MISSING';
|
||||
break;
|
||||
case 'library':
|
||||
status = SystemUtilities.checkLibrary(dep.check) ? 'INSTALLED' : 'MISSING';
|
||||
break;
|
||||
case 'service':
|
||||
status = SystemUtilities.checkServiceStatus(dep.check);
|
||||
break;
|
||||
default:
|
||||
status = 'MISSING';
|
||||
}
|
||||
|
||||
let color: string;
|
||||
let textStatus: string;
|
||||
|
||||
switch (status) {
|
||||
case 'ACTIVE':
|
||||
textStatus = STATUS_ACTIVE;
|
||||
color = GREEN;
|
||||
break;
|
||||
case 'INSTALLED':
|
||||
textStatus = STATUS_INSTALLED;
|
||||
color = GREEN;
|
||||
break;
|
||||
case 'DISABLED':
|
||||
textStatus = STATUS_DISABLED;
|
||||
color = YELLOW;
|
||||
break;
|
||||
case 'MISSING':
|
||||
default:
|
||||
textStatus = STATUS_MISSING;
|
||||
color = RED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dep.description === undefined) {
|
||||
return ` ${colorText(textStatus, color)} ${dep.package}`;
|
||||
}
|
||||
|
||||
return ` ${colorText(textStatus, color)} ${dep.package}: ${dep.description ?? ''}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks all dependencies and returns a formatted output.
|
||||
*
|
||||
* @description Gathers the status of both required and optional dependencies and formats the result.
|
||||
*/
|
||||
export function checkDependencies(): string {
|
||||
try {
|
||||
const dependencies: Dependency[] = [
|
||||
{
|
||||
package: 'wireplumber',
|
||||
required: true,
|
||||
type: 'executable',
|
||||
check: ['wireplumber'],
|
||||
},
|
||||
{
|
||||
package: 'libgtop',
|
||||
required: true,
|
||||
type: 'library',
|
||||
check: ['gtop-2.0'],
|
||||
},
|
||||
{
|
||||
package: 'bluez',
|
||||
required: true,
|
||||
type: 'service',
|
||||
check: ['bluetooth.service'],
|
||||
},
|
||||
{
|
||||
package: 'bluez-utils',
|
||||
required: true,
|
||||
type: 'executable',
|
||||
check: ['bluetoothctl'],
|
||||
},
|
||||
{
|
||||
package: 'networkmanager',
|
||||
required: true,
|
||||
type: 'service',
|
||||
check: ['NetworkManager.service'],
|
||||
},
|
||||
{
|
||||
package: 'dart-sass',
|
||||
required: true,
|
||||
type: 'executable',
|
||||
check: ['sass'],
|
||||
},
|
||||
{
|
||||
package: 'wl-clipboard',
|
||||
required: true,
|
||||
type: 'executable',
|
||||
check: ['wl-copy', 'wl-paste'],
|
||||
},
|
||||
{
|
||||
package: 'upower',
|
||||
required: true,
|
||||
type: 'service',
|
||||
check: ['upower.service'],
|
||||
},
|
||||
{
|
||||
package: 'aylurs-gtk-shell',
|
||||
required: true,
|
||||
type: 'executable',
|
||||
check: ['ags'],
|
||||
},
|
||||
|
||||
{
|
||||
package: 'python',
|
||||
required: false,
|
||||
type: 'executable',
|
||||
check: ['python', 'python3'],
|
||||
description: 'GPU usage tracking (NVidia only)',
|
||||
},
|
||||
{
|
||||
package: 'python-gpustat',
|
||||
required: false,
|
||||
type: 'executable',
|
||||
check: ['gpustat'],
|
||||
description: 'GPU usage tracking (NVidia only)',
|
||||
},
|
||||
{
|
||||
package: 'pywal',
|
||||
required: false,
|
||||
type: 'executable',
|
||||
check: ['wal'],
|
||||
description: 'Pywal hook for wallpapers',
|
||||
},
|
||||
{
|
||||
package: 'pacman-contrib',
|
||||
required: false,
|
||||
type: 'executable',
|
||||
check: ['paccache', 'rankmirrors'],
|
||||
description: 'Checking for pacman updates',
|
||||
},
|
||||
{
|
||||
package: 'power-profiles-daemon',
|
||||
required: false,
|
||||
type: 'service',
|
||||
check: ['power-profiles-daemon.service'],
|
||||
description: 'Switch power profiles',
|
||||
},
|
||||
{
|
||||
package: 'swww',
|
||||
required: false,
|
||||
type: 'executable',
|
||||
check: ['swww'],
|
||||
description: 'Setting wallpapers',
|
||||
},
|
||||
{
|
||||
package: 'grimblast',
|
||||
required: false,
|
||||
type: 'executable',
|
||||
check: ['grimblast'],
|
||||
description: 'For the snapshot shortcut',
|
||||
},
|
||||
{
|
||||
package: 'brightnessctl',
|
||||
required: false,
|
||||
type: 'executable',
|
||||
check: ['brightnessctl'],
|
||||
description: 'To control keyboard and screen brightness',
|
||||
},
|
||||
{
|
||||
package: 'btop',
|
||||
required: false,
|
||||
type: 'executable',
|
||||
check: ['btop'],
|
||||
description: 'To view system resource usage',
|
||||
},
|
||||
{
|
||||
package: 'wf-recorder',
|
||||
required: false,
|
||||
type: 'executable',
|
||||
check: ['wf-recorder'],
|
||||
description: 'To use the built-in screen recorder',
|
||||
},
|
||||
{
|
||||
package: 'hyprpicker',
|
||||
required: false,
|
||||
type: 'executable',
|
||||
check: ['hyprpicker'],
|
||||
description: 'To use the preset color picker shortcut',
|
||||
},
|
||||
{
|
||||
package: 'matugen',
|
||||
required: false,
|
||||
type: 'executable',
|
||||
check: ['matugen'],
|
||||
description: 'To use wallpaper-based color schemes',
|
||||
},
|
||||
];
|
||||
|
||||
let output = `${BOLD}Required Dependencies:${RESET}\n`;
|
||||
|
||||
for (const dep of dependencies.filter((d) => d.required)) {
|
||||
output += getDependencyStatus(dep) + '\n';
|
||||
}
|
||||
|
||||
output += `\n${BOLD}Optional Dependencies:${RESET}\n`;
|
||||
|
||||
for (const dep of dependencies.filter((d) => !d.required)) {
|
||||
output += getDependencyStatus(dep) + '\n';
|
||||
}
|
||||
|
||||
return output;
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
type DependencyType = 'executable' | 'library' | 'service';
|
||||
|
||||
type Dependency = {
|
||||
package: string;
|
||||
required: boolean;
|
||||
type: DependencyType;
|
||||
check: string[];
|
||||
description?: string;
|
||||
};
|
||||
221
src/services/cli/commander/commands/system/index.ts
Normal file
221
src/services/cli/commander/commands/system/index.ts
Normal file
@@ -0,0 +1,221 @@
|
||||
import AstalNotifd from 'gi://AstalNotifd?version=0.1';
|
||||
import AstalWp from 'gi://AstalWp?version=0.1';
|
||||
import { Command } from '../../types';
|
||||
import { execAsync, Gio, GLib } from 'astal';
|
||||
import { checkDependencies } from './checkDependencies';
|
||||
import { getSystrayItems } from 'src/services/cli/helpers/systray';
|
||||
import { idleInhibit } from 'src/lib/window/visibility';
|
||||
import { errorHandler } from 'src/core/errors/handler';
|
||||
import { clearNotifications } from 'src/lib/shared/notifications';
|
||||
import options from 'src/configuration';
|
||||
import { listCpuTempSensors } from './listSensors';
|
||||
|
||||
const { clearDelay } = options.notifications;
|
||||
const notifdService = AstalNotifd.get_default();
|
||||
const audio = AstalWp.get_default();
|
||||
|
||||
export const utilityCommands: Command[] = [
|
||||
{
|
||||
name: 'systrayItems',
|
||||
aliases: ['sti'],
|
||||
description: 'Gets a list of IDs for the current applications in the system tray.',
|
||||
category: 'System',
|
||||
args: [],
|
||||
handler: (): string => {
|
||||
try {
|
||||
return getSystrayItems() ?? 'No items found!';
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'clearNotifications',
|
||||
aliases: ['cno'],
|
||||
description: 'Clears all of the notifications that currently exist.',
|
||||
category: 'System',
|
||||
args: [],
|
||||
handler: (): string => {
|
||||
try {
|
||||
const allNotifications = notifdService.get_notifications();
|
||||
clearNotifications(allNotifications, clearDelay.get());
|
||||
|
||||
return 'Notifications cleared successfully.';
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'toggleDnd',
|
||||
aliases: ['dnd'],
|
||||
description: 'Toggled the Do Not Disturb mode for notifications.',
|
||||
category: 'System',
|
||||
args: [],
|
||||
handler: (): string => {
|
||||
try {
|
||||
notifdService.set_dont_disturb(!notifdService.dontDisturb);
|
||||
|
||||
return notifdService.dontDisturb ? 'Enabled' : 'Disabled';
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'adjustVolume',
|
||||
aliases: ['vol'],
|
||||
description: 'Adjusts the volume of the default audio output device.',
|
||||
category: 'System',
|
||||
args: [
|
||||
{
|
||||
name: 'volume',
|
||||
description: 'A positive or negative number to adjust the volume by.',
|
||||
type: 'number',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
handler: (args: Record<string, unknown>): number => {
|
||||
try {
|
||||
const speaker = audio?.defaultSpeaker;
|
||||
|
||||
if (speaker === undefined) {
|
||||
throw new Error('A default speaker was not found.');
|
||||
}
|
||||
|
||||
const volumeInput = Number(args['volume']) / 100;
|
||||
|
||||
if (options.menus.volume.raiseMaximumVolume.get()) {
|
||||
speaker.set_volume(Math.min(speaker.volume + volumeInput, 1.5));
|
||||
} else {
|
||||
speaker.set_volume(Math.min(speaker.volume + volumeInput, 1));
|
||||
}
|
||||
|
||||
return Math.round((speaker.volume + volumeInput) * 100);
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'isInhibiting',
|
||||
aliases: ['isi'],
|
||||
description: 'Returns the status of the Idle Inhibitor.',
|
||||
category: 'System',
|
||||
args: [],
|
||||
handler: (): boolean => {
|
||||
try {
|
||||
return idleInhibit.get();
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'idleInhibit',
|
||||
aliases: ['idi'],
|
||||
description:
|
||||
'Enables/Disables the Idle Inhibitor. Toggles the Inhibitor if no parameter is provided.',
|
||||
category: 'System',
|
||||
args: [
|
||||
{
|
||||
name: 'shouldInhibit',
|
||||
description: 'The boolean value that enables/disables the inhibitor.',
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
handler: (args: Record<string, unknown>): boolean => {
|
||||
try {
|
||||
const shouldInhibit = args['shouldInhibit'] ?? idleInhibit.get() === false;
|
||||
idleInhibit.set(Boolean(shouldInhibit));
|
||||
|
||||
return idleInhibit.get();
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'migrateConfig',
|
||||
aliases: ['mcfg'],
|
||||
description: 'Migrates the configuration file from the old location to the new one.',
|
||||
category: 'System',
|
||||
args: [],
|
||||
handler: (): string => {
|
||||
const oldPath = `${GLib.get_user_cache_dir()}/ags/hyprpanel/options.json`;
|
||||
|
||||
try {
|
||||
const oldFile = Gio.File.new_for_path(oldPath);
|
||||
const newFile = Gio.File.new_for_path(CONFIG_FILE);
|
||||
|
||||
if (oldFile.query_exists(null)) {
|
||||
oldFile.move(newFile, Gio.FileCopyFlags.OVERWRITE, null, null);
|
||||
return `Configuration file moved to ${CONFIG_FILE}`;
|
||||
} else {
|
||||
return `Old configuration file does not exist at ${oldPath}`;
|
||||
}
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'checkDependencies',
|
||||
aliases: ['chd'],
|
||||
description: 'Checks the status of required and optional dependencies.',
|
||||
category: 'System',
|
||||
args: [],
|
||||
handler: (): string => {
|
||||
try {
|
||||
return checkDependencies();
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'listCpuSensors',
|
||||
aliases: ['lcs'],
|
||||
description: 'Lists all available CPU temperature sensors and shows the current one.',
|
||||
category: 'System',
|
||||
args: [],
|
||||
handler: (): string => {
|
||||
try {
|
||||
return listCpuTempSensors();
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'restart',
|
||||
aliases: ['r'],
|
||||
description: 'Restarts HyprPanel.',
|
||||
category: 'System',
|
||||
args: [],
|
||||
handler: (): string => {
|
||||
try {
|
||||
execAsync('bash -c "hyprpanel -q; hyprpanel"');
|
||||
return '';
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'quit',
|
||||
aliases: ['q'],
|
||||
description: 'Quits HyprPanel.',
|
||||
category: 'System',
|
||||
args: [],
|
||||
handler: (): string => {
|
||||
try {
|
||||
execAsync('bash -c "hyprpanel -q"');
|
||||
return '';
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
34
src/services/cli/commander/commands/system/listSensors.ts
Normal file
34
src/services/cli/commander/commands/system/listSensors.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { CpuTempSensorDiscovery } from 'src/services/system/cputemp/sensorDiscovery';
|
||||
import CpuTempService from 'src/services/system/cputemp';
|
||||
|
||||
/**
|
||||
* Lists all available CPU temperature sensors and shows which one is currently active
|
||||
*/
|
||||
export function listCpuTempSensors(): string {
|
||||
const sensors = CpuTempSensorDiscovery.getAllSensors();
|
||||
const cpuTempService = new CpuTempService();
|
||||
cpuTempService.initialize();
|
||||
|
||||
const currentSensor = cpuTempService.currentSensorPath;
|
||||
|
||||
let outputMessage = '';
|
||||
outputMessage += 'Available CPU Temperature Sensors:\n';
|
||||
outputMessage += '==================================\n';
|
||||
|
||||
if (sensors.length === 0) {
|
||||
outputMessage += 'No temperature sensors found on the system.\n';
|
||||
return outputMessage;
|
||||
}
|
||||
|
||||
for (const sensor of sensors) {
|
||||
const isCurrent = sensor.path === currentSensor;
|
||||
const marker = isCurrent ? ' [CURRENT]' : '';
|
||||
outputMessage += `${sensor.type.padEnd(8)} | ${sensor.name.padEnd(20)} | ${sensor.path}${marker}\n`;
|
||||
}
|
||||
|
||||
outputMessage += `Auto-discovered sensor: ${CpuTempSensorDiscovery.discover() || 'None'}\n`;
|
||||
|
||||
cpuTempService.destroy();
|
||||
|
||||
return outputMessage;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import { Command } from '../../types';
|
||||
import { App } from 'astal/gtk3';
|
||||
import { isWindowVisible } from 'src/lib/window/visibility';
|
||||
import { BarVisibility } from 'src/services/display/bar';
|
||||
import { errorHandler } from 'src/core/errors/handler';
|
||||
|
||||
export const windowManagementCommands: Command[] = [
|
||||
{
|
||||
name: 'isWindowVisible',
|
||||
aliases: ['iwv'],
|
||||
description: 'Checks if a specified window is visible.',
|
||||
category: 'Window Management',
|
||||
args: [
|
||||
{
|
||||
name: 'window',
|
||||
description: 'Name of the window to check.',
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
handler: (args: Record<string, unknown>): boolean => {
|
||||
return isWindowVisible(args['window'] as string);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'toggleWindow',
|
||||
aliases: ['t'],
|
||||
description: 'Toggles the visibility of a specified window.',
|
||||
category: 'Window Management',
|
||||
args: [
|
||||
{
|
||||
name: 'window',
|
||||
description: 'The name of the window to toggle.',
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
handler: (args: Record<string, unknown>): string => {
|
||||
try {
|
||||
const windowName = args['window'] as string;
|
||||
const foundWindow = App.get_window(windowName);
|
||||
|
||||
if (!foundWindow) {
|
||||
throw new Error(`Window ${args['window']} not found.`);
|
||||
}
|
||||
|
||||
const windowStatus = foundWindow.visible ? 'hidden' : 'visible';
|
||||
|
||||
App.toggle_window(windowName);
|
||||
|
||||
BarVisibility.set(windowName, windowStatus === 'visible');
|
||||
|
||||
return windowStatus;
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'listWindows',
|
||||
aliases: ['lw'],
|
||||
description: 'Gets a list of all HyprPanel windows.',
|
||||
category: 'Window Management',
|
||||
args: [],
|
||||
handler: (): string => {
|
||||
try {
|
||||
const windowList = App.get_windows().map((window) => window.name);
|
||||
return windowList.join('\n');
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
Reference in New Issue
Block a user