fix(ags notifs): refactor and make notifs work with latest ags
This commit is contained in:
parent
6a40c0141d
commit
b2e4c84545
5 changed files with 189 additions and 220 deletions
|
@ -4,8 +4,8 @@ import { exec } from 'resource:///com/github/Aylur/ags/utils.js';
|
||||||
import Setup from './js/setup.js';
|
import Setup from './js/setup.js';
|
||||||
import Powermenu from './js/powermenu.js';
|
import Powermenu from './js/powermenu.js';
|
||||||
import * as Bar from './js/bar/main.js';
|
import * as Bar from './js/bar/main.js';
|
||||||
//import NotifCenter from './js/notifications/center.js';
|
import NotifCenter from './js/notifications/center.js';
|
||||||
//import NotifPopups from './js/notifications/popup.js';
|
import NotifPopups from './js/notifications/popup.js';
|
||||||
import Calendar from './js/date.js';
|
import Calendar from './js/date.js';
|
||||||
import QuickSettings from './js/quick-settings/main.js';
|
import QuickSettings from './js/quick-settings/main.js';
|
||||||
//import Overview from './js/overview/main.js';
|
//import Overview from './js/overview/main.js';
|
||||||
|
@ -18,7 +18,6 @@ exec(`sassc ${scss} ${css}`);
|
||||||
Setup();
|
Setup();
|
||||||
|
|
||||||
|
|
||||||
// FIXME: notification and overview stuff are bugged as of this ags commit
|
|
||||||
export default {
|
export default {
|
||||||
style: css,
|
style: css,
|
||||||
notificationPopupTimeout: 5000,
|
notificationPopupTimeout: 5000,
|
||||||
|
@ -34,7 +33,7 @@ export default {
|
||||||
windows: [
|
windows: [
|
||||||
AppLauncher(),
|
AppLauncher(),
|
||||||
Calendar(),
|
Calendar(),
|
||||||
//NotifCenter(),
|
NotifCenter(),
|
||||||
//Overview(),
|
//Overview(),
|
||||||
Powermenu(),
|
Powermenu(),
|
||||||
QuickSettings(),
|
QuickSettings(),
|
||||||
|
@ -43,6 +42,6 @@ export default {
|
||||||
Bar.BgGradient(),
|
Bar.BgGradient(),
|
||||||
Corners.Bottomleft(),
|
Corners.Bottomleft(),
|
||||||
Corners.Bottomright(),
|
Corners.Bottomright(),
|
||||||
//NotifPopups(),
|
NotifPopups(),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ import Applications from 'resource:///com/github/Aylur/ags/service/applications.
|
||||||
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
|
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
|
||||||
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
|
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
|
||||||
import { Box, Icon, Label, Button } from 'resource:///com/github/Aylur/ags/widget.js';
|
import { Box, Icon, Label, Button } from 'resource:///com/github/Aylur/ags/widget.js';
|
||||||
import { lookUpIcon, execAsync, timeout } from 'resource:///com/github/Aylur/ags/utils.js';
|
import { lookUpIcon, execAsync } from 'resource:///com/github/Aylur/ags/utils.js';
|
||||||
|
|
||||||
import GLib from 'gi://GLib';
|
import GLib from 'gi://GLib';
|
||||||
|
|
||||||
|
@ -48,15 +48,17 @@ const NotificationIcon = notif => {
|
||||||
return EventBox({
|
return EventBox({
|
||||||
onPrimaryClickRelease: iconCmd,
|
onPrimaryClickRelease: iconCmd,
|
||||||
child: Box({
|
child: Box({
|
||||||
valign: 'start',
|
vpack: 'start',
|
||||||
hexpand: false,
|
hexpand: false,
|
||||||
className: 'icon img',
|
className: 'icon img',
|
||||||
style: `background-image: url("${notif.image}");
|
css: `
|
||||||
background-size: contain;
|
background-image: url("${notif.image}");
|
||||||
background-repeat: no-repeat;
|
background-size: contain;
|
||||||
background-position: center;
|
background-repeat: no-repeat;
|
||||||
min-width: 78px;
|
background-position: center;
|
||||||
min-height: 78px;`,
|
min-width: 78px;
|
||||||
|
min-height: 78px;
|
||||||
|
`,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -73,16 +75,16 @@ const NotificationIcon = notif => {
|
||||||
return EventBox({
|
return EventBox({
|
||||||
onPrimaryClickRelease: iconCmd,
|
onPrimaryClickRelease: iconCmd,
|
||||||
child: Box({
|
child: Box({
|
||||||
valign: 'start',
|
vpack: 'start',
|
||||||
hexpand: false,
|
hexpand: false,
|
||||||
className: 'icon',
|
className: 'icon',
|
||||||
style: `min-width: 78px;
|
css: `min-width: 78px;
|
||||||
min-height: 78px;`,
|
min-height: 78px;`,
|
||||||
children: [Icon({
|
children: [Icon({
|
||||||
icon, size: 58,
|
icon, size: 58,
|
||||||
halign: 'center',
|
hpack: 'center',
|
||||||
hexpand: true,
|
hexpand: true,
|
||||||
valign: 'center',
|
vpack: 'center',
|
||||||
vexpand: true,
|
vexpand: true,
|
||||||
})],
|
})],
|
||||||
}),
|
}),
|
||||||
|
@ -114,37 +116,11 @@ export const Notification = ({
|
||||||
|
|
||||||
// Init notif
|
// Init notif
|
||||||
const notifWidget = Gesture({
|
const notifWidget = Gesture({
|
||||||
maxOffset: 200,
|
command,
|
||||||
command: () => command(),
|
|
||||||
slideIn,
|
slideIn,
|
||||||
properties: [
|
id: notif.id,
|
||||||
['hovered', false],
|
|
||||||
['id', notif.id],
|
|
||||||
],
|
|
||||||
onHover: w => {
|
|
||||||
if (!w._hovered)
|
|
||||||
w._hovered = true;
|
|
||||||
},
|
|
||||||
onHoverLost: w => {
|
|
||||||
if (w._hovered)
|
|
||||||
w._hovered = false;
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Notif methods
|
|
||||||
notifWidget.slideAway = side => {
|
|
||||||
notifWidget.child.setStyle(notifWidget.child[`_slide${side}`]);
|
|
||||||
notifWidget.sensitive = false;
|
|
||||||
timeout(400, () => {
|
|
||||||
notifWidget.child.setStyle(notifWidget.child[`_squeeze${side}`]);
|
|
||||||
timeout(500, () => {
|
|
||||||
HasNotifs.value = Notifications.notifications.length > 0;
|
|
||||||
notifWidget.get_parent().remove(notifWidget);
|
|
||||||
notifWidget.destroy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add body to notif
|
// Add body to notif
|
||||||
notifWidget.child.add(Box({
|
notifWidget.child.add(Box({
|
||||||
className: `notification ${notif.urgency}`,
|
className: `notification ${notif.urgency}`,
|
||||||
|
@ -177,14 +153,14 @@ export const Notification = ({
|
||||||
}),
|
}),
|
||||||
Label({
|
Label({
|
||||||
className: 'time',
|
className: 'time',
|
||||||
valign: 'start',
|
vpack: 'start',
|
||||||
label: setTime(notif.time),
|
label: setTime(notif.time),
|
||||||
}),
|
}),
|
||||||
EventBox({
|
EventBox({
|
||||||
reset: false,
|
reset: false,
|
||||||
child: Button({
|
child: Button({
|
||||||
className: 'close-button',
|
className: 'close-button',
|
||||||
valign: 'start',
|
vpack: 'start',
|
||||||
onClicked: () => notif.close(),
|
onClicked: () => notif.close(),
|
||||||
child: Icon('window-close-symbolic'),
|
child: Icon('window-close-symbolic'),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -2,10 +2,56 @@ import Notifications from 'resource:///com/github/Aylur/ags/service/notification
|
||||||
import { Button, Label, Box, Icon, Scrollable, Revealer } from 'resource:///com/github/Aylur/ags/widget.js';
|
import { Button, Label, Box, Icon, Scrollable, Revealer } from 'resource:///com/github/Aylur/ags/widget.js';
|
||||||
|
|
||||||
import { Notification, HasNotifs } from './base.js';
|
import { Notification, HasNotifs } from './base.js';
|
||||||
import PopupWindow from '../misc/popup.js';
|
import PopupWindow from '../misc/popup.js';
|
||||||
import EventBox from '../misc/cursorbox.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
|
|
||||||
|
|
||||||
|
const addNotif = (box, notif) => {
|
||||||
|
if (!notif)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const NewNotif = Notification({
|
||||||
|
notif,
|
||||||
|
slideIn: 'Right',
|
||||||
|
command: () => notif.close(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (NewNotif) {
|
||||||
|
box.pack_end(NewNotif, false, false, 0);
|
||||||
|
box.show_all();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const NotificationList = () => Box({
|
||||||
|
vertical: true,
|
||||||
|
vexpand: true,
|
||||||
|
vpack: 'start',
|
||||||
|
binds: [['visible', HasNotifs]],
|
||||||
|
setup: box => {
|
||||||
|
// Get cached notifications
|
||||||
|
const id = Notifications.connect('changed', () => {
|
||||||
|
Notifications.notifications.forEach(notif => {
|
||||||
|
addNotif(box, notif);
|
||||||
|
});
|
||||||
|
Notifications.disconnect(id);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
connections: [
|
||||||
|
[Notifications, (box, id) => {
|
||||||
|
if (!id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
addNotif(box, Notifications.getNotification(id));
|
||||||
|
}, 'notified'],
|
||||||
|
|
||||||
|
[Notifications, (box, id) => {
|
||||||
|
const notif = box.children.find(ch => ch._id === id);
|
||||||
|
if (notif?.sensitive)
|
||||||
|
notif.slideAway('Right');
|
||||||
|
}, 'closed'],
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
// Needs to be wrapped to still have onHover when disabled
|
// Needs to be wrapped to still have onHover when disabled
|
||||||
const ClearButton = () => EventBox({
|
const ClearButton = () => EventBox({
|
||||||
child: Button({
|
child: Button({
|
||||||
|
@ -37,65 +83,14 @@ const Header = () => Box({
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const NotificationList = () => Box({
|
|
||||||
vertical: true,
|
|
||||||
vexpand: true,
|
|
||||||
valign: 'start',
|
|
||||||
binds: [['visible', HasNotifs]],
|
|
||||||
connections: [
|
|
||||||
[Notifications, (box, id) => {
|
|
||||||
if (box.children.length == 0) {
|
|
||||||
for (const notif of Notifications.notifications) {
|
|
||||||
if (!notif)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const NewNotif = Notification({
|
|
||||||
notif,
|
|
||||||
slideIn: 'Right',
|
|
||||||
command: () => notif.close(),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (NewNotif) {
|
|
||||||
box.pack_end(NewNotif, false, false, 0);
|
|
||||||
box.show_all();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (id) {
|
|
||||||
const notif = Notifications.getNotification(id);
|
|
||||||
|
|
||||||
const NewNotif = Notification({
|
|
||||||
notif,
|
|
||||||
slideIn: 'Right',
|
|
||||||
command: () => notif.close(),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (NewNotif) {
|
|
||||||
box.pack_end(NewNotif, false, false, 0);
|
|
||||||
box.show_all();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 'notified'],
|
|
||||||
|
|
||||||
[Notifications, (box, id) => {
|
|
||||||
for (const ch of box.children) {
|
|
||||||
if (ch._id == id) {
|
|
||||||
ch.slideAway('Right');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 'closed'],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
const Placeholder = () => Revealer({
|
const Placeholder = () => Revealer({
|
||||||
transition: 'crossfade',
|
transition: 'crossfade',
|
||||||
binds: [['revealChild', HasNotifs, 'value', value => !value]],
|
binds: [['revealChild', HasNotifs, 'value', value => !value]],
|
||||||
child: Box({
|
child: Box({
|
||||||
className: 'placeholder',
|
className: 'placeholder',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
valign: 'center',
|
vpack: 'center',
|
||||||
halign: 'center',
|
hpack: 'center',
|
||||||
vexpand: true,
|
vexpand: true,
|
||||||
hexpand: true,
|
hexpand: true,
|
||||||
children: [
|
children: [
|
||||||
|
@ -133,6 +128,6 @@ const NotificationCenterWidget = () => Box({
|
||||||
export default () => PopupWindow({
|
export default () => PopupWindow({
|
||||||
name: 'notification-center',
|
name: 'notification-center',
|
||||||
anchor: ['top', 'right'],
|
anchor: ['top', 'right'],
|
||||||
margin: [6, 60, 0, 0],
|
margins: [6, 60, 0, 0],
|
||||||
child: NotificationCenterWidget(),
|
child: NotificationCenterWidget(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,40 +1,43 @@
|
||||||
|
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
|
||||||
import { Box, EventBox } from 'resource:///com/github/Aylur/ags/widget.js';
|
import { Box, EventBox } from 'resource:///com/github/Aylur/ags/widget.js';
|
||||||
import { timeout } from 'resource:///com/github/Aylur/ags/utils.js';
|
import { timeout } from 'resource:///com/github/Aylur/ags/utils.js';
|
||||||
|
|
||||||
|
import { HasNotifs } from './base.js';
|
||||||
|
|
||||||
import Gtk from 'gi://Gtk';
|
import Gtk from 'gi://Gtk';
|
||||||
import Gdk from 'gi://Gdk';
|
import Gdk from 'gi://Gdk';
|
||||||
const display = Gdk.Display.get_default();
|
const display = Gdk.Display.get_default();
|
||||||
|
|
||||||
|
|
||||||
export default ({
|
export default ({
|
||||||
|
id,
|
||||||
slideIn = 'Left',
|
slideIn = 'Left',
|
||||||
maxOffset = 150,
|
maxOffset = 200,
|
||||||
startMargin = 0,
|
startMargin = 0,
|
||||||
endMargin = 300,
|
endMargin = 300,
|
||||||
command = () => {},
|
command = () => {},
|
||||||
onHover = () => {},
|
|
||||||
onHoverLost = () => {},
|
|
||||||
child = '',
|
|
||||||
children = [],
|
|
||||||
properties = [[]],
|
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
const widget = EventBox({
|
const widget = EventBox({
|
||||||
...props,
|
...props,
|
||||||
properties: [
|
|
||||||
['dragging', false],
|
|
||||||
...properties,
|
|
||||||
],
|
|
||||||
onHover: self => {
|
onHover: self => {
|
||||||
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
|
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
|
||||||
onHover(self);
|
if (!self._hovered)
|
||||||
|
self._hovered = true;
|
||||||
},
|
},
|
||||||
onHoverLost: self => {
|
onHoverLost: self => {
|
||||||
self.window.set_cursor(null);
|
self.window.set_cursor(null);
|
||||||
onHoverLost(self);
|
if (self._hovered)
|
||||||
|
self._hovered = false;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
widget._dragging = false;
|
||||||
|
widget._hovered = false;
|
||||||
|
widget._id = id;
|
||||||
|
widget.ready = false;
|
||||||
|
|
||||||
const gesture = Gtk.GestureDrag.new(widget);
|
const gesture = Gtk.GestureDrag.new(widget);
|
||||||
|
|
||||||
const TRANSITION = 'transition: margin 0.5s ease, opacity 0.5s ease;';
|
const TRANSITION = 'transition: margin 0.5s ease, opacity 0.5s ease;';
|
||||||
|
@ -48,32 +51,45 @@ export default ({
|
||||||
margin-right: -${Number(maxOffset + endMargin)}px;
|
margin-right: -${Number(maxOffset + endMargin)}px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const slideLeft = `${TRANSITION} ${MAX_LEFT} opacity: 0;`;
|
const slideLeft = `${TRANSITION} ${MAX_LEFT} margin-top: 0px; margin-bottom: 0px; opacity: 0;`;
|
||||||
const squeezeLeft = `${TRANSITION} ${MAX_LEFT} ${SQUEEZED} opacity: 0;`;
|
const squeezeLeft = `${TRANSITION} ${MAX_LEFT} ${SQUEEZED} opacity: 0;`;
|
||||||
const slideRight = `${TRANSITION} ${MAX_RIGHT} opacity: 0;`;
|
const slideRight = `${TRANSITION} ${MAX_RIGHT} margin-top: 0px; margin-bottom: 0px; opacity: 0;`;
|
||||||
const squeezeRight = `${TRANSITION} ${MAX_RIGHT} ${SQUEEZED} opacity: 0;`;
|
const squeezeRight = `${TRANSITION} ${MAX_RIGHT} ${SQUEEZED} opacity: 0;`;
|
||||||
|
const defaultStyle = `${TRANSITION} margin: unset; opacity: 1;`;
|
||||||
|
|
||||||
|
// Notif methods
|
||||||
|
widget.slideAway = side => {
|
||||||
|
// Slide away
|
||||||
|
widget.child.setCss(side === 'Left' ? slideLeft : slideRight);
|
||||||
|
|
||||||
|
// Makie it uninteractable
|
||||||
|
widget.sensitive = false;
|
||||||
|
|
||||||
|
timeout(400, () => {
|
||||||
|
// Reduce height after sliding away
|
||||||
|
widget.child?.setCss(side === 'Left' ? squeezeLeft : squeezeRight);
|
||||||
|
|
||||||
|
timeout(500, () => {
|
||||||
|
// Kill notif and update HasNotifs after anim is done
|
||||||
|
command();
|
||||||
|
HasNotifs.value = Notifications.notifications.length > 0;
|
||||||
|
widget.get_parent()?.remove(widget);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
widget.add(Box({
|
widget.add(Box({
|
||||||
properties: [
|
css: squeezeLeft,
|
||||||
['slideLeft', slideLeft],
|
|
||||||
['squeezeLeft', squeezeLeft],
|
|
||||||
['slideRight', slideRight],
|
|
||||||
['squeezeRight', squeezeRight],
|
|
||||||
['ready', false],
|
|
||||||
],
|
|
||||||
children: [
|
|
||||||
...children,
|
|
||||||
child,
|
|
||||||
],
|
|
||||||
style: squeezeLeft,
|
|
||||||
connections: [
|
connections: [
|
||||||
|
|
||||||
|
// When dragging
|
||||||
[gesture, self => {
|
[gesture, self => {
|
||||||
var offset = gesture.get_offset()[1];
|
var offset = gesture.get_offset()[1];
|
||||||
|
|
||||||
// Slide right
|
// Slide right
|
||||||
if (offset >= 0) {
|
if (offset >= 0) {
|
||||||
self.setStyle(`
|
self.setCss(`
|
||||||
|
margin-top: 0px; margin-bottom: 0px; opacity: 1; transition: none;
|
||||||
margin-left: ${Number(offset + startMargin)}px;
|
margin-left: ${Number(offset + startMargin)}px;
|
||||||
margin-right: -${Number(offset + startMargin)}px;
|
margin-right: -${Number(offset + startMargin)}px;
|
||||||
`);
|
`);
|
||||||
|
@ -82,26 +98,31 @@ export default ({
|
||||||
// Slide left
|
// Slide left
|
||||||
else {
|
else {
|
||||||
offset = Math.abs(offset);
|
offset = Math.abs(offset);
|
||||||
self.setStyle(`
|
self.setCss(`
|
||||||
|
margin-top: 0px; margin-bottom: 0px; opacity: 1; transition: none;
|
||||||
margin-right: ${Number(offset + startMargin)}px;
|
margin-right: ${Number(offset + startMargin)}px;
|
||||||
margin-left: -${Number(offset + startMargin)}px;
|
margin-left: -${Number(offset + startMargin)}px;
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put a threshold on if a click is actually dragging
|
// Put a threshold on if a click is actually dragging
|
||||||
self.get_parent()._dragging = Math.abs(offset) > 10;
|
widget._dragging = Math.abs(offset) > 10;
|
||||||
|
widget.window?.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing'));
|
||||||
if (widget.window)
|
|
||||||
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing'));
|
|
||||||
}, 'drag-update'],
|
}, 'drag-update'],
|
||||||
|
|
||||||
|
|
||||||
|
// On drag end
|
||||||
[gesture, self => {
|
[gesture, self => {
|
||||||
// Make it slide in on init
|
// Make it slide in on init
|
||||||
if (!self._ready) {
|
if (!widget.ready) {
|
||||||
self.setStyle(slideIn === 'Left' ? slideLeft : slideRight);
|
// Reverse of slideAway, so it started at squeeze, then we go to slide
|
||||||
|
self.setCss(slideIn === 'Left' ? slideLeft : slideRight);
|
||||||
|
|
||||||
timeout(500, () => self.setStyle(`${TRANSITION} margin: unset; opacity: 1;`));
|
timeout(500, () => {
|
||||||
timeout(1000, () => self._ready = true);
|
// Then we got to center
|
||||||
|
self.setCss(defaultStyle);
|
||||||
|
timeout(500, () => widget.ready = true);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,35 +130,16 @@ export default ({
|
||||||
|
|
||||||
// If crosses threshold after letting go, slide away
|
// If crosses threshold after letting go, slide away
|
||||||
if (Math.abs(offset) > maxOffset) {
|
if (Math.abs(offset) > maxOffset) {
|
||||||
// Slide away right
|
if (offset > 0)
|
||||||
if (offset > 0) {
|
widget.slideAway('Right');
|
||||||
// Disable inputs during animation
|
else
|
||||||
widget.sensitive = false;
|
widget.slideAway('Left');
|
||||||
|
|
||||||
self.setStyle(slideRight);
|
|
||||||
timeout(500, () => self.setStyle(squeezeRight));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slide away left
|
|
||||||
else {
|
|
||||||
// Disable inputs during animation
|
|
||||||
widget.sensitive = false;
|
|
||||||
|
|
||||||
self.setStyle(slideLeft);
|
|
||||||
timeout(500, () => self.setStyle(squeezeLeft));
|
|
||||||
}
|
|
||||||
|
|
||||||
timeout(1000, () => {
|
|
||||||
command();
|
|
||||||
self.destroy();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self.setStyle(`${TRANSITION} margin: unset; opacity: 1;`);
|
self.setCss(defaultStyle);
|
||||||
if (widget.window)
|
widget.window?.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
|
||||||
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
|
|
||||||
|
|
||||||
self.get_parent()._dragging = false;
|
widget._dragging = false;
|
||||||
}
|
}
|
||||||
}, 'drag-end'],
|
}, 'drag-end'],
|
||||||
|
|
||||||
|
|
|
@ -1,71 +1,68 @@
|
||||||
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
|
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
|
||||||
import { Box, Window } from 'resource:///com/github/Aylur/ags/widget.js';
|
import { Box } from 'resource:///com/github/Aylur/ags/widget.js';
|
||||||
import { interval } from 'resource:///com/github/Aylur/ags/utils.js';
|
import { interval } from 'resource:///com/github/Aylur/ags/utils.js';
|
||||||
|
|
||||||
import GLib from 'gi://GLib';
|
import GLib from 'gi://GLib';
|
||||||
|
|
||||||
import { Notification } from './base.js';
|
import { Notification } from './base.js';
|
||||||
|
import PopupWindow from '../misc/popup.js';
|
||||||
|
|
||||||
|
|
||||||
const Popups = () => Box({
|
const addPopup = (box, id) => {
|
||||||
vertical: true,
|
if (!id)
|
||||||
properties: [
|
return;
|
||||||
['notify', (box, id) => {
|
|
||||||
if (id) {
|
|
||||||
const notif = Notifications.getNotification(id);
|
|
||||||
|
|
||||||
const NewNotif = Notification({
|
const notif = Notifications.getNotification(id);
|
||||||
notif,
|
|
||||||
command: () => notif.dismiss(),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (NewNotif) {
|
const NewNotif = Notification({
|
||||||
// use this instead of add to put it at the top
|
notif,
|
||||||
box.pack_end(NewNotif, false, false, 0);
|
command: () => notif.dismiss(),
|
||||||
box.show_all();
|
});
|
||||||
}
|
|
||||||
|
if (NewNotif) {
|
||||||
|
// use this instead of add to put it at the top
|
||||||
|
box.pack_end(NewNotif, false, false, 0);
|
||||||
|
box.show_all();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDismiss = (box, id, force = false) => {
|
||||||
|
const notif = box.children.find(ch => ch._id === id);
|
||||||
|
if (!notif)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If notif isn't hovered or was closed, slide away
|
||||||
|
if (!notif._hovered || force) {
|
||||||
|
notif.slideAway('Left');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If notif is hovered, delay close
|
||||||
|
else if (notif._hovered) {
|
||||||
|
notif.interval = interval(2000, () => {
|
||||||
|
if (!notif._hovered && notif.interval) {
|
||||||
|
notif.slideAway('Left');
|
||||||
|
|
||||||
|
GLib.source_remove(notif.interval);
|
||||||
|
notif.interval = undefined;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}],
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
['dismiss', (box, id, force = false) => {
|
export default () => PopupWindow({
|
||||||
for (const ch of box.children) {
|
|
||||||
if (ch._id == id) {
|
|
||||||
// If notif isn't hovered or was closed, slide away
|
|
||||||
if (!ch._hovered || force) {
|
|
||||||
ch.slideAway('Left');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If notif is hovered, delay close
|
|
||||||
else if (ch._hovered) {
|
|
||||||
ch.interval = interval(2000, () => {
|
|
||||||
if (!ch._hovered && ch.interval) {
|
|
||||||
ch.slideAway('Left');
|
|
||||||
|
|
||||||
GLib.source_remove(ch.interval);
|
|
||||||
ch.interval = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
],
|
|
||||||
connections: [
|
|
||||||
[Notifications, (box, id) => box._notify(box, id), 'notified'],
|
|
||||||
[Notifications, (box, id) => box._dismiss(box, id), 'dismissed'],
|
|
||||||
[Notifications, (box, id) => box._dismiss(box, id, true), 'closed'],
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
export default () => Window({
|
|
||||||
name: 'notifications',
|
name: 'notifications',
|
||||||
anchor: ['top', 'left'],
|
anchor: ['top', 'left'],
|
||||||
|
visible: true,
|
||||||
|
transition: 'none',
|
||||||
|
closeOnUnfocus: 'none',
|
||||||
child: Box({
|
child: Box({
|
||||||
style: `min-height:1px;
|
vertical: true,
|
||||||
min-width:1px;
|
connections: [
|
||||||
padding: 1px;`,
|
[Notifications, (box, id) => addPopup(box, id), 'notified'],
|
||||||
children: [Popups()],
|
[Notifications, (box, id) => handleDismiss(box, id), 'dismissed'],
|
||||||
|
[Notifications, (box, id) => handleDismiss(box, id, true), 'closed'],
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue