diff --git a/modules/menus/notifications/notification/index.ts b/modules/menus/notifications/notification/index.ts index 9254327..2e3dd82 100644 --- a/modules/menus/notifications/notification/index.ts +++ b/modules/menus/notifications/notification/index.ts @@ -12,7 +12,7 @@ import { filterNotifications } from 'lib/shared/notifications.js'; import Scrollable from 'types/widgets/scrollable.js'; import { Attribute, Child } from 'lib/types/widget.js'; -const { displayedTotal, ignore } = options.notifications; +const { displayedTotal, ignore, showActionsOnHover } = options.notifications; const NotificationCard = (notifs: Notifications, curPage: Variable): Scrollable => { return Widget.Scrollable({ @@ -30,8 +30,9 @@ const NotificationCard = (notifs: Notifications, curPage: Variable): Scr curPage.bind('value'), displayedTotal.bind('value'), ignore.bind('value'), + showActionsOnHover.bind('value'), ], - (notifications, currentPage, dispTotal, ignoredNotifs) => { + (notifications, currentPage, dispTotal, ignoredNotifs, showActions) => { const filteredNotifications = filterNotifications(notifications, ignoredNotifs); const sortedNotifications = filteredNotifications.sort((a, b) => b.time - a.time); @@ -45,27 +46,49 @@ const NotificationCard = (notifs: Notifications, curPage: Variable): Scr return (self.children = sortedNotifications .slice(pageStart, pageEnd) .map((notif: Notification) => { - return Widget.Box({ - class_name: 'notification-card-content-container', - children: [ - Widget.Box({ - class_name: 'notification-card menu', - vpack: 'start', - hexpand: true, - vexpand: false, - children: [ - Image(notif), - Widget.Box({ - vpack: 'center', - vertical: true, - hexpand: true, - class_name: `notification-card-content ${!notifHasImg(notif) ? 'noimg' : ' menu'}`, - children: [Header(notif), Body(notif), Actions(notif, notifs)], - }), - ], - }), - CloseButton(notif, notifs), - ], + const actionsbox = + notif.actions.length > 0 + ? Widget.Revealer({ + transition: 'slide_down', + reveal_child: showActions ? false : true, + child: Widget.EventBox({ + child: Actions(notif, notifs), + }), + }) + : null; + + return Widget.EventBox({ + on_hover() { + if (actionsbox && showActions) actionsbox.reveal_child = true; + }, + on_hover_lost() { + if (actionsbox && showActions) actionsbox.reveal_child = false; + }, + child: Widget.Box({ + class_name: 'notification-card-content-container', + children: [ + Widget.Box({ + class_name: 'notification-card menu', + vpack: 'start', + hexpand: true, + vexpand: false, + children: [ + Image(notif), + Widget.Box({ + vpack: 'center', + vertical: true, + hexpand: true, + class_name: `notification-card-content ${!notifHasImg(notif) ? 'noimg' : ' menu'}`, + + children: actionsbox + ? [Header(notif), Body(notif), actionsbox] + : [Header(notif), Body(notif)], + }), + ], + }), + CloseButton(notif, notifs), + ], + }), }); })); }, diff --git a/modules/notifications/index.ts b/modules/notifications/index.ts index 9731210..d373cd9 100644 --- a/modules/notifications/index.ts +++ b/modules/notifications/index.ts @@ -14,7 +14,8 @@ import Box from 'types/widgets/box.js'; import { Attribute, Child } from 'lib/types/widget.js'; const hyprland = await Service.import('hyprland'); -const { position, timeout, cache_actions, monitor, active_monitor, displayedTotal, ignore } = options.notifications; +const { position, timeout, cache_actions, monitor, active_monitor, displayedTotal, ignore, showActionsOnHover } = + options.notifications; const curMonitor = Variable(monitor.value); @@ -50,15 +51,32 @@ export default (): Window, unknown> => { hexpand: true, setup: (self) => { Utils.merge( - [notifs.bind('popups'), ignore.bind('value')], - (notifications: Notification[], ignoredNotifs: string[]) => { + [notifs.bind('popups'), ignore.bind('value'), showActionsOnHover.bind('value')], + (notifications: Notification[], ignoredNotifs: string[], showActions: boolean) => { const filteredNotifications = filterNotifications(notifications, ignoredNotifs); return (self.children = filteredNotifications.slice(0, displayedTotal.value).map((notif) => { + const actionsbox = + notif.actions.length > 0 + ? Widget.Revealer({ + transition: 'slide_down', + reveal_child: showActions ? false : true, + child: Widget.EventBox({ + child: Action(notif, notifs), + }), + }) + : null; + return Widget.EventBox({ on_secondary_click: () => { notifs.CloseNotification(notif.id); }, + on_hover() { + if (actionsbox && showActions) actionsbox.reveal_child = true; + }, + on_hover_lost() { + if (actionsbox && showActions) actionsbox.reveal_child = false; + }, child: Widget.Box({ class_name: 'notification-card', vpack: 'start', @@ -70,7 +88,9 @@ export default (): Window, unknown> => { vertical: true, hexpand: true, class_name: `notification-card-content ${!notifHasImg(notif) ? 'noimg' : ''}`, - children: [Header(notif), Body(notif), Action(notif, notifs)], + children: actionsbox + ? [Header(notif), Body(notif), actionsbox] + : [Header(notif), Body(notif)], }), CloseButton(notif, notifs), ], diff --git a/options.ts b/options.ts index bd71306..5d7b5fc 100644 --- a/options.ts +++ b/options.ts @@ -1211,6 +1211,7 @@ const options = mkOptions(OPTIONS, { displayedTotal: opt(10), monitor: opt(0), active_monitor: opt(true), + showActionsOnHover: opt(false), timeout: opt(7000), cache_actions: opt(true), clearDelay: opt(100), diff --git a/widget/settings/pages/config/notifications/index.ts b/widget/settings/pages/config/notifications/index.ts index 4191d4f..0c633ed 100644 --- a/widget/settings/pages/config/notifications/index.ts +++ b/widget/settings/pages/config/notifications/index.ts @@ -39,6 +39,12 @@ export const NotificationSettings = (): Scrollable => { subtitle: 'The ID of the monitor on which to display the notification', type: 'number', }), + Option({ + opt: options.notifications.showActionsOnHover, + title: 'Show Actions only on Hover', + subtitle: 'Show the action buttons only when hovering over a notification', + type: 'boolean', + }), Option({ opt: options.notifications.active_monitor, title: 'Follow Cursor',