Added filters for notifications and system tray items. (#234)

* Added filters for notifications and systray. closes #233

* Add links to documentation.
This commit is contained in:
Jas Singh
2024-09-08 02:01:13 -07:00
committed by GitHub
parent bd573ec4e7
commit 4f91bb8b8f
22 changed files with 630 additions and 174 deletions

View File

@@ -46,6 +46,7 @@ const BatteryLabel = () => {
default: "style1",
split: "style2",
wave: "style3",
wave2: "style3",
};
return `battery ${styleMap[style]} ${!showLabel ? "no-label" : ""}`;
}),

View File

@@ -32,6 +32,7 @@ const Bluetooth = () => {
default: "style1",
split: "style2",
wave: "style3",
wave2: "style3",
};
return `bluetooth ${styleMap[style]} ${!showLabel ? "no-label" : ""}`;
}),

View File

@@ -33,6 +33,7 @@ const Clock = () => {
default: "style1",
split: "style2",
wave: "style3",
wave2: "style3",
};
return `bluetooth ${styleMap[btnStyle]} ${!shwLbl ? "no-label" : ""} ${!shwIcn ? "no-icon" : ""}`;

View File

@@ -70,6 +70,7 @@ const Media = () => {
default: "style1",
split: "style2",
wave: "style3",
wave2: "style3",
};
return `media ${styleMap[style]}`;
}),

View File

@@ -10,6 +10,7 @@ const Menu = () => {
default: "style1",
split: "style2",
wave: "style3",
wave2: "style3",
};
return `dashboard ${styleMap[style]}`;
}),

View File

@@ -15,6 +15,7 @@ const Network = () => {
default: "style1",
split: "style2",
wave: "style3",
wave2: "style3",
};
return `network ${styleMap[style]}${!showLabel ? " no-label" : ""}`;
}),

View File

