feat: on hover only show actions if available on notifications (#396)

* feat: on hover only show actions if available on notifications

* feat: on hover only show actions if available on notifications

* fix: make the change configurable

* fix: remove unneeded op
This commit is contained in:
Rubin Bhandari
2024-11-05 12:32:26 +05:45
committed by GitHub
parent b5e91fa2dc
commit b88644833d
4 changed files with 77 additions and 27 deletions

View File

@@ -12,7 +12,7 @@ import { filterNotifications } from 'lib/shared/notifications.js';
import Scrollable from 'types/widgets/scrollable.js'; import Scrollable from 'types/widgets/scrollable.js';
import { Attribute, Child } from 'lib/types/widget.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<number>): Scrollable<Child, Attribute> => { const NotificationCard = (notifs: Notifications, curPage: Variable<number>): Scrollable<Child, Attribute> => {
return Widget.Scrollable({ return Widget.Scrollable({
@@ -30,8 +30,9 @@ const NotificationCard = (notifs: Notifications, curPage: Variable<number>): Scr
curPage.bind('value'), curPage.bind('value'),
displayedTotal.bind('value'), displayedTotal.bind('value'),
ignore.bind('value'), ignore.bind('value'),
showActionsOnHover.bind('value'),
], ],
(notifications, currentPage, dispTotal, ignoredNotifs) => { (notifications, currentPage, dispTotal, ignoredNotifs, showActions) => {
const filteredNotifications = filterNotifications(notifications, ignoredNotifs); const filteredNotifications = filterNotifications(notifications, ignoredNotifs);
const sortedNotifications = filteredNotifications.sort((a, b) => b.time - a.time); const sortedNotifications = filteredNotifications.sort((a, b) => b.time - a.time);
@@ -45,27 +46,49 @@ const NotificationCard = (notifs: Notifications, curPage: Variable<number>): Scr
return (self.children = sortedNotifications return (self.children = sortedNotifications
.slice(pageStart, pageEnd) .slice(pageStart, pageEnd)
.map((notif: Notification) => { .map((notif: Notification) => {
return Widget.Box({ const actionsbox =
class_name: 'notification-card-content-container', notif.actions.length > 0
children: [ ? Widget.Revealer({
Widget.Box({ transition: 'slide_down',
class_name: 'notification-card menu', reveal_child: showActions ? false : true,
vpack: 'start', child: Widget.EventBox({
hexpand: true, child: Actions(notif, notifs),
vexpand: false, }),
children: [ })
Image(notif), : null;
Widget.Box({
vpack: 'center', return Widget.EventBox({
vertical: true, on_hover() {
hexpand: true, if (actionsbox && showActions) actionsbox.reveal_child = true;
class_name: `notification-card-content ${!notifHasImg(notif) ? 'noimg' : ' menu'}`, },
children: [Header(notif), Body(notif), Actions(notif, notifs)], on_hover_lost() {
}), if (actionsbox && showActions) actionsbox.reveal_child = false;
], },
}), child: Widget.Box({
CloseButton(notif, notifs), 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),
],
}),
}); });
})); }));
}, },

View File

@@ -14,7 +14,8 @@ import Box from 'types/widgets/box.js';
import { Attribute, Child } from 'lib/types/widget.js'; import { Attribute, Child } from 'lib/types/widget.js';
const hyprland = await Service.import('hyprland'); 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); const curMonitor = Variable(monitor.value);
@@ -50,15 +51,32 @@ export default (): Window<Box<Child, Attribute>, unknown> => {
hexpand: true, hexpand: true,
setup: (self) => { setup: (self) => {
Utils.merge( Utils.merge(
[notifs.bind('popups'), ignore.bind('value')], [notifs.bind('popups'), ignore.bind('value'), showActionsOnHover.bind('value')],
(notifications: Notification[], ignoredNotifs: string[]) => { (notifications: Notification[], ignoredNotifs: string[], showActions: boolean) => {
const filteredNotifications = filterNotifications(notifications, ignoredNotifs); const filteredNotifications = filterNotifications(notifications, ignoredNotifs);
return (self.children = filteredNotifications.slice(0, displayedTotal.value).map((notif) => { 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({ return Widget.EventBox({
on_secondary_click: () => { on_secondary_click: () => {
notifs.CloseNotification(notif.id); 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({ child: Widget.Box({
class_name: 'notification-card', class_name: 'notification-card',
vpack: 'start', vpack: 'start',
@@ -70,7 +88,9 @@ export default (): Window<Box<Child, Attribute>, unknown> => {
vertical: true, vertical: true,
hexpand: true, hexpand: true,
class_name: `notification-card-content ${!notifHasImg(notif) ? 'noimg' : ''}`, 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), CloseButton(notif, notifs),
], ],

View File

@@ -1211,6 +1211,7 @@ const options = mkOptions(OPTIONS, {
displayedTotal: opt(10), displayedTotal: opt(10),
monitor: opt(0), monitor: opt(0),
active_monitor: opt(true), active_monitor: opt(true),
showActionsOnHover: opt(false),
timeout: opt(7000), timeout: opt(7000),
cache_actions: opt(true), cache_actions: opt(true),
clearDelay: opt(100), clearDelay: opt(100),

View File

@@ -39,6 +39,12 @@ export const NotificationSettings = (): Scrollable<Child, Attribute> => {
subtitle: 'The ID of the monitor on which to display the notification', subtitle: 'The ID of the monitor on which to display the notification',
type: 'number', 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({ Option({
opt: options.notifications.active_monitor, opt: options.notifications.active_monitor,
title: 'Follow Cursor', title: 'Follow Cursor',