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:
@@ -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),
|
||||||
|
],
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
Reference in New Issue
Block a user