@@ -1,8 +1,10 @@
import Gdk from 'gi://Gdk?version=3.0';
import { openMenu } from "../utils.js";
import options from "options";
import { filterNotifications } from 'lib/shared/notifications.js';
const { show_total } = options.bar.notifications;
const { ignore } = options.notifications;
const notifs = await Service.import("notifications");
@@ -10,30 +12,41 @@ export const Notifications = () => {
return {
component: Widget.Box({
hpack: "start",
className: Utils.merge([options.theme.bar.buttons.style.bind("value"), show_total.bind("value")], (style, showTotal) => {
const styleMap = {
default: "style1",
split: "style2",
wave: "style3",
};
return `notifications ${styleMap[style]} ${!showTotal ? "no-label" : ""}`;
}),
className: Utils.merge(
[
options.theme.bar.buttons.style.bind("value"),
show_total.bind("value")
],
(
style,
showTotal
) => {
const styleMap = {
default: "style1",
split: "style2",
wave: "style3",
wave2: "style3",
};
return `notifications ${styleMap[style]} ${!showTotal ? "no-label" : ""}`;
}),
child: Widget.Box({
hpack: "start",
class_name: "bar-notifications",
children: Utils.merge(
[notifs.bind("notifications"), notifs.bind("dnd"), show_total.bind("value")],
(notif, dnd, showTotal) => {
[notifs.bind("notifications"), notifs.bind("dnd"), show_total.bind("value"), ignore.bind("value")],
(notif, dnd, showTotal, ignoredNotifs) => {
const filteredNotifications = filterNotifications(notif, ignoredNotifs);
const notifIcon = Widget.Label({
hpack: "center",
class_name: "bar-button-icon notifications txt-icon bar",
label: dnd ? "󰂛" : notif.length > 0 ? "󱅫" : "󰂚",
label: dnd ? "󰂛" : filteredNotifications.length > 0 ? "󱅫" : "󰂚",
});
const notifLabel = Widget.Label({
hpack: "center",
class_name: "bar-button-label notifications",
label: notif.length.toString(),
label: filteredNotifications.length.toString(),
});
if (showTotal) {

View File

@@ -1,4 +1,5 @@
import Gdk from 'gi://Gdk?version=3.0';
import { Notify } from 'lib/utils';
const systemtray = await Service.import("systemtray");
import options from "options";
@@ -27,6 +28,7 @@ const SysTray = () => {
}),
on_primary_click: (_: any, event: Gdk.Event) => item.activate(event),
on_secondary_click: (_, event) => item.openMenu(event),
onMiddleClick: () => Notify({ summary: "App Name", body: item.id }),
tooltip_markup: item.bind("tooltip_markup"),
});
});

View File

@@ -2,9 +2,11 @@ import Gdk from 'gi://Gdk?version=3.0';
const audio = await Service.import("audio");
import { openMenu } from "../utils.js";
import options from "options";
import { Binding } from 'lib/utils.js';
import { VolumeIcons } from 'lib/types/volume.js';
const Volume = () => {
const icons = {
const icons: VolumeIcons = {
101: "󰕾",
66: "󰕾",
34: "󰖀",
@@ -13,16 +15,16 @@ const Volume = () => {
};
const getIcon = () => {
const icon = Utils.merge(
const icon: Binding<number> = Utils.merge(
[audio.speaker.bind("is_muted"), audio.speaker.bind("volume")],
(isMuted, vol) => {
return isMuted
? 0
: [101, 66, 34, 1, 0].find((threshold) => threshold <= vol * 100);
: [101, 66, 34, 1, 0].find((threshold) => threshold <= vol * 100) || 101;
},
);
return icon.as((i) => i !== undefined ? icons[i] : 101);
return icon.as((i: number) => i !== undefined ? icons[i] : icons[101]);
};
const volIcn = Widget.Label({
@@ -46,6 +48,7 @@ const Volume = () => {
default: "style1",
split: "style2",
wave: "style3",
wave2: "style3",
};
return `volume ${styleMap[style]} ${!showLabel ? "no-label" : ""}`;

View File

@@ -140,6 +140,7 @@ const ClientTitle = () => {
default: "style1",
split: "style2",
wave: "style3",
wave2: "style3",
};
return `windowtitle ${styleMap[style]} ${!showLabel ? "no-label" : ""}`;
}),

View File

@@ -8,8 +8,9 @@ import { Body } from "./body/index.js";
import { CloseButton } from "./close/index.js";
import options from "options.js";
import { Variable } from "types/variable.js";
import { filterNotifications } from "lib/shared/notifications.js";
const { displayedTotal } = options.notifications;
const { displayedTotal, ignore } = options.notifications;
const NotificationCard = (notifs: Notifications, curPage: Variable<number>) => {
return Widget.Scrollable({
@@ -21,46 +22,60 @@ const NotificationCard = (notifs: Notifications, curPage: Variable<number>) => {
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,
);
Utils.merge(
[
notifs.bind("notifications"),
curPage.bind("value"),
displayedTotal.bind("value"),
ignore.bind("value")
],
(
notifications,
currentPage,
dispTotal,
ignoredNotifs
) => {
const filteredNotifications = filterNotifications(notifications, ignoredNotifs);
if (notifications.length <= 0) {
return (self.children = [Placeholder(notifs)]);
}
const sortedNotifications = filteredNotifications.sort(
(a, b) => b.time - a.time,
);
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),
],
});
}));
});
if (filteredNotifications.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

@@ -7,9 +7,11 @@ import { Header } from "./header/index.js";
import { Body } from "./body/index.js";
import { CloseButton } from "./close/index.js";
import { getPosition } from "lib/utils.js";
import { filterNotifications } from "lib/shared/notifications.js";
import { Notification } from "types/service/notifications.js";
const hyprland = await Service.import("hyprland");
const { position, timeout, cache_actions, monitor, active_monitor, displayedTotal } = options.notifications;
const { position, timeout, cache_actions, monitor, active_monitor, displayedTotal, ignore } = options.notifications;
const curMonitor = Variable(monitor.value);
@@ -46,8 +48,10 @@ export default () => {
vertical: true,
hexpand: true,
setup: (self) => {
self.hook(notifs, () => {
return (self.children = notifs.popups.slice(0, displayedTotal.value).map((notif) => {
Utils.merge([notifs.bind("popups"), ignore.bind("value")], (notifications: Notification[], ignoredNotifs: string[]) => {
const filteredNotifications = filterNotifications(notifications, ignoredNotifs);
return (self.children = filteredNotifications.slice(0, displayedTotal.value).map((notif) => {
return Widget.Box({
class_name: "notification-card",
vpack: "start",
@@ -65,7 +69,7 @@ export default () => {
],
});
}));
});
})
},
}),
});