refactor: eww notifications

This commit is contained in:
hesam-init 2024-07-02 17:45:31 +03:30
parent b73eb585af
commit caad2ba8ef
10 changed files with 498 additions and 245 deletions

View file

@ -73,10 +73,9 @@
(deflisten notifications :initial '{ (deflisten notifications :initial '{
"count": 0, "count": 0,
"dnd": false, "dnd": false,
"notifications": [],
"popups": [] "popups": []
}' }'
"./scripts/notif.py" "./scripts/notification/notifs.py"
) )
; Playerctl ; Playerctl

View file

@ -1,4 +1,4 @@
(include "./src/_definitions.yuck") (include "./_definitions.yuck")
(include "./src/-components/_helpers.yuck") (include "./src/-components/_helpers.yuck")
(include "./src/-components/_separator.yuck") (include "./src/-components/_separator.yuck")
@ -16,7 +16,7 @@
(include "./src/windows/_dashboard.yuck") (include "./src/windows/_dashboard.yuck")
(include "./src/windows/_osd.yuck") (include "./src/windows/_osd.yuck")
(include "./setups.yuck") (include "./_setups.yuck")
(include "./src/wallpapers/main.yuck") (include "./src/wallpapers/main.yuck")
(include "./src/dock/main.yuck") (include "./src/dock/main.yuck")

View file

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import gi import gi
gi.require_version('Gtk', '3.0') gi.require_version('Gtk', '3.0')
from gi.repository import Gtk from gi.repository import Gtk

View file

@ -1,55 +0,0 @@
#!/usr/bin/bash
# Taken from Juminai
dismiss() {
dbus-send --session --type=method_call \
--dest=org.freedesktop.Notifications \
/org/freedesktop/Notifications \
org.freedesktop.Notifications.DismissPopup \
uint32:$1
}
close() {
dbus-send --session --type=method_call \
--dest=org.freedesktop.Notifications \
/org/freedesktop/Notifications \
org.freedesktop.Notifications.CloseNotification \
uint32:$1
}
action() {
dbus-send --session --type=method_call \
--dest=org.freedesktop.Notifications \
/org/freedesktop/Notifications \
org.freedesktop.Notifications.InvokeAction \
uint32:$1 string:$2
}
clear_all() {
dbus-send --session --type=method_call \
--dest=org.freedesktop.Notifications \
/org/freedesktop/Notifications \
org.freedesktop.Notifications.ClearAll
}
listen() {
dbus-send --session --type=method_call \
--dest=org.freedesktop.Notifications \
/org/freedesktop/Notifications \
org.freedesktop.Notifications.Listen
}
toggle_dnd() {
dbus-send --session --type=method_call \
--dest=org.freedesktop.Notifications \
/org/freedesktop/Notifications \
org.freedesktop.Notifications.ToggleDND
}
if [[ $1 == '--dismiss' ]]; then dismiss $2 $3; fi
if [[ $1 == '--close' ]]; then close $2; fi
if [[ $1 == '--action' ]]; then action $2 $3; fi
if [[ $1 == '--clear' ]]; then clear_all; fi
if [[ $1 == '--listen' ]]; then listen; fi
if [[ $1 == '--toggle' ]]; then toggle_dnd; fi

View file

@ -0,0 +1,59 @@
#!/usr/bin/bash
DBUS_CMD="dbus-send --session --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications"
dismiss() {
$DBUS_CMD org.freedesktop.Notifications.DismissPopup uint32:$1
}
close() {
$DBUS_CMD org.freedesktop.Notifications.CloseNotification uint32:$1
}
action() {
$DBUS_CMD org.freedesktop.Notifications.InvokeAction uint32:$1 string:$2
}
get_current() {
$DBUS_CMD org.freedesktop.Notifications.GetCurrent
}
clear_all() {
$DBUS_CMD org.freedesktop.Notifications.ClearAll
}
listen() {
$DBUS_CMD org.freedesktop.Notifications.Listen
}
toggle_dnd() {
$DBUS_CMD org.freedesktop.Notifications.ToggleDND
}
case "$1" in
--dismiss)
dismiss "$2"
;;
--close)
close "$2"
;;
--action)
action "$2" "$3"
;;
--current)
get_current
;;
--clear)
clear_all
;;
--listen)
listen
;;
--toggle)
toggle_dnd
;;
*)
echo "Usage: $0 {--dismiss|--close|--action|--clear|--listen|--toggle} [args]"
exit 1
;;
esac

