108 lines
4.3 KiB
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)))))))))))
|