Files
custum-hyprpanel/src/components/bar/modules/media/index.tsx
Jas Singh 8cf5806766 Minor: Refactor the code-base for better organization and compartmentalization. (#934)
* Clean up unused code

* Fix media player formatting issue for labels with new line characteres.

* Refactor the media player handlers into a class.

* More code cleanup and organize shared weather utils into distinct classes.

* Flatten some nesting.

* Move weather manager in dedicated class and build HTTP Utility class for Rest API calling.

* Remove logs

* Rebase master merge

* Reorg code (WIP)

* More reorg

* Delete utility scripts

* Reorg options

* Finish moving all options over

* Fix typescript issues

* Update options imports to default

* missed update

* Screw barrel files honestly, work of the devil.

* Only initialize power profiles if power-profiles-daemon is running.

* Fix window positioning and weather service naming

* style dir

* More organization

* Restructure types to be closer to their source

* Remove lib types and constants

* Update basic weather object to be saner with extensibility.

* Service updates

* Fix initialization strategy for services.

* Fix Config Manager to only emit changed objects and added missing temp converters.

* Update storage service to handle unit changes.

* Added cpu temp sensor auto-discovery

* Added missing JSDocs to services

* remove unused

* Migrate to network service.

* Fix network password issue.

* Move out password input into helper

* Rename password mask constant to be less double-negativey.

* Dropdown menu rename

* Added a component to edit JSON in the settings dialog (rough/WIP)

* Align settings

* Add and style JSON Editor.

* Adjust padding

* perf(shortcuts):  avoid unnecessary polling when shortcuts are disabled

Stops the recording poller when shortcuts are disabled, preventing redundant polling and reducing resource usage.

* Fix types and return value if shortcut not enabled.

* Move the swww daemon checking process outside of the wallpaper service into a dedicated deamon lifecyle processor.

* Add more string formatters and use title case for weather status (as it was).

* Fix startup errors.

* Rgba fix

* Remove zod from dependencies

---------

Co-authored-by: KernelDiego <gonzalezdiego.contact@gmail.com>
2025-05-26 19:45:11 -07:00

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 };