From 5bc1c1e7d47581f7e898156729f2a77a1c4c6939 Mon Sep 17 00:00:00 2001 From: Jas Singh Date: Mon, 28 Oct 2024 00:03:28 -0700 Subject: [PATCH] Add workspace app icon side-effects and add wiki link for settings. (#387) * Add side-effect for app icons for workspaces and udated mpris types. * Add links to workspace icon toggles. * Add subtitle --- lib/constants/workspaces.ts | 2 +- modules/bar/workspaces/utils.ts | 5 +- .../media/components/controls/loop/index.ts | 3 +- .../components/controls/playpause/index.ts | 5 +- modules/menus/media/components/helpers.ts | 5 +- .../menus/media/components/timebar/helpers.ts | 16 +++- widget/settings/pages/config/bar/index.ts | 11 ++- widget/settings/side_effects/index.ts | 73 ++++++++++++++----- 8 files changed, 90 insertions(+), 30 deletions(-) diff --git a/lib/constants/workspaces.ts b/lib/constants/workspaces.ts index 40f8a14..ffa94b1 100644 --- a/lib/constants/workspaces.ts +++ b/lib/constants/workspaces.ts @@ -5,7 +5,7 @@ export const defaultApplicationIcons = { 'draw.io': '󰇟', 'firefox-developer-edition': '', 'google-chrome': '', - 'title:.*youtube': '', + 'title:YouTube ': '', Spotify: '󰓇', chromium: '', code: '󰨞', diff --git a/modules/bar/workspaces/utils.ts b/modules/bar/workspaces/utils.ts index 446e460..3b99ad3 100644 --- a/modules/bar/workspaces/utils.ts +++ b/modules/bar/workspaces/utils.ts @@ -94,12 +94,13 @@ export const getAppIcon = ( try { if (matcher.startsWith('class:')) { const re = matcher.substring(6); - return new RegExp(re, 'i').test(clientClass); + return new RegExp(re).test(clientClass); } if (matcher.startsWith('title:')) { const re = matcher.substring(6); - return new RegExp(re, 'i').test(clientTitle); + + return new RegExp(re).test(clientTitle); } return new RegExp(matcher, 'i').test(clientClass); diff --git a/modules/menus/media/components/controls/loop/index.ts b/modules/menus/media/components/controls/loop/index.ts index 77b347b..cfd94c0 100644 --- a/modules/menus/media/components/controls/loop/index.ts +++ b/modules/menus/media/components/controls/loop/index.ts @@ -1,7 +1,6 @@ import icons from 'lib/icons'; import { BoxWidget } from 'lib/types/widget'; import { getPlayerInfo } from '../../helpers'; -import { MprisPlayer } from 'types/service/mpris'; import { isLoopActive, isValidLoopStatus } from './helpers'; const media = await Service.import('mpris'); @@ -36,7 +35,7 @@ export const loopControl = (): BoxWidget => { child: Widget.Icon({ setup: (self) => { self.hook(media, () => { - const foundPlayer: MprisPlayer = getPlayerInfo(); + const foundPlayer = getPlayerInfo(); if (foundPlayer === undefined) { self.icon = icons.mpris.loop['none']; diff --git a/modules/menus/media/components/controls/playpause/index.ts b/modules/menus/media/components/controls/playpause/index.ts index 8da3216..f931eb3 100644 --- a/modules/menus/media/components/controls/playpause/index.ts +++ b/modules/menus/media/components/controls/playpause/index.ts @@ -1,6 +1,5 @@ const media = await Service.import('mpris'); import { getPlayerInfo } from '../../helpers'; -import { MprisPlayer } from 'types/service/mpris'; import { isValidPlaybackStatus } from './helpers'; import Button from 'types/widgets/button'; import Icon from 'types/widgets/icon'; @@ -26,10 +25,12 @@ export const playPause = (): Button, Attribute> => { }, child: Widget.Icon({ icon: Utils.watch(icons.mpris.paused, media, 'changed', () => { - const foundPlayer: MprisPlayer = getPlayerInfo(); + const foundPlayer = getPlayerInfo(); + if (foundPlayer === undefined) { return icons.mpris['paused']; } + const playbackStatus = foundPlayer.play_back_status?.toLowerCase(); if (playbackStatus && isValidPlaybackStatus(playbackStatus)) { diff --git a/modules/menus/media/components/helpers.ts b/modules/menus/media/components/helpers.ts index a0c1a26..0d08a00 100644 --- a/modules/menus/media/components/helpers.ts +++ b/modules/menus/media/components/helpers.ts @@ -46,6 +46,9 @@ export const initializeActivePlayerHook = (): void => { }); }; -export const getPlayerInfo = (): MprisPlayer => { +export const getPlayerInfo = (): MprisPlayer | undefined => { + if (media.players.length === 0) { + return; + } return media.players.find((p) => p.bus_name === curPlayer.value) || media.players[0]; }; diff --git a/modules/menus/media/components/timebar/helpers.ts b/modules/menus/media/components/timebar/helpers.ts index 0aeb6a3..e5a63ff 100644 --- a/modules/menus/media/components/timebar/helpers.ts +++ b/modules/menus/media/components/timebar/helpers.ts @@ -2,7 +2,13 @@ import { Attribute } from 'lib/types/widget'; import { MprisPlayer } from 'types/service/mpris'; import Slider from 'types/widgets/slider'; -export const updateTooltip = (self: Slider, foundPlayer: MprisPlayer): void => { +/** + * Updates the tooltip text of the slider based on the player's current position. + * + * @param self - The slider component to update. + * @param foundPlayer - The MPRIS player object, if available. + */ +export const updateTooltip = (self: Slider, foundPlayer?: MprisPlayer): void => { if (foundPlayer === undefined) { self.tooltip_text = '00:00'; return; @@ -29,7 +35,13 @@ export const updateTooltip = (self: Slider, foundPlayer: MprisPlayer) } }; -export const update = (self: Slider, foundPlayer: MprisPlayer): void => { +/** + * Updates the value of the slider based on the player's current position and length. + * + * @param self - The slider component to update. + * @param foundPlayer - The MPRIS player object, if available. + */ +export const update = (self: Slider, foundPlayer?: MprisPlayer): void => { if (foundPlayer !== undefined) { const value = foundPlayer.length ? foundPlayer.position / foundPlayer.length : 0; self.value = value > 0 ? value : 0; diff --git a/widget/settings/pages/config/bar/index.ts b/widget/settings/pages/config/bar/index.ts index dc83f85..0165cda 100644 --- a/widget/settings/pages/config/bar/index.ts +++ b/widget/settings/pages/config/bar/index.ts @@ -259,12 +259,17 @@ export const BarSettings = (): Scrollable => { Option({ opt: options.bar.workspaces.showWsIcons, title: 'Map Workspaces to Icons', + subtitle: 'https://hyprpanel.com/configuration/panel.html#show-workspace-icons', + subtitleLink: 'https://hyprpanel.com/configuration/panel.html#show-workspace-icons', type: 'boolean', }), Option({ opt: options.bar.workspaces.showApplicationIcons, title: 'Map Workspaces to Application Icons', - subtitle: "Requires 'Map Workspace to Icons' to be enabled", + subtitle: + "Requires 'Map Workspace to Icons' to be enabled\n" + + 'https://hyprpanel.com/configuration/panel.html#map-workspaces-to-application-icons', + subtitleLink: 'https://hyprpanel.com/configuration/panel.html#map-workspaces-to-application-icons', type: 'boolean', }), Option({ @@ -291,7 +296,9 @@ export const BarSettings = (): Scrollable => { }), Option({ opt: options.bar.workspaces.workspaceIconMap, - title: 'Workspace Icon Mappings', + title: 'Workspace Icon & Color Mappings', + subtitle: 'https://hyprpanel.com/configuration/panel.html#show-workspace-icons', + subtitleLink: 'https://hyprpanel.com/configuration/panel.html#show-workspace-icons', type: 'object', }), Option({ diff --git a/widget/settings/side_effects/index.ts b/widget/settings/side_effects/index.ts index 6e268c1..c4d6927 100644 --- a/widget/settings/side_effects/index.ts +++ b/widget/settings/side_effects/index.ts @@ -1,30 +1,67 @@ +import { Opt } from 'lib/option'; import options from 'options'; -const { show_numbered, show_icons, showWsIcons } = options.bar.workspaces; +const { show_numbered, show_icons, showWsIcons, showApplicationIcons } = options.bar.workspaces; const { monochrome: monoBar } = options.theme.bar.buttons; const { monochrome: monoMenu } = options.theme.bar.menus; const { matugen } = options.theme; -show_numbered.connect('changed', ({ value }) => { - if (value === true) { - show_icons.value = false; - showWsIcons.value = false; +/** + * Turns off the specified option variables when the source value is true. + * + * @param sourceValue - The source option whose value determines whether to turn off other options. + * @param optionsToDisable - An array of option variables to disable if the source value is true. + * @param ignoreVars - An optional array of option variables to ignore and not disable. + */ +const turnOffOptionVars = ( + sourceValue: Opt, + optionsToDisable: Array>, + ignoreVars?: Array>, +): void => { + const toggleOffVars = (varsToToggle: Array>): void => { + const varsToNotToggle = ignoreVars?.map((curVar) => curVar.id) || []; + + varsToToggle.forEach((curVar) => { + if (sourceValue.id !== curVar.id && !varsToNotToggle.includes(curVar.id)) { + curVar.value = false; + } + }); + }; + + if (sourceValue.value) { + const varsToToggleOff = optionsToDisable; + toggleOffVars(varsToToggleOff); + } +}; + +/* ================================================== */ +/* WORKSPACE SIDE EFFECTS */ +/* ================================================== */ +const workspaceOptsToDisable = [show_numbered, show_icons, showWsIcons, showApplicationIcons]; + +show_numbered.connect('changed', (sourceVar) => { + turnOffOptionVars(sourceVar, workspaceOptsToDisable); +}); + +show_icons.connect('changed', (sourceVar) => { + turnOffOptionVars(sourceVar, workspaceOptsToDisable); +}); + +showWsIcons.connect('changed', (sourceVar) => { + turnOffOptionVars(sourceVar, workspaceOptsToDisable, [showApplicationIcons]); +}); + +showApplicationIcons.connect('changed', (sourceVar) => { + turnOffOptionVars(sourceVar, workspaceOptsToDisable, [showWsIcons]); + + if (sourceVar.value) { + showWsIcons.value = true; } }); -show_icons.connect('changed', ({ value }) => { - if (value === true) { - show_numbered.value = false; - showWsIcons.value = false; - } -}); - -showWsIcons.connect('changed', ({ value }) => { - if (value === true) { - show_numbered.value = false; - show_icons.value = false; - } -}); +/* ================================================== */ +/* MATUGEN SIDE EFFECTS */ +/* ================================================== */ matugen.connect('changed', ({ value }) => { if (value === true) {