View file

@ -0,0 +1,236 @@
#!/usr/bin/python
import gi
gi.require_version("GdkPixbuf", "2.0")
gi.require_version("Gtk", "3.0")
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GLib
import datetime
import os
import typing
import sys
import json
from gi.repository import Gtk, GdkPixbuf
import subprocess
cache_dir = f"{os.getenv('HOME')}/.cache/notify_img_data"
log_file = f"{os.getenv('HOME')}/.cache/notifications.json"
os.makedirs(cache_dir, exist_ok=True)
active_popups = {}
# RECIEVE NOTIFICATIONS
class NotificationDaemon(dbus.service.Object):
def __init__(self):
bus_name = dbus.service.BusName("org.freedesktop.Notifications", dbus.SessionBus())
dbus.service.Object.__init__(self, bus_name, "/org/freedesktop/Notifications")
self.dnd = False
@dbus.service.method("org.freedesktop.Notifications", in_signature="susssasa{sv}i", out_signature="u")
def Notify(self, app_name, replaces_id, app_icon, summary, body, actions, hints, timeout):
replaces_id = int(replaces_id)
actions = list(actions)
app_icon = str(app_icon)
app_name = str(app_name)
summary = str(summary)
body = str(body)
if replaces_id != 0:
id = replaces_id
else:
log_file = self.read_log_file()
if log_file['notifications'] != []:
id = log_file['notifications'][0]['id'] + 1
else:
id = 1
acts = []
for i in range(0, len(actions), 2):
acts.append([str(actions[i]), str(actions[i + 1])])
details = {
"id": id,
"app": app_name,
"summary": self.format_long_string(summary, 35),
"body": self.format_long_string(body, 35),
"time": datetime.datetime.now().strftime("%H:%M"),
"urgency": hints["urgency"] if "urgency" in hints else 1,
"actions": acts
}
if app_icon.strip():
if os.path.isfile(app_icon) or app_icon.startswith("file://"):
details["image"] = app_icon
else:
details["image"] = self.get_gtk_icon(app_icon)
else:
details["image"] = None
if "image-data" in hints:
details["image"] = f"{cache_dir}/{details['id']}.png"
self.save_img_byte(hints["image-data"], details["image"])
self.save_notifications(details)
if not self.dnd:
self.save_popup(details)
return id
def format_long_string(self, long_string, interval):
split_string = []
max_length = 256
for i in range(0, len(long_string), interval):
split_string.append(long_string[i:i+interval])
result = "-\n".join(split_string)
if len(result) > max_length:
result = result[:max_length] + "..."
return result
@dbus.service.method("org.freedesktop.Notifications", in_signature="", out_signature="ssss")
def GetServerInformation(self):
return ("linkfrg's notification daemon", "linkfrg", "1.0", "1.2")
@dbus.service.method("org.freedesktop.Notifications", in_signature="", out_signature="as")
def GetCapabilities(self):
return ('actions', 'body', 'icon-static', 'persistence')
@dbus.service.signal("org.freedesktop.Notifications", signature="us")
def ActionInvoked(self, id, action):
return (id, action)
@dbus.service.method("org.freedesktop.Notifications", in_signature="us", out_signature="")
def InvokeAction(self, id, action):
self.ActionInvoked(id, action)
@dbus.service.signal("org.freedesktop.Notifications", signature="uu")
def NotificationClosed(self, id, reason):
return (id, reason)
@dbus.service.method("org.freedesktop.Notifications", in_signature="u", out_signature="")
def CloseNotification(self, id):
current = self.read_log_file()
current["notifications"] = [n for n in current["notifications"] if n["id"] != id]
current["count"] = len(current["notifications"])
self.write_log_file(current)
self.NotificationClosed(id, 2)
self.DismissPopup(id)
@dbus.service.method("org.freedesktop.Notifications", in_signature="", out_signature="")
def ToggleDND(self):
match self.dnd:
case False:
self.dnd = True
case True:
self.dnd = False
@dbus.service.method("org.freedesktop.Notifications", in_signature="", out_signature="")
def GetDNDState(self):
subprocess.run(["eww", "update", f"do-not-disturb={json.dumps(self.dnd)}"])
def get_gtk_icon(self, icon_name):
theme = Gtk.IconTheme.get_default()
icon_info = theme.lookup_icon(icon_name, 128, 0)
if icon_info is not None:
return icon_info.get_filename()
def save_img_byte(self, px_args: typing.Iterable, save_path: str):
GdkPixbuf.Pixbuf.new_from_bytes(
width=px_args[0],
height=px_args[1],
has_alpha=px_args[3],
data=GLib.Bytes(px_args[6]),
colorspace=GdkPixbuf.Colorspace.RGB,
rowstride=px_args[2],
bits_per_sample=px_args[4],
).savev(save_path, "png")
def write_log_file(self, data):
output_json = json.dumps(data, indent=2)
subprocess.run(["eww", "update", f"notifications={output_json}"])
with open(log_file, "w") as log:
log.write(output_json)
def read_log_file(self):
empty = {"count": 0, "notifications": [], "popups": []}
try:
with open(log_file, "r") as log:
return json.load(log)
except FileNotFoundError:
with open(log_file, "w") as log:
json.dump(empty, log)
return empty
def save_notifications(self, notification):
current = self.read_log_file()
current["notifications"].insert(0, notification)
current["count"] = len(current["notifications"])
self.write_log_file(current)
@dbus.service.method("org.freedesktop.Notifications", in_signature="", out_signature="")
def ClearAll(self):
for notify in self.read_log_file()['notifications']:
self.NotificationClosed(notify['id'], 2)
data = {"count": 0, "notifications": [], "popups": []}
self.write_log_file(data)
# OPERATIONS WITH POPUPS
def save_popup(self, notification):
global active_popups
current = self.read_log_file()
if len(current["popups"]) >= 3:
oldest_popup = current["popups"].pop()
self.DismissPopup(oldest_popup["id"])
current["popups"].append(notification)
self.write_log_file(current)
popup_id = notification["id"]
active_popups[popup_id] = GLib.timeout_add_seconds(5, self.DismissPopup, popup_id)
@dbus.service.method("org.freedesktop.Notifications", in_signature="u", out_signature="")
def DismissPopup(self, id):
global active_popups
current = self.read_log_file()
current["popups"] = [n for n in current["popups"] if n["id"] != id]
self.write_log_file(current)
active_popups.pop(id, None)
@dbus.service.method("org.freedesktop.Notifications", in_signature="", out_signature="")
def GetCurrent(self):
subprocess.run(["eww", "update", f"notifications={json.dumps(self.read_log_file())}"])
# MAINLOOP
def main():
DBusGMainLoop(set_as_default=True)
loop = GLib.MainLoop()
NotificationDaemon()
try:
loop.run()
except KeyboardInterrupt:
exit(0)
if __name__ == "__main__":
main()

