]> git.r.bdr.sh - rbdr/r.bdr.sh/blame - swiftbar/focus.utils.sh
Add Focus checks instructions
[rbdr/r.bdr.sh] / swiftbar / focus.utils.sh
CommitLineData
1bf7c9b9
RBR
1ASSERT_PATH="$HOME/Library/DoNotDisturb/DB/Assertions.json"
2MODECONFIG_PATH="$HOME/Library/DoNotDisturb/DB/ModeConfigurations.json"
3
4###############################################################################
5#
6# USAGE:
7#
8# You can ask a script to only continue if it matches a focus mode, or to halt
9# if it encounters it. You can do this by passing pipe separated values to
10# VAR_RUN_ON_FOCUS or VAR_HALT_ON_FOCUS and then calling focus_check.
11# For example, this will only run the script if "Personal" or "Do Not Disturb"
12# are active:
13#
14# VAR_RUN_ON_FOCUS="Personal|Do Not Disturb"
15# focus_check
16#
17# And this will halt the script only if the focus is Work
18#
19# VAR_HALT_ON_FOCUS="Work"
20# focus_check
21#
22# If neither variable is set, then all checks will be disabled.
23#
24# SETUP:
25#
26# Copy focus.utils.sh to your SwiftBar directory and include it if it exists.
27#
28# if [[ -f "${BASH_SOURCE%/*}/focus.utils.sh" ]]; then
29# source "${BASH_SOURCE%/*}/focus.utils.sh"
30# focus_check
31# fi
32#
33# PERMISSIONS:
34#
35# Accessing these databases requires that SwiftBar has full disk access
36# permissions. If the checks are enabled but the database files can't be read
37# it will instead return an error with instructions on what to do.
38#
39# ADDITIONAL FUNCTIONS:
40#
41# If you need custom behavior you can use the get_focus and is_focus_active
42#
43# get_focus will return the name of the currently active focus, or an empty
44# string if there's no focus enabled.
45#
46# is_focus_active receives a pipe delimited string and will return 0 if the
47# current focus is in the list, or 1 if the current focus is not present.
48#
49###############################################################################
50# Internal Utilities
51###############################################################################
52
53_assert_permissions() {
54
55 if [[ ! -r "$ASSERT_PATH" ]] || [[ ! -r "$MODECONFIG_PATH" ]]; then
56 echo ":light.beacon.max:"
57 echo "---"
58 echo "Focus database not readable.\nAllow SwiftBar in System Settings > Privacy & Security > Full Disk Access."
59 exit 0
60 fi
61}
62
63_run_on_focus() {
64 [[ -z "${VAR_RUN_ON_FOCUS}" ]] && return 0
65 _assert_permissions
66 is_focus_active $VAR_RUN_ON_FOCUS || exit 0
67 return 0
68}
69
70_halt_on_focus() {
71 [[ -z "${VAR_HALT_ON_FOCUS}" ]] && return 0
72 _assert_permissions
73 is_focus_active $VAR_HALT_ON_FOCUS || return 0
74 exit 0
75}
76
77###############################################################################
78# Public Functions
79###############################################################################
80
81get_focus() {
82 local focus=""
83
84 # Check for active assertions
85 if [[ -f "$ASSERT_PATH" ]]; then
86 local modeid=$(jq -r '.data[0].storeAssertionRecords[0].assertionDetails.assertionDetailsModeIdentifier // empty' "$ASSERT_PATH")
87
88 if [[ -n "$modeid" ]]; then
89 focus=$(jq -r --arg mid "$modeid" '.data[0].modeConfigurations[$mid].mode.name' "$MODECONFIG_PATH")
90 echo "$focus"
91 return
92 fi
93 fi
94
95 # Calculate current time in minutes
96 local hour=$(date +%H)
97 local minute=$(date +%M)
98 local now=$((hour * 60 + minute))
99
100 # Process scheduled triggers
101 jq -r '.data[0].modeConfigurations | to_entries[] | select(.value.triggers.triggers[0] != null) |
102 select(.value.triggers.triggers[0].enabledSetting == 2) |
103 {
104 id: .key,
105 name: .value.mode.name,
106 start: (.value.triggers.triggers[0].timePeriodStartTimeHour * 60 + .value.triggers.triggers[0].timePeriodStartTimeMinute),
107 end: (.value.triggers.triggers[0].timePeriodEndTimeHour * 60 + .value.triggers.triggers[0].timePeriodEndTimeMinute)
108 } | @json' "$MODECONFIG_PATH" 2>/dev/null | while read -r line; do
109 local start=$(echo "$line" | jq -r '.start')
110 local end=$(echo "$line" | jq -r '.end')
111 local name=$(echo "$line" | jq -r '.name')
112
113 if [[ $start -lt $end ]]; then
114 if [[ $now -ge $start && $now -lt $end ]]; then
115 focus="$name"
116 break
117 fi
118 elif [[ $start -gt $end ]]; then
119 if [[ $now -ge $start || $now -lt $end ]]; then
120 focus="$name"
121 break
122 fi
123 fi
124 done
125
126 echo -n "$focus" | xargs
127}
128
129is_focus_active() {
130 local current_focus=$(get_focus)
131 [[ "$current_focus" =~ ^($1)$ ]] && return 0
132 return 1
133}
134
135focus_check() {
136 _run_on_focus
137 _halt_on_focus
138}