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:
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 />;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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={() => {
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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'} />;
|
||||
}
|
||||
|
||||
|
||||
@@ -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'} />;
|
||||
}
|
||||
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ Variable.derive([bind(bluetoothService, 'adapter')], () => {
|
||||
discoveringBinding?.drop();
|
||||
discoveringBinding = undefined;
|
||||
|
||||
if (!bluetoothService.adapter) {
|
||||
if (bluetoothService.adapter === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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'}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { globalWeatherVar } from 'src/globals/weather';
|
||||
import { globalWeatherVar } from 'src/shared/weather';
|
||||
import { getNextEpoch } from '../helpers';
|
||||
import { bind } from 'astal';
|
||||
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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,
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ Variable.derive([bind(networkService, 'wifi')], () => {
|
||||
wifiEnabledBinding?.drop();
|
||||
wifiEnabledBinding = undefined;
|
||||
|
||||
if (!networkService.wifi) {
|
||||
if (networkService.wifi === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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, '\\"');
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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)}`,
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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}`;
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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],
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -10,7 +10,7 @@ Variable.derive([bind(networkService, 'wifi')], () => {
|
||||
scanningBinding?.drop();
|
||||
scanningBinding = undefined;
|
||||
|
||||
if (!networkService.wifi) {
|
||||
if (networkService.wifi === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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';
|
||||
})}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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'}
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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'} />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BarLocation } from 'src/lib/types/options';
|
||||
import { BarLocation } from 'src/lib/options/options.types';
|
||||
|
||||
export type EventBoxPaddingProps = {
|
||||
className: string;
|
||||
|
||||
@@ -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}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user