* Clean up unused code * Fix media player formatting issue for labels with new line characteres. * Refactor the media player handlers into a class. * More code cleanup and organize shared weather utils into distinct classes. * Flatten some nesting. * Move weather manager in dedicated class and build HTTP Utility class for Rest API calling. * Remove logs * Rebase master merge * Reorg code (WIP) * More reorg * Delete utility scripts * Reorg options * Finish moving all options over * Fix typescript issues * Update options imports to default * missed update * Screw barrel files honestly, work of the devil. * Only initialize power profiles if power-profiles-daemon is running. * Fix window positioning and weather service naming * style dir * More organization * Restructure types to be closer to their source * Remove lib types and constants * Update basic weather object to be saner with extensibility. * Service updates * Fix initialization strategy for services. * Fix Config Manager to only emit changed objects and added missing temp converters. * Update storage service to handle unit changes. * Added cpu temp sensor auto-discovery * Added missing JSDocs to services * remove unused * Migrate to network service. * Fix network password issue. * Move out password input into helper * Rename password mask constant to be less double-negativey. * Dropdown menu rename * Added a component to edit JSON in the settings dialog (rough/WIP) * Align settings * Add and style JSON Editor. * Adjust padding * perf(shortcuts): ⚡ avoid unnecessary polling when shortcuts are disabled Stops the recording poller when shortcuts are disabled, preventing redundant polling and reducing resource usage. * Fix types and return value if shortcut not enabled. * Move the swww daemon checking process outside of the wallpaper service into a dedicated deamon lifecyle processor. * Add more string formatters and use title case for weather status (as it was). * Fix startup errors. * Rgba fix * Remove zod from dependencies --------- Co-authored-by: KernelDiego <gonzalezdiego.contact@gmail.com>
134 lines
4.3 KiB
TypeScript
134 lines
4.3 KiB
TypeScript
import { generateMediaLabel } from './helpers/index.js';
|
|
import { onPrimaryClick, onSecondaryClick, onMiddleClick, onScroll } from 'src/lib/shared/eventHandlers';
|
|
import { bind, Variable } from 'astal';
|
|
import { Astal } from 'astal/gtk3';
|
|
import AstalMpris from 'gi://AstalMpris?version=0.1';
|
|
import { BarBoxChild } from 'src/components/bar/types.js';
|
|
import { activePlayer, mediaTitle, mediaAlbum, mediaArtist } from 'src/services/media';
|
|
import options from 'src/configuration';
|
|
import { runAsyncCommand } from '../../utils/input/commandExecutor';
|
|
import { throttledScrollHandler } from '../../utils/input/throttle';
|
|
import { openDropdownMenu } from '../../utils/menu';
|
|
|
|
const mprisService = AstalMpris.get_default();
|
|
const {
|
|
truncation,
|
|
truncation_size,
|
|
show_label,
|
|
show_active_only,
|
|
rightClick,
|
|
middleClick,
|
|
scrollUp,
|
|
scrollDown,
|
|
format,
|
|
} = options.bar.media;
|
|
|
|
const isVis = Variable(!show_active_only.get());
|
|
|
|
Variable.derive([bind(show_active_only), bind(mprisService, 'players')], (showActive, players) => {
|
|
isVis.set(!showActive || players?.length > 0);
|
|
});
|
|
|
|
const Media = (): BarBoxChild => {
|
|
activePlayer.set(mprisService.get_players()[0]);
|
|
|
|
const songIcon = Variable('');
|
|
|
|
const mediaLabel = Variable.derive(
|
|
[
|
|
bind(activePlayer),
|
|
bind(truncation),
|
|
bind(truncation_size),
|
|
bind(show_label),
|
|
bind(format),
|
|
bind(mediaTitle),
|
|
bind(mediaAlbum),
|
|
bind(mediaArtist),
|
|
],
|
|
() => {
|
|
return generateMediaLabel(truncation_size, show_label, format, songIcon, activePlayer);
|
|
},
|
|
);
|
|
|
|
const componentClassName = Variable.derive(
|
|
[options.theme.bar.buttons.style, show_label],
|
|
(style: string) => {
|
|
const styleMap: Record<string, string> = {
|
|
default: 'style1',
|
|
split: 'style2',
|
|
wave: 'style3',
|
|
wave2: 'style3',
|
|
};
|
|
return `media-container ${styleMap[style]}`;
|
|
},
|
|
);
|
|
|
|
const component = (
|
|
<box
|
|
className={componentClassName()}
|
|
onDestroy={() => {
|
|
songIcon.drop();
|
|
mediaLabel.drop();
|
|
componentClassName.drop();
|
|
}}
|
|
>
|
|
<label
|
|
className={'bar-button-icon media txt-icon bar'}
|
|
label={bind(songIcon).as((icn) => icn || '')}
|
|
/>
|
|
<label className={'bar-button-label media'} label={mediaLabel()} />
|
|
</box>
|
|
);
|
|
|
|
return {
|
|
component,
|
|
isVis: bind(isVis),
|
|
boxClass: 'media',
|
|
props: {
|
|
setup: (self: Astal.Button): void => {
|
|
let disconnectFunctions: (() => void)[] = [];
|
|
|
|
Variable.derive(
|
|
[
|
|
bind(rightClick),
|
|
bind(middleClick),
|
|
bind(scrollUp),
|
|
bind(scrollDown),
|
|
bind(options.bar.scrollSpeed),
|
|
],
|
|
() => {
|
|
disconnectFunctions.forEach((disconnect) => disconnect());
|
|
disconnectFunctions = [];
|
|
|
|
const throttledHandler = throttledScrollHandler(options.bar.scrollSpeed.get());
|
|
|
|
disconnectFunctions.push(
|
|
onPrimaryClick(self, (clicked, event) => {
|
|
openDropdownMenu(clicked, event, 'mediamenu');
|
|
}),
|
|
);
|
|
|
|
disconnectFunctions.push(
|
|
onSecondaryClick(self, (clicked, event) => {
|
|
runAsyncCommand(rightClick.get(), { clicked, event });
|
|
}),
|
|
);
|
|
|
|
disconnectFunctions.push(
|
|
onMiddleClick(self, (clicked, event) => {
|
|
runAsyncCommand(middleClick.get(), { clicked, event });
|
|
}),
|
|
);
|
|
|
|
disconnectFunctions.push(
|
|
onScroll(self, throttledHandler, scrollUp.get(), scrollDown.get()),
|
|
);
|
|
},
|
|
);
|
|
},
|
|
},
|
|
};
|
|
};
|
|
|
|
export { Media };
|