104 lines
3.2 KiB
TypeScript
104 lines
3.2 KiB
TypeScript
// From astal examples
|
|
|
|
import { GLib } from "astal"
|
|
import { Gtk } from "astal/gtk4"
|
|
import Notifd from "gi://AstalNotifd"
|
|
// 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 cssName="header">
|
|
{(n.appIcon || n.desktopEntry) ? <Gtk.Image
|
|
cssName="app-icon"
|
|
visible={Boolean(n.appIcon || n.desktopEntry)}
|
|
iconName={n.appIcon || n.desktopEntry}
|
|
/> : <Gtk.Image iconName={'window-close-symbolic'}></Gtk.Image>}
|
|
<label
|
|
cssName="app-name"
|
|
halign={START}
|
|
// ellipsize={Pango.EllipsizeMode.END}
|
|
label={n.appName || "Unknown"}
|
|
/>
|
|
<label
|
|
cssName="time"
|
|
hexpand
|
|
halign={END}
|
|
label={time(n.time)}
|
|
/>
|
|
<button onClicked={() => del( id )}>
|
|
<Gtk.Image iconName="window-close-symbolic" />
|
|
</button>
|
|
</box>
|
|
<Gtk.Separator visible />
|
|
<box cssName="content">
|
|
{n.image && fileExists(n.image) ? <box
|
|
valign={START}
|
|
cssName="image">
|
|
<Gtk.Image file={n.image}></Gtk.Image>
|
|
</box>
|
|
: <box></box>}
|
|
{n.image ? <box
|
|
expand={false}
|
|
valign={START}
|
|
className="icon-image">
|
|
<Gtk.Image iconName={n.image} expand halign={CENTER} valign={CENTER} />
|
|
</box>
|
|
: <box></box>}
|
|
<box vertical>
|
|
<Gtk.Label
|
|
cssName="summary"
|
|
halign={START}
|
|
xalign={0}
|
|
label={n.summary}
|
|
// ellipsize={Pango.EllipsizeMode.END}
|
|
/>
|
|
{n.body ? <label
|
|
cssName="body"
|
|
wrap
|
|
useMarkup
|
|
halign={START}
|
|
xalign={0}
|
|
label={n.body}
|
|
/> : <label></label>}
|
|
</box>
|
|
</box>
|
|
{n.get_actions().length > 0 ? <box cssName="actions">
|
|
{n.get_actions().map(({ label, id }) => (
|
|
<button
|
|
hexpand
|
|
onClicked={() => n.invoke(id)}>
|
|
<label label={label} halign={CENTER} hexpand />
|
|
</button>
|
|
))}
|
|
</box> : <box></box>}
|
|
</box>
|
|
}
|