Fix: An issue that would cause Matugen colors to not apply. (#929)

* Eslint updates

* linter fixes

* Type fixes

* More type fixes

* Fix isvis

* More type fixes

* Type Fixes

* Consolidate logic to manage options

* Linter fixes

* Package lock update

* Update configs

* Version checker

* Debug pipeline

* Package lock update

* Update ci

* Strict check

* Revert ci

* Eslint

* Remove rule since it causes issues in CI

* Actual matugen fix
This commit is contained in:
Jas Singh
2025-05-11 23:01:55 -07:00
committed by GitHub
parent 0c82ce9704
commit 2bb1449fb6
275 changed files with 4363 additions and 2505 deletions

View File

@@ -7,7 +7,7 @@ const audioService = wireplumber.audio;
const ActiveDeviceContainer = ({ children }: ActiveDeviceContainerProps): JSX.Element => {
return (
<box className={'menu-items-section selected'} name={ActiveDeviceMenu.Devices} vertical>
<box className={'menu-items-section selected'} name={ActiveDeviceMenu.DEVICES} vertical>
{children}
</box>
);

View File

@@ -5,11 +5,11 @@ import { bind, Variable } from 'astal';
import { isPrimaryClick } from 'src/lib/utils.js';
export enum ActiveDeviceMenu {
Devices = 'devices',
Playbacks = 'playbacks',
DEVICES = 'devices',
PLAYBACKS = 'playbacks',
}
const activeMenu: Variable<ActiveDeviceMenu> = Variable(ActiveDeviceMenu.Devices);
const activeMenu: Variable<ActiveDeviceMenu> = Variable(ActiveDeviceMenu.DEVICES);
const Header = (): JSX.Element => (
<box className={'menu-label-container volume selected'} halign={Gtk.Align.FILL}>
@@ -21,15 +21,15 @@ const Header = (): JSX.Element => (
return;
}
if (activeMenu.get() === ActiveDeviceMenu.Devices) {
activeMenu.set(ActiveDeviceMenu.Playbacks);
if (activeMenu.get() === ActiveDeviceMenu.DEVICES) {
activeMenu.set(ActiveDeviceMenu.PLAYBACKS);
} else {
activeMenu.set(ActiveDeviceMenu.Devices);
activeMenu.set(ActiveDeviceMenu.DEVICES);
}
}}
halign={Gtk.Align.END}
hexpand
label={bind(activeMenu).as((menu) => (menu === ActiveDeviceMenu.Devices ? '' : '󰤽'))}
label={bind(activeMenu).as((menu) => (menu === ActiveDeviceMenu.DEVICES ? '' : '󰤽'))}
/>
</box>
);
@@ -40,13 +40,13 @@ export const VolumeSliders = (): JSX.Element => {
<Header />
<revealer
transitionType={Gtk.RevealerTransitionType.NONE}
revealChild={bind(activeMenu).as((curMenu) => curMenu === ActiveDeviceMenu.Devices)}
revealChild={bind(activeMenu).as((curMenu) => curMenu === ActiveDeviceMenu.DEVICES)}
>
<ActiveDevices />
</revealer>
<revealer
transitionType={Gtk.RevealerTransitionType.NONE}
revealChild={bind(activeMenu).as((curMenu) => curMenu === ActiveDeviceMenu.Playbacks)}
revealChild={bind(activeMenu).as((curMenu) => curMenu === ActiveDeviceMenu.PLAYBACKS)}
>
<ActivePlaybacks />
</revealer>

View File

@@ -12,11 +12,11 @@ const NoStreams = (): JSX.Element => {
export const ActivePlaybacks = (): JSX.Element => {
return (
<box className={'menu-items-section selected'} name={ActiveDeviceMenu.Playbacks} vertical>
<box className={'menu-items-section selected'} name={ActiveDeviceMenu.PLAYBACKS} vertical>
<scrollable className={'menu-scroller active-playbacks-scrollable'}>
<box vertical>
{bind(audioService, 'streams').as((streams) => {
if (!streams || streams.length === 0) {
if (streams === null || streams.length === 0) {
return <NoStreams />;
}

View File

@@ -28,8 +28,8 @@ export const Slider = ({ device, type }: SliderProps): JSX.Element => {
max={type === 'playback' ? bind(raiseMaximumVolume).as((raise) => (raise ? 1.5 : 1)) : 1}
onDragged={({ value, dragging }) => {
if (dragging) {
device.volume = value;
device.mute = false;
device.set_volume(value);
device.set_mute(false);
}
}}
setup={(self) => {

View File

@@ -16,12 +16,14 @@ export const SliderIcon = ({ type, device }: SliderIconProps): JSX.Element => {
return (
<button
className={bind(device, 'mute').as((isMuted) => `menu-active-button ${type} ${isMuted ? 'muted' : ''}`)}
className={bind(device, 'mute').as(
(isMuted) => `menu-active-button ${type} ${isMuted ? 'muted' : ''}`,
)}
vexpand={false}
valign={Gtk.Align.END}
onClick={(_, event) => {
if (isPrimaryClick(event)) {
device.mute = !device.mute;
device.set_mute(!device.mute);
}
}}
onDestroy={() => {

View File

@@ -20,7 +20,9 @@ const DeviceName = ({ device, type }: Omit<AudioDeviceProps, 'icon'>): JSX.Eleme
truncate
wrap
className={bind(device, 'description').as((currentDesc) =>
device.description === currentDesc ? `menu-button-name active ${type}` : `menu-button-name ${type}`,
device.description === currentDesc
? `menu-button-name active ${type}`
: `menu-button-name ${type}`,
)}
label={device.description}
/>

View File

@@ -13,7 +13,7 @@ export const InputDevices = (): JSX.Element => {
<box className={'menu-items-section input'} vertical>
<box className={'menu-container input'} vertical>
{inputDevices.as((devices) => {
if (!devices || devices.length === 0) {
if (devices === null || devices.length === 0) {
return <NotFoundButton type={'input'} />;
}

View File

@@ -13,7 +13,7 @@ export const PlaybackDevices = (): JSX.Element => {
<box className={'menu-items-section playback'} vertical>
<box className={'menu-container playback'} vertical>
{playbackDevices.as((devices) => {
if (!devices || devices.length === 0) {
if (devices === null || devices.length === 0) {
return <NotFoundButton type={'playback'} />;
}

View File

@@ -29,7 +29,7 @@ type IconVolumes = keyof typeof speakerIcons;
*/
const getIcon = (audioVol: number, isMuted: boolean): Record<string, string> => {
const thresholds: IconVolumes[] = [101, 66, 34, 1, 0];
const icon = isMuted ? 0 : thresholds.find((threshold) => threshold <= audioVol * 100) || 0;
const icon = isMuted ? 0 : (thresholds.find((threshold) => threshold <= audioVol * 100) ?? 0);
return {
spkr: speakerIcons[icon],

View File

@@ -2,7 +2,13 @@ import { Gtk } from 'astal/gtk3';
export const BluetoothDisabled = (): JSX.Element => {
return (
<box className={'bluetooth-items'} vertical expand valign={Gtk.Align.CENTER} halign={Gtk.Align.CENTER}>
<box
className={'bluetooth-items'}
vertical
expand
valign={Gtk.Align.CENTER}
halign={Gtk.Align.CENTER}
>
<label className={'bluetooth-disabled dim'} hexpand label={'Bluetooth is disabled'} />
</box>
);

View File

@@ -2,7 +2,13 @@ import { Gtk } from 'astal/gtk3';
export const NoBluetoothDevices = (): JSX.Element => {
return (
<box className={'bluetooth-items'} vertical expand valign={Gtk.Align.CENTER} halign={Gtk.Align.CENTER}>
<box
className={'bluetooth-items'}
vertical
expand
valign={Gtk.Align.CENTER}
halign={Gtk.Align.CENTER}
>
<label className={'no-bluetooth-devices dim'} hexpand label={'No devices currently found'} />
<label className={'search-bluetooth-label dim'} hexpand label={"Press '󰑐' to search"} />
</box>

View File

@@ -1,7 +1,12 @@
import { Binding } from 'astal';
import { ButtonProps } from 'astal/gtk3/widget';
export const ActionButton = ({ name = '', tooltipText = '', label = '', ...props }: ActionButtonProps): JSX.Element => {
export const ActionButton = ({
name = '',
tooltipText = '',
label = '',
...props
}: ActionButtonProps): JSX.Element => {
return (
<button className={`menu-icon-button ${name} bluetooth`} {...props}>
<label

View File

@@ -41,7 +41,9 @@ export const getAvailableBluetoothDevices = (): AstalBluetooth.Device[] => {
*/
export const getConnectedBluetoothDevices = (): string[] => {
const availableDevices = getAvailableBluetoothDevices();
const connectedDeviceNames = availableDevices.filter((d) => d.connected || d.paired).map((d) => d.address);
const connectedDeviceNames = availableDevices
.filter((d) => d.connected || d.paired)
.map((d) => d.address);
return connectedDeviceNames;
};

View File

@@ -10,7 +10,7 @@ Variable.derive([bind(bluetoothService, 'adapter')], () => {
discoveringBinding?.drop();
discoveringBinding = undefined;
if (!bluetoothService.adapter) {
if (bluetoothService.adapter === null) {
return;
}

View File

@@ -3,7 +3,14 @@ import { Controls } from './Controls';
export const Header = (): JSX.Element => {
const MenuLabel = (): JSX.Element => {
return <label className="menu-label" valign={Gtk.Align.CENTER} halign={Gtk.Align.START} label="Bluetooth" />;
return (
<label
className="menu-label"
valign={Gtk.Align.CENTER}
halign={Gtk.Align.START}
label="Bluetooth"
/>
);
};
return (

View File

@@ -3,7 +3,12 @@ import Calendar from 'src/components/shared/Calendar';
export const CalendarWidget = (): JSX.Element => {
return (
<box className={'calendar-menu-item-container calendar'} halign={Gtk.Align.FILL} valign={Gtk.Align.FILL} expand>
<box
className={'calendar-menu-item-container calendar'}
halign={Gtk.Align.FILL}
valign={Gtk.Align.FILL}
expand
>
<box className={'calendar-container-box'}>
<Calendar
className={'calendar-menu-widget'}

View File

@@ -1,7 +1,7 @@
import options from 'src/options';
import { bind, Variable } from 'astal';
import { Gtk } from 'astal/gtk3';
import { systemTime } from 'src/globals/time';
import { systemTime } from 'src/shared/time';
const { military, hideSeconds } = options.menus.clock.time;
@@ -16,7 +16,7 @@ export const MilitaryTime = (): JSX.Element => {
<label
className={'clock-content-time'}
label={bind(systemTime).as((time) => {
return time?.format(hideSeconds ? '%H:%M' : '%H:%M:%S') || '';
return time?.format(hideSeconds ? '%H:%M' : '%H:%M:%S') ?? '';
})}
/>
</box>

View File

@@ -1,11 +1,11 @@
import options from 'src/options';
import { bind, GLib, Variable } from 'astal';
import { Gtk } from 'astal/gtk3';
import { systemTime } from 'src/globals/time';
import { systemTime } from 'src/shared/time';
const { military, hideSeconds } = options.menus.clock.time;
const period = Variable('').poll(1000, (): string => GLib.DateTime.new_now_local().format('%p') || '');
const period = Variable('').poll(1000, (): string => GLib.DateTime.new_now_local().format('%p') ?? '');
export const StandardTime = (): JSX.Element => {
const CurrentTime = ({ hideSeconds }: CurrentTimeProps): JSX.Element => {
@@ -14,7 +14,7 @@ export const StandardTime = (): JSX.Element => {
<label
className={'clock-content-time'}
label={bind(systemTime).as((time) => {
return time?.format(hideSeconds ? '%I:%M' : '%I:%M:%S') || '';
return time?.format(hideSeconds ? '%I:%M' : '%I:%M:%S') ?? '';
})}
/>
</box>

View File

@@ -4,8 +4,18 @@ import { StandardTime } from './StandardTime';
export const TimeWidget = (): JSX.Element => {
return (
<box className={'calendar-menu-item-container clock'} valign={Gtk.Align.CENTER} halign={Gtk.Align.FILL} hexpand>
<box className={'clock-content-items'} valign={Gtk.Align.CENTER} halign={Gtk.Align.CENTER} hexpand>
<box
className={'calendar-menu-item-container clock'}
valign={Gtk.Align.CENTER}
halign={Gtk.Align.FILL}
hexpand
>
<box
className={'clock-content-items'}
valign={Gtk.Align.CENTER}
halign={Gtk.Align.CENTER}
hexpand
>
<StandardTime />
<MilitaryTime />
</box>

View File

@@ -1,5 +1,5 @@
import { isValidWeatherIconTitle } from 'src/globals/weather';
import { Weather, WeatherIconTitle } from 'src/lib/types/weather';
import { Weather, WeatherIconTitle } from 'src/lib/types/weather.types';
import { isValidWeatherIconTitle } from 'src/shared/weather';
/**
* Retrieves the next epoch time for weather data.

View File

@@ -1,5 +1,5 @@
import { bind } from 'astal';
import { globalWeatherVar } from 'src/globals/weather';
import { globalWeatherVar } from 'src/shared/weather';
import { Gtk } from 'astal/gtk3';
import { weatherIcons } from 'src/lib/icons/weather.js';
import { getIconQuery } from '../helpers';

View File

@@ -1,5 +1,5 @@
import options from 'src/options';
import { globalWeatherVar } from 'src/globals/weather';
import { globalWeatherVar } from 'src/shared/weather';
import { getNextEpoch } from '../helpers';
import { bind, Variable } from 'astal';

View File

@@ -1,4 +1,4 @@
import { globalWeatherVar } from 'src/globals/weather';
import { globalWeatherVar } from 'src/shared/weather';
import { getNextEpoch } from '../helpers';
import { bind } from 'astal';

View File

@@ -1,6 +1,6 @@
import { bind } from 'astal';
import { Gtk } from 'astal/gtk3';
import { getWeatherStatusTextIcon } from 'src/globals/weather.js';
import { getWeatherStatusTextIcon, globalWeatherVar } from 'src/shared/weather';
export const TodayIcon = (): JSX.Element => {
return (
@@ -11,7 +11,7 @@ export const TodayIcon = (): JSX.Element => {
>
<label
className={'calendar-menu-weather today icon txt-icon'}
label={bind(globalWeatherVar).as(getWeatherStatusTextIcon)}
label={bind(globalWeatherVar).as((weather) => getWeatherStatusTextIcon(weather))}
/>
</box>
);

View File

@@ -1,6 +1,6 @@
import { getTemperature, globalWeatherVar } from 'src/globals/weather';
import { getTemperature, globalWeatherVar } from 'src/shared/weather';
import options from 'src/options';
import { getRainChance } from 'src/globals/weather';
import { getRainChance } from 'src/shared/weather';
import { Gtk } from 'astal/gtk3';
import { bind, Variable } from 'astal';

View File

@@ -1,6 +1,6 @@
import options from 'src/options';
import { globalWeatherVar } from 'src/globals/weather';
import { getTemperature, getWeatherIcon } from 'src/globals/weather';
import { globalWeatherVar } from 'src/shared/weather';
import { getTemperature, getWeatherIcon } from 'src/shared/weather';
import { Gtk } from 'astal/gtk3';
import { bind, Variable } from 'astal';
const { unit } = options.menus.clock.weather;
@@ -35,7 +35,9 @@ const Temperature = (): JSX.Element => {
(weather) =>
`calendar-menu-weather today temp label icon txt-icon ${getWeatherIcon(Math.ceil(weather.current.temp_f)).color}`,
)}
label={bind(globalWeatherVar).as((weather) => getWeatherIcon(Math.ceil(weather.current.temp_f)).icon)}
label={bind(globalWeatherVar).as(
(weather) => getWeatherIcon(Math.ceil(weather.current.temp_f)).icon,
)}
/>
);
};

View File

@@ -18,7 +18,9 @@ const notifdService = AstalNotifd.get_default();
export const WifiButton = (): JSX.Element => {
return (
<button
className={bind(isWifiEnabled).as((isEnabled) => `dashboard-button wifi ${!isEnabled ? 'disabled' : ''}`)}
className={bind(isWifiEnabled).as(
(isEnabled) => `dashboard-button wifi ${!isEnabled ? 'disabled' : ''}`,
)}
onClick={(_, event) => {
if (isPrimaryClick(event)) {
networkService.wifi?.set_enabled(!networkService.wifi.enabled);
@@ -27,7 +29,10 @@ export const WifiButton = (): JSX.Element => {
tooltipText={'Toggle Wifi'}
expand
>
<label className={'txt-icon'} label={bind(isWifiEnabled).as((isEnabled) => (isEnabled ? '󰤨' : '󰤭'))} />
<label
className={'txt-icon'}
label={bind(isWifiEnabled).as((isEnabled) => (isEnabled ? '󰤨' : '󰤭'))}
/>
</button>
);
};
@@ -68,7 +73,10 @@ export const NotificationsButton = (): JSX.Element => {
tooltipText={'Toggle Notifications'}
expand
>
<label className={'txt-icon'} label={bind(notifdService, 'dontDisturb').as((dnd) => (dnd ? '󰂛' : '󰂚'))} />
<label
className={'txt-icon'}
label={bind(notifdService, 'dontDisturb').as((dnd) => (dnd ? '󰂛' : '󰂚'))}
/>
</button>
);
};

View File

@@ -10,7 +10,7 @@ Variable.derive([bind(networkService, 'wifi')], () => {
wifiEnabledBinding?.drop();
wifiEnabledBinding = undefined;
if (!networkService.wifi) {
if (networkService.wifi === null) {
return;
}

View File

@@ -1,5 +1,11 @@
import { Gtk } from 'astal/gtk3';
import { BluetoothButton, MicrophoneButton, NotificationsButton, PlaybackButton, WifiButton } from './ControlButtons';
import {
BluetoothButton,
MicrophoneButton,
NotificationsButton,
PlaybackButton,
WifiButton,
} from './ControlButtons';
export const Controls = ({ isEnabled }: ControlsProps): JSX.Element => {
if (!isEnabled) {
@@ -7,7 +13,12 @@ export const Controls = ({ isEnabled }: ControlsProps): JSX.Element => {
}
return (
<box className={'dashboard-card controls-container'} halign={Gtk.Align.FILL} valign={Gtk.Align.FILL} expand>
<box
className={'dashboard-card controls-container'}
halign={Gtk.Align.FILL}
valign={Gtk.Align.FILL}
expand
>
<WifiButton />
<BluetoothButton />
<NotificationsButton />

View File

@@ -8,7 +8,12 @@ export const Directories = ({ isEnabled }: DirectoriesProps): JSX.Element => {
}
return (
<box className={'dashboard-card directories-container'} valign={Gtk.Align.FILL} halign={Gtk.Align.FILL} expand>
<box
className={'dashboard-card directories-container'}
valign={Gtk.Align.FILL}
halign={Gtk.Align.FILL}
expand
>
<LeftSection>
<LeftLink1 />
<LeftLink2 />

View File

@@ -1,6 +1,6 @@
import { PowerOptions } from 'src/lib/types/options';
import { isPrimaryClick } from 'src/lib/utils';
import { handleClick } from './helpers';
import { PowerOptions } from 'src/lib/options/options.types';
const PowerActionButton = (icon: string, tooltip: string, action: PowerOptions): JSX.Element => {
return (

View File

@@ -1,7 +1,9 @@
import { App } from 'astal/gtk3';
import powermenu from '../../power/helpers/actions.js';
import { PowerOptions } from 'src/lib/types/options.js';
import { execAsync } from 'astal';
import options from 'src/options';
import { PowerOptions } from 'src/lib/options/options.types.js';
const { confirmation, shutdown, logout, sleep, reboot } = options.menus.dashboard.powermenu;
/**
@@ -22,7 +24,9 @@ export const handleClick = (action: PowerOptions): void => {
App.get_window('dashboardmenu')?.set_visible(false);
if (!confirmation.get()) {
execAsync(actions[action]).catch((err) => console.error(`Failed to execute ${action} command. Error: ${err}`));
execAsync(actions[action]).catch((err) =>
console.error(`Failed to execute ${action} command. Error: ${err}`),
);
} else {
powermenu.action(action);
}

View File

@@ -15,7 +15,12 @@ const MonitorListDropdown = (): JSX.Element => {
});
return (
<Menu className={'dropdown recording'} halign={Gtk.Align.FILL} onDestroy={() => monitorBinding.drop()} hexpand>
<Menu
className={'dropdown recording'}
halign={Gtk.Align.FILL}
onDestroy={() => monitorBinding.drop()}
hexpand
>
{bind(monitorList).as((monitors) =>
monitors.map((monitor) => {
const sanitizedPath = getRecordingPath().replace(/"/g, '\\"');

View File

@@ -1,8 +1,8 @@
import { Widget } from 'astal/gtk3';
import { ShortcutVariable } from 'src/lib/types/dashboard';
import { isPrimaryClick } from 'src/lib/utils';
import { handleClick, hasCommand } from '../helpers';
import options from 'src/options';
import { ShortcutVariable } from 'src/lib/types/dashboard.types';
const { left, right } = options.menus.dashboard.shortcuts;
@@ -41,7 +41,7 @@ export const LeftShortcut2 = (): JSX.Element => {
return <box />;
}
return <ShortcutButton shortcut={left.shortcut2} className={`dashboard-button`} />;
return <ShortcutButton shortcut={left.shortcut2} className={'dashboard-button'} />;
};
export const LeftShortcut3 = (): JSX.Element => {
@@ -62,7 +62,7 @@ export const LeftShortcut4 = (): JSX.Element => {
return <box />;
}
return <ShortcutButton shortcut={left.shortcut4} className={`dashboard-button `} />;
return <ShortcutButton shortcut={left.shortcut4} className={'dashboard-button '} />;
};
export const RightShortcut1 = (): JSX.Element => {
@@ -70,7 +70,7 @@ export const RightShortcut1 = (): JSX.Element => {
return <box />;
}
return <ShortcutButton shortcut={right.shortcut1} className={`dashboard-button top-button paired`} />;
return <ShortcutButton shortcut={right.shortcut1} className={'dashboard-button top-button paired'} />;
};
export const RightShortcut3 = (): JSX.Element => {
@@ -78,7 +78,7 @@ export const RightShortcut3 = (): JSX.Element => {
return <box />;
}
return <ShortcutButton shortcut={right.shortcut3} className={`dashboard-button top-button paired`} />;
return <ShortcutButton shortcut={right.shortcut3} className={'dashboard-button top-button paired'} />;
};
interface ShortcutButtonProps extends Widget.ButtonProps {

View File

@@ -1,7 +1,7 @@
import { bind, execAsync, timeout, Variable } from 'astal';
import { App } from 'astal/gtk3';
import { BashPoller } from 'src/lib/poller/BashPoller';
import { ShortcutVariable } from 'src/lib/types/dashboard';
import { ShortcutVariable } from 'src/lib/types/dashboard.types';
import options from 'src/options';
const { left } = options.menus.dashboard.shortcuts;

View File

@@ -1,7 +1,7 @@
export const LeftColumn = ({ isVisible, children }: LeftColumnProps): JSX.Element => {
return (
<box className={`card-button-section-container ${isVisible ? 'visible' : ''}`}>
{isVisible ? (
<box className={`card-button-section-container ${isVisible === true ? 'visible' : ''}`}>
{isVisible === true ? (
<box vertical hexpand vexpand>
{children}
</box>
@@ -14,7 +14,7 @@ export const LeftColumn = ({ isVisible, children }: LeftColumnProps): JSX.Elemen
export const RightColumn = ({ children }: RightColumnProps): JSX.Element => {
return (
<box className={`card-button-section-container`}>
<box className={'card-button-section-container'}>
<box vertical hexpand vexpand>
{children}
</box>

View File

@@ -77,7 +77,9 @@ export const RightShortcuts = (): JSX.Element => {
<box>
{Variable.derive(rightBindings, () => {
return (
<box className={`container utilities dashboard-card ${!leftCardHidden.get() ? 'paired' : ''}`}>
<box
className={`container utilities dashboard-card ${!leftCardHidden.get() ? 'paired' : ''}`}
>
<LeftColumn isVisible={true}>
<RightShortcut1 />
<SettingsButton />

View File

@@ -71,7 +71,9 @@ export const RamStat = (): JSX.Element => {
icon={''}
stat={'ram'}
value={bind(ramService.ram).as((ramUsage) => ramUsage.percentage / 100)}
label={bind(ramService.ram).as((ramUsage) => `${renderResourceLabel('used/total', ramUsage, true)}`)}
label={bind(ramService.ram).as(
(ramUsage) => `${renderResourceLabel('used/total', ramUsage, true)}`,
)}
/>
);
};

View File

@@ -47,7 +47,12 @@ const monitorInterval = (cpuService: Cpu, ramService: Ram, storageService: Stora
* @param gpuService The GPU service instance.
* @param storageService The storage service instance.
*/
const monitorStatsEnabled = (cpuService: Cpu, ramService: Ram, gpuService: Gpu, storageService: Storage): void => {
const monitorStatsEnabled = (
cpuService: Cpu,
ramService: Ram,
gpuService: Gpu,
storageService: Storage,
): void => {
enabled.subscribe(() => {
if (!enabled.get()) {
ramService.stopPoller();
@@ -95,7 +100,12 @@ const monitorGpuTrackingEnabled = (gpuService: Gpu): void => {
* @param gpuService The GPU service instance.
* @param storageService The storage service instance.
*/
export const initializePollers = (cpuService: Cpu, ramService: Ram, gpuService: Gpu, storageService: Storage): void => {
export const initializePollers = (
cpuService: Cpu,
ramService: Ram,
gpuService: Gpu,
storageService: Storage,
): void => {
ramService.setShouldRound(true);
storageService.setShouldRound(true);

View File

@@ -3,6 +3,11 @@ import icons from 'src/lib/icons/icons';
export const BrightnessIcon = (): JSX.Element => {
return (
<icon className={'brightness-slider-icon'} valign={Gtk.Align.CENTER} icon={icons.brightness.screen} vexpand />
<icon
className={'brightness-slider-icon'}
valign={Gtk.Align.CENTER}
icon={icons.brightness.screen}
vexpand
/>
);
};

View File

@@ -2,7 +2,7 @@ import { bind } from 'astal';
import { Gtk } from 'astal/gtk3';
import AstalPowerProfiles from 'gi://AstalPowerProfiles?version=0.1';
import icons from 'src/lib/icons/icons';
import { ProfileType } from 'src/lib/types/powerprofiles';
import { ProfileType } from 'src/lib/types/powerprofiles.types';
import { isPrimaryClick } from 'src/lib/utils';
const powerProfilesService = AstalPowerProfiles.get_default();
@@ -18,7 +18,8 @@ export const PowerProfiles = (): JSX.Element => {
return (
<button
className={bind(powerProfilesService, 'activeProfile').as(
(active) => `power-profile-item ${active === powerProfile.profile ? 'active' : ''}`,
(active) =>
`power-profile-item ${active === powerProfile.profile ? 'active' : ''}`,
)}
onClick={(_, event) => {
if (isPrimaryClick(event)) {

View File

@@ -7,7 +7,13 @@ export const MediaContainer = ({ children }: MediaContainerProps): JSX.Element =
<box className="menu-items-container media" halign={Gtk.Align.FILL} hexpand>
<box className={'menu-section-container'}>
<box className={'menu-items-section'} vertical={false}>
<box className={'menu-content'} css={getBackground()} halign={Gtk.Align.FILL} hexpand vertical>
<box
className={'menu-content'}
css={getBackground()}
halign={Gtk.Align.FILL}
hexpand
vertical
>
{children}
</box>
</box>

View File

@@ -4,14 +4,15 @@ import { isPrimaryClick } from 'src/lib/utils';
import { bind } from 'astal';
import { isLoopActive, isShuffleActive, loopIconMap, loopTooltipMap } from './helpers';
import AstalMpris from 'gi://AstalMpris?version=0.1';
import { activePlayer, loopStatus, shuffleStatus } from 'src/globals/media';
import { activePlayer, loopStatus, shuffleStatus } from 'src/shared/media';
export type LoopStatus = 'none' | 'track' | 'playlist';
export const Loop = (): JSX.Element => {
const className = bind(loopStatus).as((status) => {
const isActive = isLoopActive(status);
const loopingAllowed = status !== null && status !== AstalMpris.Loop.UNSUPPORTED ? 'enabled' : 'disabled';
const loopingAllowed =
status !== null && status !== AstalMpris.Loop.UNSUPPORTED ? 'enabled' : 'disabled';
return `media-indicator-control-button loop ${isActive} ${loopingAllowed}`;
});
@@ -60,7 +61,8 @@ export const Loop = (): JSX.Element => {
export const Shuffle = (): JSX.Element => {
const className = bind(shuffleStatus).as((status) => {
const isActive = isShuffleActive(status);
const shuffleAllowed = status !== null && status !== AstalMpris.Shuffle.UNSUPPORTED ? 'enabled' : 'disabled';
const shuffleAllowed =
status !== null && status !== AstalMpris.Shuffle.UNSUPPORTED ? 'enabled' : 'disabled';
return `media-indicator-control-button shuffle ${isActive} ${shuffleAllowed}`;
});

View File

@@ -3,7 +3,7 @@ import { isPrimaryClick } from 'src/lib/utils';
import { bind } from 'astal';
import { getPlaybackIcon } from './helpers';
import AstalMpris from 'gi://AstalMpris?version=0.1';
import { activePlayer, canPlay, playbackStatus } from 'src/globals/media';
import { activePlayer, canPlay, playbackStatus } from 'src/shared/media';
export const PlayPause = (): JSX.Element => {
const className = bind(canPlay).as((canPlay) => {
@@ -31,7 +31,13 @@ export const PlayPause = (): JSX.Element => {
};
return (
<button className={className} halign={Gtk.Align.CENTER} hasTooltip tooltipText={tooltipText} onClick={onClick}>
<button
className={className}
halign={Gtk.Align.CENTER}
hasTooltip
tooltipText={tooltipText}
onClick={onClick}
>
<icon icon={icon} />
</button>
);

View File

@@ -2,7 +2,7 @@ import icons from 'src/lib/icons/icons';
import { Astal, Gtk, Widget } from 'astal/gtk3';
import { isPrimaryClick } from 'src/lib/utils';
import { bind } from 'astal';
import { activePlayer, canGoNext, canGoPrevious } from 'src/globals/media';
import { activePlayer, canGoNext, canGoPrevious } from 'src/shared/media';
export const NextTrack = (): JSX.Element => {
const className = bind(canGoNext).as((skippable) => {

View File

@@ -1,7 +1,7 @@
import AstalMpris from 'gi://AstalMpris?version=0.1';
import { activePlayer } from 'src/globals/media';
import { activePlayer } from 'src/shared/media';
import icons2 from 'src/lib/icons/icons2';
import { PlaybackIconMap } from 'src/lib/types/mpris';
import { PlaybackIconMap } from 'src/lib/types/mpris.types';
const mprisService = AstalMpris.get_default();
@@ -123,5 +123,7 @@ export const getPreviousPlayer = (): void => {
return activePlayer.set(mprisService.get_players()[0]);
}
return activePlayer.set(mprisService.get_players()[(currentPlayerIndex - 1 + totalPlayers) % totalPlayers]);
return activePlayer.set(
mprisService.get_players()[(currentPlayerIndex - 1 + totalPlayers) % totalPlayers],
);
};

View File

@@ -1,11 +1,10 @@
import { BoxWidget } from 'src/lib/types/widget.js';
import { NextTrack, PreviousTrack } from './Tracks.js';
import { PlayPause } from './PlayPause.js';
import { Loop, Shuffle } from './Modes.js';
import { Gtk } from 'astal/gtk3';
import { NextPlayer, PreviousPlayer } from './Players.js';
export const MediaControls = (): BoxWidget => {
export const MediaControls = (): JSX.Element => {
return (
<box className={'media-indicator-current-player-controls'} vertical>
<box className={'media-indicator-current-controls'} halign={Gtk.Align.CENTER}>

View File

@@ -1,7 +1,7 @@
import { Binding } from 'astal';
import { bind, Variable } from 'astal';
import AstalMpris from 'gi://AstalMpris?version=0.1';
import { mediaArtUrl } from 'src/globals/media';
import { mediaArtUrl } from 'src/shared/media';
import options from 'src/options';
const mprisService = AstalMpris.get_default();
@@ -56,7 +56,9 @@ export const initializeActivePlayerHook = (): void => {
.get_players()
.find((p) => p['playbackStatus'] === AstalMpris.PlaybackStatus.PLAYING);
const playerStillExists = mprisService.get_players().some((player) => curPlayer.set(player.busName));
const playerStillExists = mprisService
.get_players()
.some((player) => curPlayer.get() === player.busName);
const nextPlayerUp = mprisService
.get_players()

View File

@@ -13,7 +13,7 @@ export const getTimeStamp = (position: number, totalLength: number): string => {
if (typeof position === 'number' && position >= 0) {
return `${getFormattedTime(position)} / ${getFormattedTime(totalLength)}`;
} else {
return `00:00`;
return '00:00';
}
};

View File

@@ -1,7 +1,7 @@
import options from 'src/options';
import { bind, Variable } from 'astal';
import { Widget } from 'astal/gtk3';
import { activePlayer, currentPosition, timeStamp } from 'src/globals/media';
import { activePlayer, currentPosition, timeStamp } from 'src/shared/media';
const { displayTimeTooltip } = options.menus.media;

View File

@@ -1,6 +1,6 @@
import options from 'src/options';
import { bind } from 'astal';
import { timeStamp } from 'src/globals/media';
import { timeStamp } from 'src/shared/media';
const { displayTime } = options.menus.media;

View File

@@ -1,7 +1,7 @@
import options from 'src/options';
import { Gtk } from 'astal/gtk3';
import { bind } from 'astal';
import { mediaAlbum } from 'src/globals/media';
import { mediaAlbum } from 'src/shared/media';
const { hideAlbum } = options.menus.media;

View File

@@ -1,7 +1,7 @@
import options from 'src/options';
import { Gtk } from 'astal/gtk3';
import { bind } from 'astal';
import { mediaArtist } from 'src/globals/media';
import { mediaArtist } from 'src/shared/media';
const { hideAuthor } = options.menus.media;

View File

@@ -1,6 +1,6 @@
import { Gtk } from 'astal/gtk3';
import { bind } from 'astal';
import { mediaTitle } from 'src/globals/media';
import { mediaTitle } from 'src/shared/media';
export const SongName = (): JSX.Element => {
return (

View File

@@ -29,7 +29,7 @@ const getWiredState = (): void => {
wiredStateBinding?.drop();
wiredStateBinding = undefined;
if (!networkService.wired) {
if (networkService.wired === null) {
wiredState.set(AstalNetwork.DeviceState.UNAVAILABLE);
return;
}
@@ -49,7 +49,7 @@ const getWiredInternet = (): void => {
wiredInternetBinding?.drop();
wiredInternetBinding = undefined;
if (!networkService.wired) {
if (networkService.wired === null) {
return;
}
@@ -68,7 +68,7 @@ const getWiredIcon = (): void => {
wiredIconBinding?.drop();
wiredIconBinding = undefined;
if (!networkService.wired) {
if (networkService.wired === null) {
wiredIcon.set('network-wired-symbolic');
return;
}
@@ -88,7 +88,7 @@ const getWiredSpeed = (): void => {
wiredSpeedBinding?.drop();
wiredSpeedBinding = undefined;
if (!networkService.wired) {
if (networkService.wired === null) {
return;
}

View File

@@ -1,4 +1,4 @@
import { WifiIcon } from 'src/lib/types/network';
import { WifiIcon } from 'src/lib/types/network.types';
/**
* Retrieves the appropriate WiFi icon based on the provided icon name.

View File

@@ -5,7 +5,9 @@ import Spinner from 'src/components/shared/Spinner';
import AstalNetwork from 'gi://AstalNetwork?version=0.1';
export const AccessPoint = ({ staging, connecting }: AccessPointProps): JSX.Element => {
const ConnectionIcon = (): JSX.Element => <icon className="network-icon wifi" icon={staging.get()?.iconName} />;
const ConnectionIcon = (): JSX.Element => (
<icon className="network-icon wifi" icon={staging.get()?.iconName} />
);
const ConnectionSpinner = (): JSX.Element => (
<revealer
halign={Gtk.Align.END}

View File

@@ -10,7 +10,7 @@ Variable.derive([bind(networkService, 'wifi')], () => {
scanningBinding?.drop();
scanningBinding = undefined;
if (!networkService.wifi) {
if (networkService.wifi === null) {
return;
}

View File

@@ -29,7 +29,11 @@ export const AccessPoint = ({ connecting, accessPoint }: AccessPointProps): JSX.
label={accessPoint.ssid ?? ''}
/>
<revealer revealChild={isApActive(accessPoint) && isApEnabled(networkService.wifi?.state)}>
<label className="connection-status dim" halign={Gtk.Align.START} label={getWifiStatus()} />
<label
className="connection-status dim"
halign={Gtk.Align.START}
label={getWifiStatus()}
/>
</revealer>
</box>
);

View File

@@ -12,7 +12,11 @@ export const Controls = ({ connecting, accessPoint }: ControlsProps): JSX.Elemen
disconnectFromAP(accessPoint, event);
}}
>
<label className="menu-icon-button disconnect-network txt-icon" tooltipText="Disconnect" label="󱘖" />
<label
className="menu-icon-button disconnect-network txt-icon"
tooltipText="Disconnect"
label="󱘖"
/>
</button>
);
};

View File

@@ -25,7 +25,7 @@ const wifiEnabled = (): void => {
wifiEnabledBinding?.drop();
wifiEnabledBinding = undefined;
if (!networkService.wifi) {
if (networkService.wifi === null) {
return;
}
@@ -44,7 +44,7 @@ const accessPoints = (): void => {
accessPointBinding?.drop();
accessPointBinding = undefined;
if (!networkService.wifi) {
if (networkService.wifi === null) {
return;
}
@@ -62,7 +62,7 @@ const accessPoints = (): void => {
* @returns An array of deduplicated access points.
*/
const dedupeWAPs = (): AstalNetwork.AccessPoint[] => {
if (!networkService.wifi) {
if (networkService.wifi === null) {
return [];
}
@@ -136,7 +136,7 @@ export const getFilteredWirelessAPs = (): AstalNetwork.AccessPoint[] => {
* @returns True if the device is in an active state; otherwise, false.
*/
export const isApEnabled = (state: AstalNetwork.DeviceState | undefined): boolean => {
if (!state) {
if (state == null) {
return false;
}
@@ -206,7 +206,7 @@ export const getIdFromSsid = (ssid: string, nmcliOutput: string): string | undef
export const getWifiStatus = (): string => {
const wifiState = networkService.wifi?.state;
if (wifiState) {
if (wifiState !== null) {
return DEVICE_STATES[wifiState];
}
return DEVICE_STATES[AstalNetwork.DeviceState.UNKNOWN];
@@ -232,9 +232,9 @@ export const connectToAP = (accessPoint: AstalNetwork.AccessPoint, event: Astal.
connecting.set('');
staging.set({} as AstalNetwork.AccessPoint);
})
.catch((err) => {
.catch((err: Error) => {
connecting.set('');
if (err.message?.toLowerCase().includes('secrets were required, but not provided')) {
if (err.message.toLowerCase().includes('secrets were required, but not provided')) {
staging.set(accessPoint);
} else {
Notify({

View File

@@ -1,6 +1,6 @@
import { bind } from 'astal';
import AstalNotifd from 'gi://AstalNotifd?version=0.1';
import { clearNotifications } from 'src/globals/notification';
import { clearNotifications, removingNotifications } from 'src/shared/notification';
import { isPrimaryClick } from 'src/lib/utils';
import options from 'src/options';
@@ -18,7 +18,7 @@ export const ClearNotificationsButton = (): JSX.Element => {
return;
}
if (removingNotifications.get()) {
if (removingNotifications.get() === true) {
return;
}
@@ -27,7 +27,7 @@ export const ClearNotificationsButton = (): JSX.Element => {
>
<label
className={bind(removingNotifications).as((removing) => {
return removing
return removing === true
? 'clear-notifications-label txt-icon removing'
: 'clear-notifications-label txt-icon';
})}

View File

@@ -2,7 +2,12 @@ import { Gtk } from 'astal/gtk3';
export const MenuLabel = (): JSX.Element => {
return (
<box className={'menu-label-container notifications'} halign={Gtk.Align.START} valign={Gtk.Align.CENTER} expand>
<box
className={'menu-label-container notifications'}
halign={Gtk.Align.START}
valign={Gtk.Align.CENTER}
expand
>
<label className={'menu-label notifications'} label={'Notifications'} />
</box>
);

View File

@@ -1,7 +1,8 @@
import { bind, Variable } from 'astal';
import AstalNotifd from 'gi://AstalNotifd?version=0.1';
const { displayedTotal } = options.notifications;
import options from 'src/options';
const { displayedTotal } = options.notifications;
const notifdService = AstalNotifd.get_default();
/**

View File

@@ -6,7 +6,12 @@ const notifdService = AstalNotifd.get_default();
export const Placeholder = (): JSX.Element => {
return (
<box className={'notification-label-container'} halign={Gtk.Align.CENTER} valign={Gtk.Align.FILL} expand>
<box
className={'notification-label-container'}
halign={Gtk.Align.CENTER}
valign={Gtk.Align.FILL}
expand
>
<box valign={Gtk.Align.CENTER} vertical expand>
<label
className={'placeholder-label dim bell txt-icon'}

View File

@@ -13,7 +13,12 @@ const { displayedTotal, ignore, showActionsOnHover } = options.notifications;
export const NotificationsContainer = ({ curPage }: NotificationsContainerProps): JSX.Element => {
return (
<scrollable vscroll={Gtk.PolicyType.AUTOMATIC}>
<box className={'menu-content-container notifications'} halign={Gtk.Align.FILL} spacing={0} vexpand>
<box
className={'menu-content-container notifications'}
halign={Gtk.Align.FILL}
spacing={0}
vexpand
>
{Variable.derive(
[
bind(notifdService, 'notifications'),

View File

@@ -32,7 +32,11 @@ export const NotificationPager = ({ curPage }: NotificationPagerProps): JSX.Elem
<box>
<FirstPageButton curPage={curPage} currentPage={currentPage} />
<PreviousPageButton curPage={curPage} currentPage={currentPage} />
<PageDisplay notifications={notifications} currentPage={currentPage} dispTotal={dispTotal} />
<PageDisplay
notifications={notifications}
currentPage={currentPage}
dispTotal={dispTotal}
/>
<NextPageButton
curPage={curPage}
currentPage={currentPage}

View File

@@ -1,7 +1,7 @@
import { Action } from 'src/lib/types/power';
import options from 'src/options';
import { execAsync, GObject, property, register } from 'astal';
import { App } from 'astal/gtk3';
import { Action } from 'src/lib/types/power.types';
const { sleep, reboot, logout, shutdown } = options.menus.dashboard.powermenu;
@register({ GTypeName: 'PowerMenu' })
@@ -10,16 +10,16 @@ class PowerMenu extends GObject.Object {
#cmd = '';
@property(String)
get title(): string {
public get title(): string {
return this.#title;
}
@property(String)
get cmd(): string {
public get cmd(): string {
return this.#cmd;
}
action(action: Action): void {
public action(action: Action): void {
[this.#cmd, this.#title] = {
sleep: [sleep.get(), 'Sleep'],
reboot: [reboot.get(), 'Reboot'],
@@ -34,7 +34,7 @@ class PowerMenu extends GObject.Object {
App.get_window('verification')?.set_visible(true);
}
customAction(action: Action, cmnd: string): void {
public customAction(action: Action, cmnd: string): void {
[this.#cmd, this.#title] = [cmnd, action];
this.notify('cmd');
@@ -44,16 +44,15 @@ class PowerMenu extends GObject.Object {
App.get_window('verification')?.set_visible(true);
}
shutdown = (): void => {
public shutdown = (): void => {
this.action('shutdown');
};
exec = (): void => {
public exec = (): void => {
App.get_window('verification')?.set_visible(false);
execAsync(this.#cmd);
};
}
const powermenu = new PowerMenu();
Object.assign(globalThis, { powermenu });
export default powermenu;

View File

@@ -1,4 +1,3 @@
import { Action } from 'src/lib/types/power.js';
import PopupWindow from '../shared/popup/index.js';
import powermenu from './helpers/actions.js';
import options from 'src/options.js';
@@ -7,6 +6,7 @@ import icons from 'src/lib/icons/icons.js';
import { bind } from 'astal';
import { Gtk } from 'astal/gtk3';
import { RevealerTransitionMap } from 'src/lib/constants/options.js';
import { Action } from 'src/lib/types/power.types.js';
const { transition } = options.menus;
@@ -21,7 +21,11 @@ const SysButton = ({ action, label }: SysButtonProps): JSX.Element => {
}}
>
<box className={'system-button widget-box'} vertical vexpand valign={Gtk.Align.FILL}>
<icon className={`system-button_icon txt-icon ${action}`} icon={icons.powermenu[action]} vexpand />
<icon
className={`system-button_icon txt-icon ${action}`}
icon={icons.powermenu[action]}
vexpand
/>
<label className={`system-button_label ${action}`} label={label} vexpand />
</box>
</button>
@@ -29,7 +33,10 @@ const SysButton = ({ action, label }: SysButtonProps): JSX.Element => {
};
export default (): JSX.Element => (
<PopupWindow name={'powermenu'} transition={bind(transition).as((transition) => RevealerTransitionMap[transition])}>
<PopupWindow
name={'powermenu'}
transition={bind(transition).as((transition) => RevealerTransitionMap[transition])}
>
<box className={'powermenu horizontal'}>
<SysButton action={'shutdown'} label={'SHUTDOWN'} />
<SysButton action={'logout'} label={'LOG OUT'} />

View File

@@ -4,14 +4,16 @@ import { App, Gtk } from 'astal/gtk3';
import { bind } from 'astal';
export default (): JSX.Element => (
<PopupWindow name="verification" transition="crossfade" layout={'center'}>
<PopupWindow name="verification" transition={Gtk.RevealerTransitionType.CROSSFADE} layout={'center'}>
<box className="verification" expand={false}>
<box className="verification-content" expand vertical>
<box className="text-box" vertical>
<label className="title" label={bind(powermenu, 'title').as((t) => t.toUpperCase())} />
<label
className="desc"
label={bind(powermenu, 'title').as((p) => `Are you sure you want to ${p.toLowerCase()}?`)}
label={bind(powermenu, 'title').as(
(p) => `Are you sure you want to ${p.toLowerCase()}?`,
)}
/>
</box>
<box className="buttons horizontal" vexpand valign={Gtk.Align.END} homogeneous>

View File

@@ -1,9 +1,9 @@
import { PowerOptions } from 'src/lib/types/options';
import { capitalizeFirstLetter } from 'src/lib/utils';
import options from 'src/options';
import powermenu from '../power/helpers/actions';
import { App, Gtk } from 'astal/gtk3';
import { bind, execAsync } from 'astal';
import { PowerOptions } from 'src/lib/options/options.types';
const { confirmation, shutdown, logout, sleep, reboot, showLabel } = options.menus.power;
@@ -35,7 +35,9 @@ export const PowerButton = (action: PowerOptions): JSX.Element => {
return (
<button
className={bind(showLabel).as((showLbl) => `power-menu-button ${action} ${!showLbl ? 'no-label' : ''}`)}
className={bind(showLabel).as(
(showLbl) => `power-menu-button ${action} ${!showLbl ? 'no-label' : ''}`,
)}
onClicked={() => handleClick(action)}
>
<box vertical={false}>

View File

@@ -1,6 +1,6 @@
import { DropdownMenuList } from 'src/lib/options/options.types';
import { calculateMenuPosition } from './locationHandler';
import { App, Gtk } from 'astal/gtk3';
import { DropdownMenuList } from 'src/lib/types/options';
/**
* Handles the realization of a dropdown menu.

View File

@@ -1,11 +1,11 @@
import options from 'src/options';
import { DropdownMenuProps } from 'src/lib/types/dropdownmenu';
import { BarEventMargins } from './eventBoxes/index';
import { globalEventBoxes } from 'src/globals/dropdown';
import { globalEventBoxes } from 'src/shared/dropdown';
import { bind } from 'astal';
import { App, Astal, Gdk, Gtk } from 'astal/gtk3';
import { Revealer } from 'astal/gtk3/widget';
import { locationMap } from 'src/lib/types/defaults/bar';
import { locationMap } from 'src/lib/types/defaults/bar.types';
import { DropdownMenuProps } from 'src/lib/types/dropdownmenu.types';
const { location } = options.theme.bar;
@@ -66,7 +66,10 @@ export default ({
onButtonPressEvent={(_, event) => {
const buttonClicked = event.get_button()[1];
if (buttonClicked === Gdk.BUTTON_PRIMARY || buttonClicked === Gdk.BUTTON_SECONDARY) {
if (
buttonClicked === Gdk.BUTTON_PRIMARY ||
buttonClicked === Gdk.BUTTON_SECONDARY
) {
return true;
}
}}

View File

@@ -1,5 +1,5 @@
import options from 'src/options';
import { globalEventBoxes } from 'src/globals/dropdown';
import { globalEventBoxes } from 'src/shared/dropdown';
import { GLib } from 'astal';
import { EventBox } from 'astal/gtk3/widget';
import AstalHyprland from 'gi://AstalHyprland?version=0.1';
@@ -46,7 +46,7 @@ function getFocusedHyprlandMonitor(): AstalHyprland.Monitor | undefined {
* @returns An object containing `adjustedWidth` and `adjustedHeight` after scaling is applied.
*/
function applyMonitorScaling(width: number, height: number, monitorScaling: number): MonitorScaling {
const gdkEnvScale = GLib.getenv('GDK_SCALE') || '1';
const gdkEnvScale = GLib.getenv('GDK_SCALE') ?? '1';
const userScalingPriority = scalingPriority.get();
let adjustedWidth = width;
@@ -101,7 +101,11 @@ function adjustForVerticalTransform(
* @param anchorX - The X coordinate (in scaled pixels) around which the dropdown should be placed.
* @returns An object containing `leftMargin` and `rightMargin`, ensuring they do not go below 0.
*/
function calculateHorizontalMargins(monitorWidth: number, dropdownWidth: number, anchorX: number): HorizontalMargins {
function calculateHorizontalMargins(
monitorWidth: number,
dropdownWidth: number,
anchorX: number,
): HorizontalMargins {
const minimumSpacing = 0;
let rightMarginSpacing = monitorWidth - dropdownWidth / 2;
@@ -130,7 +134,11 @@ function calculateHorizontalMargins(monitorWidth: number, dropdownWidth: number,
* @param monitorHeight - The scaled (and possibly swapped) monitor height.
* @param dropdownHeight - The height of the dropdown widget.
*/
function setVerticalPosition(dropdownEventBox: EventBox, monitorHeight: number, dropdownHeight: number): void {
function setVerticalPosition(
dropdownEventBox: EventBox,
monitorHeight: number,
dropdownHeight: number,
): void {
if (location.get() === 'top') {
dropdownEventBox.set_margin_top(0);
dropdownEventBox.set_margin_bottom(monitorHeight);
@@ -151,7 +159,10 @@ function setVerticalPosition(dropdownEventBox: EventBox, monitorHeight: number,
*
* @returns A Promise that resolves once the dropdown position is fully calculated and set.
*/
export const calculateMenuPosition = async (positionCoordinates: number[], windowName: string): Promise<void> => {
export const calculateMenuPosition = async (
positionCoordinates: number[],
windowName: string,
): Promise<void> => {
try {
const dropdownEventBox = getDropdownEventBox(windowName);
@@ -182,7 +193,11 @@ export const calculateMenuPosition = async (positionCoordinates: number[], windo
);
const isVertical = transform !== undefined ? transform % 2 !== 0 : false;
const { finalWidth, finalHeight } = adjustForVerticalTransform(adjustedWidth, adjustedHeight, isVertical);
const { finalWidth, finalHeight } = adjustForVerticalTransform(
adjustedWidth,
adjustedHeight,
isVertical,
);
const { leftMargin, rightMargin } = calculateHorizontalMargins(
finalWidth,

View File

@@ -1,4 +1,4 @@
import { BarLocation } from 'src/lib/types/options';
import { BarLocation } from 'src/lib/options/options.types';
export type EventBoxPaddingProps = {
className: string;

View File

@@ -1,8 +1,13 @@
import { App, Astal, Gdk, Gtk } from 'astal/gtk3';
import { WINDOW_LAYOUTS } from 'src/globals/window';
import { LayoutFunction, Layouts, PaddingProps, PopupRevealerProps, PopupWindowProps } from 'src/lib/types/popupwindow';
import { Exclusivity, GtkWidget } from 'src/lib/types/widget';
import { WINDOW_LAYOUTS } from 'src/shared/window';
import { EventBox, Revealer } from 'astal/gtk3/widget';
import {
PaddingProps,
PopupRevealerProps,
LayoutFunction,
PopupWindowProps,
} from 'src/lib/types/popupwindow.types';
import { Layouts } from 'src/lib/types/widget.types';
export const Padding = ({ name, opts }: PaddingProps): JSX.Element => (
<eventbox
@@ -32,7 +37,7 @@ const PopupRevealer = ({ name, child, transition }: PopupRevealerProps): JSX.Ele
</box>
);
const Layout: LayoutFunction = (name: string, child: GtkWidget, transition: Gtk.RevealerTransitionType) => ({
const Layout: LayoutFunction = (name, child, transition) => ({
center: () => (
<centerbox>
<Padding name={name} />
@@ -119,10 +124,10 @@ const isValidLayout = (layout: string): layout is Layouts => {
export default ({
name,
child,
child = <box />,
layout = 'center',
transition = 'none',
exclusivity = 'ignore' as Exclusivity,
transition = Gtk.RevealerTransitionType.NONE,
exclusivity = Astal.Exclusivity.IGNORE,
...props
}: PopupWindowProps): JSX.Element => {
const layoutFn = isValidLayout(layout) ? layout : 'center';
@@ -147,7 +152,10 @@ export default ({
application={App}
layer={Astal.Layer.TOP}
anchor={
Astal.WindowAnchor.TOP | Astal.WindowAnchor.BOTTOM | Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.LEFT
Astal.WindowAnchor.TOP |
Astal.WindowAnchor.BOTTOM |
Astal.WindowAnchor.RIGHT |
Astal.WindowAnchor.LEFT
}
{...props}
>