From 4721b4fbf9793f75d1fc51f03b8212c221688b15 Mon Sep 17 00:00:00 2001 From: Jas Singh Date: Mon, 9 Sep 2024 23:03:01 -0700 Subject: [PATCH] HyprPanel now handles notification removal itself. (#242) --- globals.d.ts | 1 + globals/notification.ts | 13 ++ globals/weather.ts | 1 - modules/menus/notifications/controls/index.ts | 17 ++- modules/menus/notifications/index.ts | 34 +++-- modules/menus/notifications/pager/index.ts | 129 ++++++++++-------- scss/style/menus/notifications.scss | 6 +- 7 files changed, 125 insertions(+), 76 deletions(-) diff --git a/globals.d.ts b/globals.d.ts index bb696c0..0ff1a02 100644 --- a/globals.d.ts +++ b/globals.d.ts @@ -7,6 +7,7 @@ declare global { var useTheme: Function; var globalWeatherVar: VariableType; var options: Options + var removingNotifications: VariableType; } export { }; diff --git a/globals/notification.ts b/globals/notification.ts index 0c918e6..16daaa6 100644 --- a/globals/notification.ts +++ b/globals/notification.ts @@ -1,4 +1,7 @@ import icons from "modules/icons/index"; +import { Notification } from "types/service/notifications"; + +export const removingNotifications = Variable(false); export const getNotificationIcon = (app_name: string, app_icon: string, app_entry: string) => { let icon: string = icons.fallback.notification; @@ -22,3 +25,13 @@ export const getNotificationIcon = (app_name: string, app_icon: string, app_entr return icon; }; +export const closeNotifications = async (notifications: Notification[]) => { + removingNotifications.value = true; + for (const notif of notifications) { + notif.close(); + await new Promise(resolve => setTimeout(resolve, 100)); + } + removingNotifications.value = false; +} + +globalThis["removingNotifications"] = removingNotifications; diff --git a/globals/weather.ts b/globals/weather.ts index 6e9e43e..47760e0 100644 --- a/globals/weather.ts +++ b/globals/weather.ts @@ -125,4 +125,3 @@ export const getWeatherStatusTextIcon = (wthr: Weather): WeatherIcon => { }; globalThis["globalWeatherVar"] = globalWeatherVar; - diff --git a/modules/menus/notifications/controls/index.ts b/modules/menus/notifications/controls/index.ts index 5226f4d..8fc2712 100644 --- a/modules/menus/notifications/controls/index.ts +++ b/modules/menus/notifications/controls/index.ts @@ -1,3 +1,4 @@ +import { closeNotifications } from "globals/notification"; import { Notifications } from "types/service/notifications"; const Controls = (notifs: Notifications) => { @@ -40,11 +41,21 @@ const Controls = (notifs: Notifications) => { class_name: "menu-separator notification-controls", }), Widget.Button({ - class_name: "clear-notifications-button", + className: "clear-notifications-button", tooltip_text: "Clear Notifications", - on_primary_click: () => notifs.clear(), + on_primary_click: () => { + if (removingNotifications.value) { + return; + } + + closeNotifications(notifs.notifications); + }, child: Widget.Label({ - class_name: "clear-notifications-label txt-icon", + class_name: removingNotifications.bind("value").as((removing: boolean) => { + return removing + ? "clear-notifications-label txt-icon removing" + : "clear-notifications-label txt-icon"; + }), label: "", }), }), diff --git a/modules/menus/notifications/index.ts b/modules/menus/notifications/index.ts index de4a4d3..6b80ca6 100644 --- a/modules/menus/notifications/index.ts +++ b/modules/menus/notifications/index.ts @@ -1,3 +1,4 @@ +import { Notification } from "types/service/notifications.js"; import DropdownMenu from "../DropdownMenu.js"; const notifs = await Service.import("notifications"); import { Controls } from "./controls/index.js"; @@ -7,18 +8,27 @@ import { NotificationPager } from "./pager/index.js"; import options from "options"; const { displayedTotal } = options.notifications; -const { show: showPager } = options.theme.bar.menus.menu.notifications.pager; export default () => { const curPage = Variable(1); - Utils.merge([curPage.bind("value"), displayedTotal.bind("value"), notifs.bind("notifications")], (currentPage, dispTotal, notifications) => { - // If the page doesn't have enough notifications to display, go back - // to the previous page. - if (notifications.length <= (currentPage - 1) * dispTotal) { - curPage.value = currentPage <= 1 ? 1 : currentPage - 1; - } - }); + Utils.merge( + [ + curPage.bind("value"), + displayedTotal.bind("value"), + notifs.bind("notifications"), + ], + ( + currentPage: number, + dispTotal: number, + notifications: Notification[], + ) => { + // If the page doesn't have enough notifications to display, go back + // to the previous page. + if (notifications.length <= (currentPage - 1) * dispTotal) { + curPage.value = currentPage <= 1 ? 1 : currentPage - 1; + } + }); return DropdownMenu({ name: "notificationsmenu", @@ -34,13 +44,7 @@ export default () => { vertical: true, hexpand: false, vexpand: false, - children: showPager.bind("value").as(shPgr => { - if (shPgr) { - return [Controls(notifs), NotificationCard(notifs, curPage), NotificationPager(curPage)]; - } - return [Controls(notifs), NotificationCard(notifs, curPage)] - - }) + children: [Controls(notifs), NotificationCard(notifs, curPage), NotificationPager(curPage)] }), ], }), diff --git a/modules/menus/notifications/pager/index.ts b/modules/menus/notifications/pager/index.ts index 08aaca9..d63c872 100644 --- a/modules/menus/notifications/pager/index.ts +++ b/modules/menus/notifications/pager/index.ts @@ -1,74 +1,91 @@ const notifs = await Service.import("notifications"); import options from "options"; +import { Notification } from "types/service/notifications"; import { Variable } from "types/variable"; const { displayedTotal } = options.notifications; +const { show: showPager } = options.theme.bar.menus.menu.notifications.pager; export const NotificationPager = (curPage: Variable) => { return Widget.Box({ class_name: "notification-menu-pager", hexpand: true, vexpand: false, - children: Utils.merge([curPage.bind("value"), displayedTotal.bind("value"), notifs.bind("notifications")], (currentPage, dispTotal, _) => { - return [ - Widget.Button({ - hexpand: true, - hpack: "start", - class_name: `pager-button left ${currentPage <= 1 ? "disabled" : ""}`, - onPrimaryClick: () => { - curPage.value = 1; - }, - child: Widget.Label({ - className: "pager-button-label", - label: "" + children: Utils.merge( + [ + curPage.bind("value"), + displayedTotal.bind("value"), + notifs.bind("notifications"), + showPager.bind("value") + ], + ( + currentPage: number, + dispTotal: number, + _: Notification[], + showPgr: boolean + ) => { + if (showPgr === false) { + return []; + } + return [ + Widget.Button({ + hexpand: true, + hpack: "start", + class_name: `pager-button left ${currentPage <= 1 ? "disabled" : ""}`, + onPrimaryClick: () => { + curPage.value = 1; + }, + child: Widget.Label({ + className: "pager-button-label", + label: "" + }), }), - }), - Widget.Button({ - hexpand: true, - hpack: "start", - class_name: `pager-button left ${currentPage <= 1 ? "disabled" : ""}`, - onPrimaryClick: () => { - curPage.value = currentPage <= 1 ? 1 : currentPage - 1; - }, - child: Widget.Label({ - className: "pager-button-label", - label: "" + Widget.Button({ + hexpand: true, + hpack: "start", + class_name: `pager-button left ${currentPage <= 1 ? "disabled" : ""}`, + onPrimaryClick: () => { + curPage.value = currentPage <= 1 ? 1 : currentPage - 1; + }, + child: Widget.Label({ + className: "pager-button-label", + label: "" + }), }), - }), - Widget.Label({ - hexpand: true, - hpack: "center", - class_name: "pager-label", - label: `${currentPage} / ${Math.ceil(notifs.notifications.length / dispTotal) || 1}` - }), - Widget.Button({ - hexpand: true, - hpack: "end", - class_name: `pager-button right ${currentPage >= Math.ceil(notifs.notifications.length / dispTotal) ? "disabled" : ""}`, - onPrimaryClick: () => { - const maxPage = Math.ceil(notifs.notifications.length / displayedTotal.value); - curPage.value = currentPage >= maxPage ? currentPage : currentPage + 1; - }, - child: Widget.Label({ - className: "pager-button-label", - label: "" + Widget.Label({ + hexpand: true, + hpack: "center", + class_name: "pager-label", + label: `${currentPage} / ${Math.ceil(notifs.notifications.length / dispTotal) || 1}` }), - }), - Widget.Button({ - hexpand: true, - hpack: "end", - class_name: `pager-button right ${currentPage >= Math.ceil(notifs.notifications.length / dispTotal) ? "disabled" : ""}`, - onPrimaryClick: () => { - const maxPage = Math.ceil(notifs.notifications.length / displayedTotal.value); - curPage.value = maxPage; - }, - child: Widget.Label({ - className: "pager-button-label", - label: "󰄾" + Widget.Button({ + hexpand: true, + hpack: "end", + class_name: `pager-button right ${currentPage >= Math.ceil(notifs.notifications.length / dispTotal) ? "disabled" : ""}`, + onPrimaryClick: () => { + const maxPage = Math.ceil(notifs.notifications.length / displayedTotal.value); + curPage.value = currentPage >= maxPage ? currentPage : currentPage + 1; + }, + child: Widget.Label({ + className: "pager-button-label", + label: "" + }), }), - }), - ] - }) + Widget.Button({ + hexpand: true, + hpack: "end", + class_name: `pager-button right ${currentPage >= Math.ceil(notifs.notifications.length / dispTotal) ? "disabled" : ""}`, + onPrimaryClick: () => { + const maxPage = Math.ceil(notifs.notifications.length / displayedTotal.value); + curPage.value = maxPage; + }, + child: Widget.Label({ + className: "pager-button-label", + label: "󰄾" + }), + }), + ] + }) }) } diff --git a/scss/style/menus/notifications.scss b/scss/style/menus/notifications.scss index b71492e..5f2d735 100644 --- a/scss/style/menus/notifications.scss +++ b/scss/style/menus/notifications.scss @@ -94,7 +94,7 @@ .clear-notifications-button { margin-right: 0.3em; - &:hover label { + &:hover label:not(.removing) { color: transparentize(if($bar-menus-monochrome, $bar-menus-buttons-default, $bar-menus-menu-notifications-clear), 0.5); } } @@ -102,6 +102,10 @@ .clear-notifications-label { color: if($bar-menus-monochrome, $bar-menus-buttons-default, $bar-menus-menu-notifications-clear); font-size: 1.5em; + + &.removing { + color: $bar-menus-buttons-disabled; + } } scrollbar {