[AGS] Bar: BT, Audio, SysInfo, Brightness

This commit is contained in:
2025-04-23 20:04:48 +02:00
parent 69484fc302
commit e93e051094
26 changed files with 825 additions and 223 deletions

View File

@@ -1,103 +1,113 @@
// From astal examples
// From astal examples
import { GLib } from "astal"
import { Gtk } from "astal/gtk4"
import Notifd from "gi://AstalNotifd"
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 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 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
const { LOW, NORMAL, CRITICAL } = Notifd.Urgency;
// match operator when?
switch (n.urgency) {
case LOW: return "low"
case CRITICAL: return "critical"
case LOW:
return "low";
case CRITICAL:
return "critical";
case NORMAL:
default: return "normal"
default:
return "normal";
}
}
};
type Props = {
delete: ( id: number ) => void;
notification: Notifd.Notification
id: number,
}
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
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 ) }}>
<image iconName="window-close-symbolic" />
</button>
</box>
<Gtk.Separator visible />
<box cssClasses={["content"]}>
{n.image && fileExists(n.image) ? <box
valign={START}
cssClasses={["image"]}>
<image file={n.image}></image>
</box>
: <box></box>}
{n.image ? <box
expand={false}
valign={START}
cssClasses={["icon-image"]}>
<image iconName={n.image} expand halign={CENTER} valign={CENTER} />
</box>
: <box></box>}
<box vertical>
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={["summary"]}
cssClasses={["app-name"]}
halign={START}
xalign={0}
label={n.summary}
// ellipsize={Pango.EllipsizeMode.END}
label={n.appName || "Unknown"}
/>
{n.body ? <label
cssClasses={["body"]}
wrap
useMarkup
halign={START}
xalign={0}
label={n.body}
/> : <label></label>}
</box>
</box>
{n.get_actions().length > 0 ? <box cssClasses={["actions"]}>
{n.get_actions().map(({ label, id }) => (
<button
<label
cssClasses={["time"]}
hexpand
onClicked={() => n.invoke(id)}>
<label label={label} halign={CENTER} hexpand />
</button>
))}
</box> : <box></box>}
</box>
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>
);
}