nix-configs/modules/desktop/waybar/cal.nix

93 lines
2.9 KiB
Nix

{
pkgs,
config,
lib,
...
}:
with lib;
let
calwatcher =
(pkgs.writeShellApplication {
name = "calwatcher";
runtimeInputs = [
pkgs.inotify-tools
pkgs.khal
pkgs.jq
];
text = ''
# in parts ripped from https://git.sr.ht/~whynothugo/dotfiles/tree/3768ec57/item/home/.local/lib/waybar-khal
render() {
# Find events starting in two minutes.
# So if my current event ends in two minutes and another one starts, the
# widget is already updated with what's upcoming.
SINCE="$(date -d 'now +2 min' '+%FT%H:%M:%S')"
UNTIL="1d"
EVENT="$(
khal list "$SINCE" "$UNTIL" \
--day-format 'SKIPME' \
--format "{start-end-time-style} {title:.31}{repeat-symbol}" |
grep -v SKIPME | # filter out headers
grep -v -P '| |' | # filter out continuing all day events
grep -v '^ ' | # exclude full-day events
head -n 1 # show just the first
)"
if [ -z "$EVENT" ]; then
TEXT=" (nothing upcoming)"
CLASS="no-event"
else
TEXT=" $EVENT"
CLASS="event"
fi
jq --compact-output \
--null-input \
--arg text "$TEXT" \
--arg class "$CLASS" \
--arg tooltip "$(khal list today 7d --day-format '<span color="#ffead3"><b>{name} {date-long}</b></span>')" \
'{"text": $text, "class": $class, "tooltip": $tooltip}'
}
render # Render once for initial state.
# In order to make sure events are updated as time passes, this re-renderes
# every two minutes. That aside, whenever a calendar event changes, we alreays
# re-render immediately.
#
# It would be ideal to determine _when_ the current event ends, and set the
# timeout accordinly. That would require parsing khal's output a bit more.
while true; do
(inotifywait \
--event modify \
--event create \
--event delete \
--event close_write \
--event moved_to \
--event move \
--monitor \
--timeout 120 \
--recursive \
"$HOME/.calendars" 2> /dev/null) || true | \
while read -r _; do
render
timeout 3 cat || true # debounce for 3s, https://stackoverflow.com/a/69945839
done
done
'';
})
+ "/bin/calwatcher";
in
lib.mkIf (config.xyno.user-services.khal.enable) {
xyno.desktop.waybar.config = {
"custom/cal" = {
exec = calwatcher;
restart-interval = 5;
return-type = "json";
"on-click" = "${pkgs.foot}/bin/footclient --app-id floating-alacritty ${pkgs.khal}/bin/ikhal";
};
modules-right = mkOrder 1999 [ "custom/cal" ]; # left of clock, right of everything else
};
}