ui/widgets/notifications/__init__.hy

108 lines
4.3 KiB
Hy

(import astal *)
(import astal.gtk3 *)
(.require-version gi "AstalNotifd" "0.1")
(.require-version gi "Pango" "1.0")
(import gi.repository [AstalNotifd Pango])
(let [
ProgressBar (astalify Gtk.ProgressBar)
notifd (.get-default AstalNotifd)
notification-timeout 3
notification-icon (fn [notification]
(cond
(.get-image notification) (Widget.Box
:class-name "icon image"
:css f"
background-image: url(\"{(.get-image notification)}\");
background-size: contain;
background-repeat: no-repeat;
background-position: center;")
(. Astal Icon (lookup-icon (.get-app-icon notification))) (Widget.Icon
:icon (.get-app-icon notification)
:class-name "icon")
True (Widget.Icon
:icon "dialog-information-symbolic"
:class-name "icon")))
make-notification (fn [notification]
(let [
layout (Widget.Button
:on-clicked (fn [self] (. self (get-parent) (set-reveal-child False)))
:child (Widget.Box
:children [
(Widget.Box
:vertical True
:css "min-width: 200px; min-height 50px;;"
:children [
(Widget.Box
:children [
(notification-icon notification)
(Widget.Box
:vertical True
:children [
(Widget.Label
:class-name "title"
:label (str (.get-summary notification))
:xalign 0
:justify 0
:ellipsize Pango.EllipsizeMode.END
)
(Widget.Label
:class-name "body"
:label (str (.get-body notification))
:xalign 0
:justify 0
:wrap True
:wrap-mode Pango.WrapMode.WORD_CHAR
:use-markup True
)])])
(ProgressBar
:class-name "timeout-bar"
:hexpand True
:valign 2
:fraction (bind (.poll (Variable 1) (// (+ (* (or (max (.get-expire-timeout notification) 0) notification-timeout) 1000) 250) 100) (fn [prev]
(when (> prev .02)
(return (- prev .01)))
(return 0)))))])
(Widget.Box :class-name f"urgency-indicator {(.get-urgency notification)}")]))]
(Widget.Revealer
:transition-type Gtk.RevealerTransitionType.SLIDE_DOWN
:transition-duration 250
:class-name "notifications"
:child (Widget.Revealer
:transition-type Gtk.RevealerTransitionType.SLIDE_DOWN
:transition-duration 250
:child layout
:setup (fn [self]
(.hook self self "notify::reveal-child" (fn [#* _]
(when (not (.get-reveal-child self))
(timeout 250 (fn [] (. self (get-parent) (set-reveal-child False)))))))))
:setup (fn [self]
(.hook self self "notify::reveal-child" (fn [self revealed?]
(when revealed?
(when (.get-reveal-child self) (timeout 1 (fn [] (. self (get-child) (set-reveal-child True)))))
(timeout (* 1000 (or (max (.get-expire-timeout notification) 0) notification-timeout)) (fn []
(. self (get-child) (set-reveal-child False))
(timeout (. self (get-child) (get-transition-duration)) (fn []
(.set-reveal-child self False)
(timeout (.get-transition-duration self) (fn []
(.destroy self))))))))))
(.set-reveal-child self True)))))]
(setv notifications (Widget.Window
:namespace "notifications"
:name "notifications"
:anchor (| Astal.WindowAnchor.TOP Astal.WindowAnchor.RIGHT)
:exclusivity Astal.Exclusivity.EXCLUSIVE
:margin-top 5
:child (Widget.Box
:vertical True
:setup (fn [self]
(.hook self notifd "notified" (fn [self notification _]
(let [children (.get-children self)]
(.add self (make-notification (.get-notification notifd notification)))))))))))