114 lines
3.7 KiB
TypeScript
114 lines
3.7 KiB
TypeScript
// From astal examples
|
|
|
|
import { bind, GLib } from "astal";
|
|
import { Gtk } from "astal/gtk4";
|
|
import Notifd from "gi://AstalNotifd";
|
|
import { NotificationIcon } from "./icon";
|
|
// import Pango from "gi://Pango?version=1.0"
|
|
|
|
const fileExists = (path: string) => GLib.file_test(path, GLib.FileTest.EXISTS);
|
|
|
|
const time = (time: number, format = "%H:%M") =>
|
|
GLib.DateTime.new_from_unix_local(time).format(format)!;
|
|
|
|
const urgency = (n: Notifd.Notification) => {
|
|
const { LOW, NORMAL, CRITICAL } = Notifd.Urgency;
|
|
// match operator when?
|
|
switch (n.urgency) {
|
|
case LOW:
|
|
return "low";
|
|
case CRITICAL:
|
|
return "critical";
|
|
case NORMAL:
|
|
default:
|
|
return "normal";
|
|
}
|
|
};
|
|
|
|
type Props = {
|
|
delete: (id: number) => void;
|
|
notification: Notifd.Notification;
|
|
id: number;
|
|
};
|
|
|
|
export default function Notification(props: Props) {
|
|
const { notification: n, id: id, delete: del } = props;
|
|
const { START, CENTER, END } = Gtk.Align;
|
|
|
|
return (
|
|
<box vertical cssClasses={["notification", `${urgency(n)}`]}>
|
|
<box cssClasses={["header"]}>
|
|
{n.appIcon || n.desktopEntry ? (
|
|
<Gtk.Image
|
|
cssClasses={["app-icon"]}
|
|
visible={Boolean(n.appIcon || n.desktopEntry)}
|
|
iconName={n.appIcon || n.desktopEntry}
|
|
/>
|
|
) : (
|
|
<image iconName={"window-close-symbolic"}></image>
|
|
)}
|
|
<label
|
|
cssClasses={["app-name"]}
|
|
halign={START}
|
|
// ellipsize={Pango.EllipsizeMode.END}
|
|
label={n.appName || "Unknown"}
|
|
/>
|
|
<label
|
|
cssClasses={["time"]}
|
|
hexpand
|
|
halign={END}
|
|
label={time(n.time)}
|
|
/>
|
|
<button
|
|
onClicked={() => {
|
|
del(id);
|
|
}}
|
|
child={<image iconName="window-close-symbolic" />}
|
|
></button>
|
|
</box>
|
|
<Gtk.Separator visible />
|
|
<box cssClasses={["content"]}>
|
|
<box
|
|
cssClasses={["image"]}
|
|
visible={Boolean(NotificationIcon(n))}
|
|
halign={CENTER}
|
|
valign={CENTER}
|
|
vexpand={true}
|
|
>
|
|
{NotificationIcon(n)}
|
|
</box>
|
|
<box vertical>
|
|
<label
|
|
cssClasses={["summary"]}
|
|
halign={START}
|
|
xalign={0}
|
|
useMarkup
|
|
label={bind(n, "summary")}
|
|
// ellipsize={Pango.EllipsizeMode.END}
|
|
/>
|
|
{n.body && (
|
|
<label
|
|
cssClasses={["body"]}
|
|
valign={CENTER}
|
|
wrap={true}
|
|
maxWidthChars={50}
|
|
label={bind(n, "body")}
|
|
/>
|
|
)}
|
|
</box>
|
|
</box>
|
|
{n.get_actions().length > 0 ? (
|
|
<box cssClasses={["actions"]}>
|
|
{n.get_actions().map(({ label, id }) => (
|
|
<button hexpand onClicked={() => n.invoke(id)}>
|
|
<label label={label} halign={CENTER} hexpand />
|
|
</button>
|
|
))}
|
|
</box>
|
|
) : (
|
|
<box></box>
|
|
)}
|
|
</box>
|
|
);
|
|
}
|