Added pagination to the notifications menu and a configurable limit to the amount of notifications spawned. (#199)

* Added notification pagination and pagination configuration options. fixes #171

* Added skip to end buttons

* Update theme

* Removed unused theme parts

* Update pager colors

* Theme auto-generator

* Update label color in options for pager.

* Updated themes

* Added option to change footer background for notifications menu.

* Changes to the Displayed Total options now update the menu. Bugfix
This commit is contained in:
Jas Singh
2024-08-30 01:32:11 -07:00
committed by GitHub
parent f80b3e4ef6
commit f624153eab
39 changed files with 1586 additions and 1317 deletions

View File

@@ -1,4 +1,6 @@
const Controls = (notifs) => {
import { Notifications } from "types/service/notifications";
const Controls = (notifs: Notifications) => {
return Widget.Box({
class_name: "notification-menu-controls",
expand: false,

View File

@@ -2,25 +2,47 @@ import DropdownMenu from "../DropdownMenu.js";
const notifs = await Service.import("notifications");
import { Controls } from "./controls/index.js";
import { NotificationCard } from "./notification/index.js";
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 () => {
return DropdownMenu({
name: "notificationsmenu",
transition: "crossfade",
child: Widget.Box({
class_name: "notification-menu-content",
css: "padding: 1px; margin: -1px;",
hexpand: true,
vexpand: false,
children: [
Widget.Box({
class_name: "notification-card-container menu",
vertical: true,
hexpand: false,
vexpand: false,
children: [Controls(notifs), NotificationCard(notifs)],
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;
}
});
return DropdownMenu({
name: "notificationsmenu",
transition: "crossfade",
child: Widget.Box({
class_name: "notification-menu-content",
css: "padding: 1px; margin: -1px;",
hexpand: true,
vexpand: false,
children: [
Widget.Box({
class_name: "notification-card-container menu",
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)]
})
}),
],
}),
],
}),
});
});
};

View File

@@ -6,54 +6,63 @@ import { Image } from "./image/index.js";
import { Placeholder } from "./placeholder/index.js";
import { Body } from "./body/index.js";
import { CloseButton } from "./close/index.js";
import options from "options.js";
import { Variable } from "types/variable.js";
const NotificationCard = (notifs: Notifications) => {
return Widget.Box({
class_name: "menu-content-container notifications",
hpack: "center",
vexpand: true,
spacing: 0,
vertical: true,
setup: (self) => {
self.hook(notifs, () => {
const sortedNotifications = notifs.notifications.sort(
(a, b) => b.time - a.time,
);
const { displayedTotal } = options.notifications;
if (notifs.notifications.length <= 0) {
return (self.children = [Placeholder(notifs)]);
}
const NotificationCard = (notifs: Notifications, curPage: Variable<number>) => {
return Widget.Scrollable({
vscroll: "automatic",
child: Widget.Box({
class_name: "menu-content-container notifications",
hpack: "center",
vexpand: true,
spacing: 0,
vertical: true,
setup: (self) => {
Utils.merge([notifs.bind("notifications"), curPage.bind("value"), displayedTotal.bind("value")], (notifications, currentPage, dispTotal) => {
const sortedNotifications = notifications.sort(
(a, b) => b.time - a.time,
);
return (self.children = sortedNotifications.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),
],
});
}));
});
},
if (notifications.length <= 0) {
return (self.children = [Placeholder(notifs)]);
}
const pageStart = (currentPage - 1) * dispTotal;
const pageEnd = currentPage * dispTotal;
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),
],
});
}));
});
},
})
});
};

View File

@@ -0,0 +1,74 @@
const notifs = await Service.import("notifications");
import options from "options";
import { Variable } from "types/variable";
const { displayedTotal } = options.notifications;
export const NotificationPager = (curPage: Variable<number>) => {
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, notifications) => {
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.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.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: "󰄾"
}),
}),
]
})
})
}