#!/bin/bash # omarchy:summary=Set and show lightweight desktop notification reminders # omarchy:args= [message] | show | clear # omarchy:examples=omarchy reminder 5 | omarchy reminder 30 "Check the oven" | omarchy reminder show | 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 } parse_systemd_timespan() { local timespan="$1" local total=0 local value unit whole while read -r value unit; do whole=${value%.*} case $unit in d) total=$((total + whole * 86400)) ;; h) total=$((total + whole * 3600)) ;; min) total=$((total + whole * 60)) ;; s) total=$((total + whole)) ;; ms | us) ;; esac done < <(grep -oE '[0-9]+([.][0-9]+)?(d|h|min|s|ms|us)' <<<"$timespan" | sed -E 's/^([0-9.]+)([a-z]+)$/\1 \2/') echo "$total" } show_reminders() { local timer next remaining 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 [[ -z $timer || -z $next ]] && continue next=$((next / 1000000)) ((next <= now)) && continue remaining=$((next - now)) reminder=${timer%.timer} reminder=${reminder#omarchy-reminder-} set_at=${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 < <(systemctl --user list-timers --all --output=json "omarchy-reminder-*.timer" 2>/dev/null | jq -r '.[] | [.unit, .next] | @tsv') if [[ -z $body ]]; then omarchy-notification-send -g 󰔛 "Upcoming reminders" "No outstanding reminders" else omarchy-notification-send -g 󰔛 "Upcoming reminders" "${body%$'\n'}" fi } 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 omarchy-notification-send -g 󰔛 "All reminders have been cleared" } case ${1:-} in show | list) show_reminders 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 echo "Usage: omarchy-reminder [message]" echo " omarchy-reminder show" echo " omarchy-reminder clear" 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" -u critical; rm -f "$2"' bash "$message" "$message_file" omarchy-notification-send -g 󰔛 "$confirmation_title" "$confirmation"