View file

@ -1,90 +1,90 @@
(defwindow notifypopup (defwindow notifypopup
:geometry (geometry :geometry (geometry
:x 0 :x 0
:y 0 :y 0
:width 480 :width 480
:height 0 :height 0
:anchor "top right") :anchor "top right")
:stacking "overlay" :stacking "overlay"
:monitor 0 :monitor 0
(revealer
:reveal { arraylength(notifications.popups) > 0 } (revealer
:transition "slidedown" :reveal { arraylength(notifications.popups) > 0 }
(box :transition "slidedown"
:orientation "v" (box
:space-evenly false :orientation "v"
:spacing 5 :space-evenly false
(for noti in {notifications.popups} :spacing 5
(singlenotif :noti noti :initial true))))) (for noti in {notifications.popups}
(singlenotif :noti noti :initial true)))))
(defwidget singlenotif [noti initial] (defwidget singlenotif [noti initial]
(box (box
:orientation "v" :orientation "v"
:class "${initial ? 'popup' : 'notifbox'}" :class "${initial ? 'popup' : 'notifbox'}"
:space-evenly false :space-evenly false
(centerbox (centerbox
:orientation "h" :orientation "h"
:class "notifbar" :class "notifbar"
(image :halign "start" :image-width 30 :image-height 30 :path {noti.icon != "null" ? noti.icon : "./assets/image/idk.svg"}) (image :halign "start" :image-width 30 :image-height 30 :path {noti.icon != "null" ? noti.icon : "./assets/image/idk.svg"})
(scroll (scroll
:halign "center" :halign "center"
:valign "center" :valign "center"
:hexpand true :hexpand true
:hscroll true :hscroll true
:vscroll false :vscroll false
:width 200 :width 200
(label (label
:class "notiflabel" :class "notiflabel"
:text {noti.app})) :text {noti.app}))
(button (button
:halign "end" :halign "end"
:onclick "./scripts/notifManage --close ${noti.id}" :onclick "./scripts/notification/manage --close ${noti.id}"
(label (label
:class "notifclose" :class "notifclose"
:text ""))) :text "")))
(box (box
:orientation "h" :orientation "h"
:halign "fill" :halign "fill"
:height 80 :height 80
:space-evenly false :space-evenly false
:spacing 10 :spacing 10
(image :image-width 80 :image-height 80 :visible {noti.image != "null"} :path {noti.image != "null" ? noti.image : "./assets/image/idk.svg"}) (image :image-width 80 :image-height 80 :visible {noti.image != "null"} :path {noti.image != "null" ? noti.image : "./assets/image/idk.svg"})
(button (button
:onclick "./scripts/notifManage --dismiss ${noti.id}" :onclick "./scripts/notification/manage --dismiss ${noti.id}"
:onrightclick "./scripts/notifManage --close ${noti.id}" :onrightclick "./scripts/notification/manage --close ${noti.id}"
:tooltip "${noti.time}" :tooltip "${noti.time}"
:hexpand true :hexpand true
:vexpand true :vexpand true
(box (box
:orientation "v" :orientation "v"
:space-evenly false :space-evenly false
:valign "center" :valign "center"
(scroll (scroll
:hscroll true :hscroll true
:vscroll false :vscroll false
:hexpand true :hexpand true
(label (label
:class "notiftitle" :class "notiftitle"
:text {noti.summary})) :text {noti.summary}))
(scroll (scroll
:hscroll true :hscroll true
:vscroll false :vscroll false
:hexpand true :hexpand true
(label (label
:class "notifbody" :class "notifbody"
:visible {noti.body != "null"} :visible {noti.body != "null"}
:text {noti.body}))))) :text {noti.body})))))
(box (box
:orientation "h" :orientation "h"
(for action in {noti.actions} (for action in {noti.actions}
(button (button
:onclick "./scripts/notifManage --action ${noti.id} ${action[0]} && ./scripts/notifManage --close ${noti.id}" :onclick "./scripts/notification/manage --action ${noti.id} ${action[0]} && ./scripts/notification/manage --close ${noti.id}"
(label (label
:class "notifactions" :class "notifactions"
:text {action[1]})) :text {action[1]}))
)))) ))))

