Files
arthur-os/bin/omarchy-reminder
T

202 lines
6.0 KiB
Bash
Executable File

#!/bin/bash
# omarchy:summary=Set and show lightweight desktop notification reminders
# omarchy:args=[-i|--interactive] | <minutes> [message] | show [-j|--json] | clear
# omarchy:examples=omarchy reminder -i | omarchy reminder 5 | omarchy reminder 30 "Check the oven" | omarchy reminder show | omarchy reminder show --json | omarchy reminder clear
set -euo pipefail
format_remaining() {
local seconds=$1
local minutes=$((seconds / 60))
local remainder=$((seconds % 60))
if ((minutes > 0 && remainder > 0)); then
echo "${minutes}m ${remainder}s"
elif ((minutes > 0)); then
echo "${minutes}m"
else
echo "${remainder}s"
fi
}
active_reminder_timers() {
local now=${1:-$(date +%s)}
local timer next
while IFS=$'\t' read -r timer next; do
[[ -z $timer || -z $next ]] && continue
next=$((next / 1000000))
((next <= now)) && continue
printf "%s\t%s\n" "$timer" "$next"
done < <(systemctl --user list-timers --all --output=json "omarchy-reminder-*.timer" 2>/dev/null | jq -r '.[] | [.unit, .next] | @tsv')
}
refresh_indicator() {
omarchy-shell -q omarchy.indicators refresh >/dev/null 2>&1 || true
}
open_interactive() {
omarchy-shell shell summon omarchy.reminders "{}"
}
show_reminders() {
local timer next remaining reminder reminder_minutes body=""
local reminder_dir="${XDG_RUNTIME_DIR:-/tmp}/omarchy-reminders"
local reminder_message=""
local now=$(date +%s)
while IFS=$'\t' read -r timer next; do
remaining=$((next - now))
reminder=${timer%.timer}
reminder=${reminder#omarchy-reminder-}
reminder_minutes=${reminder%%m-*}
reminder_message=""
[[ -f $reminder_dir/${timer%.timer}.message ]] && reminder_message=$(<"$reminder_dir/${timer%.timer}.message")
if [[ -n $reminder_message ]]; then
body+="$reminder_message in $(format_remaining $remaining) ($(date -d "@$next" +%-H:%M))"$'\n'
else
body+="${reminder_minutes}-min reminder in $(format_remaining $remaining) ($(date -d "@$next" +%-H:%M))"$'\n'
fi
done < <(active_reminder_timers "$now")
if [[ -z $body ]]; then
omarchy-notification-send -g 󰢌 "Upcoming reminders" "No outstanding reminders"
else
omarchy-notification-send -g 󰢌 "Upcoming reminders" "${body%$'\n'}"
fi
}
show_json() {
local timer next remaining reminder reminder_minutes unit reminder_message label item_json reminders_json="[]"
local reminder_dir="${XDG_RUNTIME_DIR:-/tmp}/omarchy-reminders"
local now=$(date +%s)
local count=0
local tooltip="Set Reminder"
while IFS=$'\t' read -r timer next; do
count=$((count + 1))
unit=${timer%.timer}
reminder=${unit#omarchy-reminder-}
reminder_minutes=${reminder%%m-*}
[[ ! $reminder_minutes =~ ^[0-9]+$ ]] && reminder_minutes=0
remaining=$((next - now))
reminder_message=""
[[ -f $reminder_dir/$unit.message ]] && reminder_message=$(<"$reminder_dir/$unit.message")
if [[ -n $reminder_message ]]; then
label=$reminder_message
else
label="${reminder_minutes}-min reminder"
fi
item_json=$(jq -cn \
--arg unit "$unit" \
--arg timer "$timer" \
--arg label "$label" \
--arg message "$reminder_message" \
--arg remaining "$(format_remaining "$remaining")" \
--arg atTime "$(date -d "@$next" +%-H:%M)" \
--argjson minutes "$reminder_minutes" \
--argjson at "$next" \
--argjson remainingSeconds "$remaining" \
'{unit:$unit,timer:$timer,minutes:$minutes,message:$message,label:$label,remaining:$remaining,remainingSeconds:$remainingSeconds,at:$at,atTime:$atTime}')
reminders_json=$(jq -cn --argjson reminders "$reminders_json" --argjson item "$item_json" '$reminders + [$item]')
done < <(active_reminder_timers "$now")
if ((count == 1)); then
tooltip="1 reminder"
elif ((count > 1)); then
tooltip="$count reminders"
fi
jq -cn --argjson count "$count" --arg tooltip "$tooltip" --argjson reminders "$reminders_json" '{count:$count,active:($count > 0),tooltip:$tooltip,reminders:$reminders}'
}
clear_reminders() {
local units
local reminder_dir="${XDG_RUNTIME_DIR:-/tmp}/omarchy-reminders"
units=$(systemctl --user list-timers --all --no-legend --no-pager "omarchy-reminder-*.timer" 2>/dev/null | awk '{ print $(NF - 1), $NF }')
if [[ -n $units ]]; then
xargs -r systemctl --user stop <<<"$units" || true
fi
rm -f "$reminder_dir"/omarchy-reminder-*.message 2>/dev/null || true
refresh_indicator
omarchy-notification-send -g 󰢌 "All reminders have been cleared"
}
usage() {
echo "Usage: omarchy-reminder [-i|--interactive]"
echo " omarchy-reminder <minutes> [message]"
echo " omarchy-reminder show [-j|--json]"
echo " omarchy-reminder clear"
}
case ${1:-} in
-i | --interactive)
open_interactive
exit 0
;;
show | list)
case ${2:-} in
-j | --json)
show_json
;;
"")
show_reminders
;;
*)
usage
exit 1
;;
esac
exit 0
;;
clear)
clear_reminders
exit 0
;;
esac
minutes=${1:-}
shift || true
message="$*"
custom_message="$message"
if [[ -z $minutes ]] || [[ ! $minutes =~ ^[0-9]+$ ]] || ((minutes == 0)); then
usage
exit 1
fi
if [[ -z $message ]]; then
message="Your ${minutes} minutes are up"
fi
set_at=$(date +%s)
remind_at=$(date -d "+${minutes} minutes" +%H:%M)
unit="omarchy-reminder-${minutes}m-$set_at"
reminder_dir="${XDG_RUNTIME_DIR:-/tmp}/omarchy-reminders"
message_file="$reminder_dir/$unit.message"
confirmation="You'll be reminded at $remind_at"
confirmation_title="Reminder set for ${minutes} minutes"
mkdir -p "$reminder_dir"
if [[ -n $custom_message ]]; then
printf "%s" "$custom_message" >"$message_file"
confirmation_title="$custom_message in ${minutes} minutes"
fi
systemd-run --user --quiet --collect --on-active="${minutes}m" --unit="$unit" \
bash -c 'omarchy-notification-send -g 󰢌 "Reminder" "$1"; rm -f "$2"; omarchy-shell -q omarchy.indicators refresh >/dev/null 2>&1 || true' bash "$message" "$message_file"
refresh_indicator
omarchy-notification-send -g 󰢌 "$confirmation_title" "$confirmation"