View file

@ -5,39 +5,39 @@
:orientation "v" :orientation "v"
:valign "fill" :valign "fill"
:vexpand true :vexpand true
(user) (User )
(chooser) (chooser)
; (weather) ; (weather)
(MediaPlayer :h 160 :permashow true) ; (MediaPlayer :h 160 :permashow true)
(box (box
:orientation "h" :orientation "h"
:space-evenly false :space-evenly false
:height 180 :height 180
(Timer) (Timer)
(bigslides)) (bigslides))
(box (box
:space-evenly false :space-evenly false
:orientation "v" :orientation "v"
:vexpand true :vexpand true
:visible true :visible true
(Toolbox) (Toolbox)
(NotificationsWeatherBox)) (NotificationsWeatherBox))
)) ))
(defwidget Toolbox [] (defwidget Toolbox []
(eventbox (eventbox
:cursor "pointer" :cursor "pointer"
(box (box
:class "tricontrol panel-widget" :class "tricontrol panel-widget"
:orientation "h" :orientation "h"
(button :onclick "./scripts/pop colourpick" (label :text "󰈊")) (button :onclick "./scripts/pop colourpick" (label :text "󰈊"))
(button :onclick "./scripts/pop scrop" (label :text "󰆞")) (button :onclick "./scripts/pop scrop" (label :text "󰆞"))
(button :onclick "~/.config/eww/themeswitch/scripts/pop" (label :text ""))))) (button :onclick "~/.config/eww/themeswitch/scripts/pop" (label :text "")))))
@ -48,10 +48,10 @@
:height 60 :height 60
:class "panel-widget" :class "panel-widget"
:space-evenly false :space-evenly false
(box (box
:orientation "h" :orientation "h"
(button (button
:onclick "${EWW_CMD} update reveal4=${!reveal4} reveal5=false reveal6=false" :onclick "${EWW_CMD} update reveal4=${!reveal4} reveal5=false reveal6=false"
:onrightclick "foot nvim ~/Documents/fuck.txt" :onrightclick "foot nvim ~/Documents/fuck.txt"
@ -62,7 +62,7 @@
(button (button
:onclick "${EWW_CMD} update reveal6=${!reveal6} reveal5=false reveal4=false" :onclick "${EWW_CMD} update reveal6=${!reveal6} reveal5=false reveal4=false"
(label :class {reveal6 ? "titlesel" : "title"} :text "Hyprland"))) (label :class {reveal6 ? "titlesel" : "title"} :text "Hyprland")))
(notes) (notes)
(sysinfo) (sysinfo)
(wmctrl))) (wmctrl)))
@ -99,19 +99,19 @@
:val gapsouter :val gapsouter
:onchange "swaymsg gaps outer all set {}" :onchange "swaymsg gaps outer all set {}"
:max 300 :max 300
:reset "${EWW_CMD} update gapsouter=0 && swaymsg gaps outer all set 0") :reset "${EWW_CMD} update gapsouter=0 && swaymsg gaps outer all set 0")
(wmslider (wmslider
:name "gaps inner" :name "gaps inner"
:val gapsinner :val gapsinner
:onchange "swaymsg gaps inner all set {}" :onchange "swaymsg gaps inner all set {}"
:max 150 :max 150
:reset "${EWW_CMD} update gapsinner=15 && swaymsg gaps inner all set 15") :reset "${EWW_CMD} update gapsinner=15 && swaymsg gaps inner all set 15")
(wmslider (wmslider
:name "border size" :name "border size"
:val borderpixel :val borderpixel
:onchange "swaymsg default_border pixel {} && swaymsg '[app_id=\".*\"] border pixel {}'" :onchange "swaymsg default_border pixel {} && swaymsg '[app_id=\".*\"] border pixel {}'"
:max 50 :max 50
:reset "${EWW_CMD} update borderpixel=2 && swaymsg default_border pixel 2 && swaymsg '[app_id=\".*\"] border pixel 2'") :reset "${EWW_CMD} update borderpixel=2 && swaymsg default_border pixel 2 && swaymsg '[app_id=\".*\"] border pixel 2'")
(box (box
:orientation "h" :orientation "h"
:space-evenly false :space-evenly false
@ -120,7 +120,7 @@
(label :text "natural scrolling") (label :text "natural scrolling")
(checkbox (checkbox
:onchecked "swaymsg input \"type:touchpad\" natural_scroll enable" :onchecked "swaymsg input \"type:touchpad\" natural_scroll enable"
:onunchecked "swaymsg input \"type:touchpad\" natural_scroll disable")) :onunchecked "swaymsg input \"type:touchpad\" natural_scroll disable"))
(box (box
:orientation "h" :orientation "h"
:space-evenly false :space-evenly false
@ -130,8 +130,8 @@
(checkbox (checkbox
:onchecked "swaymsg input \"type:touchpad\" dwt enable" :onchecked "swaymsg input \"type:touchpad\" dwt enable"
:onunchecked "swaymsg input \"type:touchpad\" dwt disable" :onunchecked "swaymsg input \"type:touchpad\" dwt disable"
)) ))
(box (box
:orientation "h" :orientation "h"
:space-evenly false :space-evenly false
@ -141,8 +141,8 @@
(checkbox (checkbox
:onchecked "swaymsg [app_id='.*'] inhibit_idle open && ${EWW_CMD} update caffeine=true" :onchecked "swaymsg [app_id='.*'] inhibit_idle open && ${EWW_CMD} update caffeine=true"
:onunchecked "swaymsg [app_id='.*'] inhibit_idle none && ${EWW_CMD} update caffeine=false" :onunchecked "swaymsg [app_id='.*'] inhibit_idle none && ${EWW_CMD} update caffeine=false"
)) ))
)))) ))))
(defwidget sysinfo [] (defwidget sysinfo []
(revealer (revealer
@ -155,7 +155,7 @@
(systat :icon "󰍛" :val { EWW_RAM.used_mem_perc }) (systat :icon "󰍛" :val { EWW_RAM.used_mem_perc })
(systat :icon "󰈐" :val { gpu }) (systat :icon "󰈐" :val { gpu })
(systat :icon "" :val { EWW_BATTERY.BAT0.capacity }) (systat :icon "" :val { EWW_BATTERY.BAT0.capacity })
))) )))
(defwidget wmslider [name val onchange max reset] (defwidget wmslider [name val onchange max reset]
(box (box
@ -167,18 +167,18 @@
:valign "center" :valign "center"
:spacing 10 :spacing 10
(label (label
:text name) :text name)
(scale (scale
:min 0 :min 0
:max max :max max
:class "wmctrlslide" :class "wmctrlslide"
:tooltip val :tooltip val
:value val :value val
:onchange onchange) :onchange onchange)
(button (button
:onclick reset :onclick reset
:style "padding: 0px 8px 0px 3px;" :style "padding: 0px 8px 0px 3px;"
""))) "")))
(defwidget systat [icon val] (defwidget systat [icon val]
(overlay (overlay
@ -187,8 +187,8 @@
:valign "center" :valign "center"
:class "circsys" :class "circsys"
:thickness 40 :thickness 40
:value val) :value val)
(box (box
:class "circiconcontain" :class "circiconcontain"
:halign "center" :halign "center"
@ -197,7 +197,7 @@
:width 55 :width 55
(label :text icon)))) (label :text icon))))
(defwidget user[] (defwidget User []
(revealer (revealer
:reveal {!reveal4 && !reveal5 && !reveal6} :reveal {!reveal4 && !reveal5 && !reveal6}
:transition "slideup" :transition "slideup"
@ -232,7 +232,7 @@
:vexpand true :vexpand true
:class "panel-widget" :class "panel-widget"
:space-evenly false :space-evenly false
(box (box
:orientation "h" :orientation "h"
(button (button
@ -241,28 +241,28 @@
(button (button
:onclick "${EWW_CMD} update revealWeather=true" :onclick "${EWW_CMD} update revealWeather=true"
(label :class {revealWeather ? "titlesel" : "title"} :text "Weather"))) (label :class {revealWeather ? "titlesel" : "title"} :text "Weather")))
(box (box
:orientation "h" :orientation "h"
:vexpand true :vexpand true
:hexpand true :hexpand true
:space-evenly false :space-evenly false
(revealer (revealer
:reveal {!revealWeather} :reveal {!revealWeather}
:hexpand {!revealWeather} :hexpand {!revealWeather}
:transition "slideleft" :transition "slideleft"
(notificationlog)) (NotificationsLogs))
(revealer (revealer
:reveal revealWeather :reveal revealWeather
:hexpand revealWeather :hexpand revealWeather
:transition "slideleft" :transition "slideleft"
(Weather)))))
(weather))))) (defwidget Weather []
(defwidget weather[]
(overlay (overlay
(box (box
:orientation "v" :orientation "v"
@ -270,8 +270,9 @@
:valign "fill" :valign "fill"
:vexpand true :vexpand true
:space-evenly false :space-evenly false
(weathermain) (weathermain)
(scroll (scroll
:hscroll false :hscroll false
:vscroll true :vscroll true
@ -287,8 +288,66 @@
:hexpand true :hexpand true
:vexpand false :vexpand false
:height 80 :height 80
:class "fadeoutbox")
))
(defwidget NotificationsLogs []
(box
:halign "fill"
:valign "fill"
:width 320
:vexpand true
:space-evenly false
:orientation "v"
(overlay
:vexpand true
(box
:halign "fill"
:valign "fill"
:vexpand true
:space-evenly false
:orientation "v"
(scroll
:hscroll false
:vscroll true
:vexpand true
:valign "fill"
(box
:orientation "v"
:valign "start"
:space-evenly false
(for notif in {notifications.notifications}
(singlenotif :noti notif :initial false))))
)
(box
:valign "end"
:hexpand true
:vexpand false
:height 80
:class "fadeoutbox") :class "fadeoutbox")
)) )
(box
:orientation "h"
:valign "end"
(button
:onclick "./scripts/notification/manage --clear"
(label
:class "title"
:text "Clear All"))
(button
:onclick "./scripts/notification/manage --toggle"
(label
:class { notifications.dnd ? "titlesel" : "title"}
:text "Do Not Disturb")))
)
)
(defwidget weatherhour[hour] (defwidget weatherhour[hour]
(box (box
@ -304,7 +363,7 @@
(image (image
:image-width 50 :image-width 50
:image-height 50 :image-height 50
:path "./assets/image/weather/${hour.icon}.svg") :path "./assets/image/weather/${hour.icon}.svg")
(box (box
:orientation "v" :orientation "v"
:space-evenly false :space-evenly false
@ -313,7 +372,7 @@
(label :halign "start" :text "${hour.FeelsLikeC}°C") (label :halign "start" :text "${hour.FeelsLikeC}°C")
(label :halign "start" :text "rain: ${hour.chanceofrain}%")))) (label :halign "start" :text "rain: ${hour.chanceofrain}%"))))
(defwidget weathermain[] (defwidget weathermain []
(box (box
:class "mainentry" :class "mainentry"
:orientation "h" :orientation "h"
@ -325,7 +384,7 @@
:image-width 100 :image-width 100
:image-height 100 :image-height 100
:style "margin: 10px;" :style "margin: 10px;"
:path "./assets/image/weather/${weatherjson.icon}.svg") :path "./assets/image/weather/${weatherjson.icon}.svg")
(scroll (scroll
:hscroll true :hscroll true
:vscroll false :vscroll false
@ -338,7 +397,7 @@
(label :halign "start" :text "← ${weatherjson.windspeedKmph} km/h") (label :halign "start" :text "← ${weatherjson.windspeedKmph} km/h")
;; (label :halign "start" :text "${weatherjson.visibility} km") ;; (label :halign "start" :text "${weatherjson.visibility} km")
;; (label :halign "start" :text "${weatherjson.precipMM} mm") ;; (label :halign "start" :text "${weatherjson.precipMM} mm")
)))) ))))
(defwidget Timer [] (defwidget Timer []
(box (box
@ -347,7 +406,7 @@
:space-evenly false :space-evenly false
:valign "fill" :valign "fill"
:width 200 :width 200
(label :class "timer" :valign "center" :vexpand true :text timerdis) (label :class "timer" :valign "center" :vexpand true :text timerdis)
(box (box
:orientation "h" :orientation "h"
@ -378,11 +437,11 @@
:tooltip "${volume}%" :tooltip "${volume}%"
:max 100 :max 100
:min 0 :min 0
:flipped true) :flipped true)
(label (label
:class "slideicon" :class "slideicon"
:valign "end" :valign "end"
:text {volumemute == 'false' ? "󰕾" : "󰖁"}))) :text {volumemute == 'false' ? "󰕾" : "󰖁"})))
(defwidget bigmic [] (defwidget bigmic []
(overlay (overlay
@ -394,11 +453,11 @@
:tooltip "${mic_volume}%" :tooltip "${mic_volume}%"
:max 100 :max 100
:min 0 :min 0
:flipped true) :flipped true)
(label (label
:class "slideicon" :class "slideicon"
:valign "end" :valign "end"
:text {volumemute == 'false' ? "" : "󰖁"}))) :text {volumemute == 'false' ? "" : "󰖁"})))
(defwidget bigbright [] (defwidget bigbright []
(overlay (overlay
@ -410,57 +469,11 @@
:tooltip "${brightness}%" :tooltip "${brightness}%"
:max 100 :max 100
:min 0 :min 0
:flipped true) :flipped true)
(label (label
:class "slideicon" :class "slideicon"
:valign "end" :valign "end"
:text "󰃞"))) :text "󰃞")))
(defwidget notificationlog []
(overlay
(box
:halign "fill"
:valign "fill"
:vexpand true
:space-evenly false
:orientation "v"
(scroll
:hscroll false
:vscroll true
:vexpand true
:valign "fill"
(box
:orientation "v"
:valign "start"
:space-evenly false
(for noti in {notifications.notifications}
(singlenotif :noti noti :initial false))))
(box
:valign "end"
:hexpand true
:vexpand false
:height 80
:class "fadeoutbox")
(box
:orientation "h"
(button
:onclick "./scripts/notifManage --clear"
(label
:class "title"
:text "Clear All"))
(button
:onclick "./scripts/notifManage --toggle"
(label
:class { notifications.dnd ? "titlesel" : "title"}
:text "Do Not Disturb")))
)
)
)
(defwidget quote [] (defwidget quote []
(box (box
@ -475,7 +488,7 @@
:class "quote" :class "quote"
:text {quotejson.content} :text {quotejson.content}
:wrap true :wrap true
:width 300)) :width 300))
(label (label
:class "quoteauthor" :class "quoteauthor"
:text "- ${quotejson.author}"))) :text "- ${quotejson.author}")))