Repository navigation
Expand file tree
/
Copy pathlock-notifications
More file actions
executable file
·171 lines (150 loc) · 7.39 KB
/
Copy pathlock-notifications
File metadata and controls
executable file
·171 lines (150 loc) · 7.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/bash
set -Eeuo pipefail
state_file="${XDG_STATE_HOME:-$HOME/.local/state}/dotfiles/notifications.conf"
source_file="$HOME/.cache/dotfiles/lock-notifications.svg"
cache_file="$HOME/.cache/dotfiles/lock-notifications.png"
theme_file="${XDG_STATE_HOME:-$HOME/.local/state}/dotfiles/color-scheme"
mkdir -p "${source_file%/*}"
theme="dark"
if [[ -r "$theme_file" ]]; then
theme=$(tr -d '[:space:]' < "$theme_file") || true
fi
encoded=""
if [[ -r "$state_file" ]]; then
encoded=$(sed -n 's/^historyJson="\(.*\)"$/\1/p' "$state_file")
fi
history='[]'
if [[ -n "$encoded" ]]; then
history=$(printf '"%s"' "$encoded" | jq -er 'fromjson | if type == "array" then . else error("history is not an array") end' 2> /dev/null) || history='[]'
fi
privacy="show"
if [[ -r "$state_file" ]]; then
privacy=$(sed -n 's/^lockScreenPrivacy=//p' "$state_file" | tr -d '"\r')
case "$privacy" in
"") privacy="show" ;;
show|redact|hide) ;;
*) privacy="hide" ;;
esac
fi
preferences_file="${DOTFILES_PREFERENCES:-$HOME/dotfiles/linux/config/system-settings/preferences.json}"
if [[ -r "$preferences_file" ]]; then
privacy=$(jq -er '.notifications.lockScreenPrivacy' "$preferences_file") || privacy=hide
case "$privacy" in show|redact|hide) ;; *) privacy=hide ;; esac
fi
temporary_source=$(mktemp "${source_file}.XXXXXX")
temporary_png=$(mktemp "${cache_file}.XXXXXX")
trap 'rm -f "$temporary_source" "$temporary_png"' EXIT
printf '%s\n' "$history" | jq -r --arg theme "$theme" --arg privacy "$privacy" '
def clean:
tostring
| gsub("[[:space:]]+"; " ")
| sub("^ +"; "")
| sub(" +$"; "");
def clip($limit):
if length > $limit then .[0:($limit - 3)] + "..." else . end;
def age($time):
((now | floor) - (($time // 0) | tonumber? // 0)) as $seconds
| (if $seconds < 0 then 0 else $seconds end) as $value
| if $value < 60 then "now"
elif $value < 3600 then (($value / 60 | floor) | tostring) + "m"
elif $value < 86400 then (($value / 3600 | floor) | tostring) + "h"
elif $value < 604800 then (($value / 86400 | floor) | tostring) + "d"
else (($value / 604800 | floor) | tostring) + "w"
end;
def cardHeight($record): 64;
def icon($record; $x; $y; $primary):
if (($record.app | ascii_downcase) | contains("microsoft teams")) then
"<g transform=\"translate(" + ($x | tostring) + " " + ($y | tostring) + ") scale(0.3125)\">"
+ "<circle cx=\"49\" cy=\"19\" r=\"10\" fill=\"#7b83eb\"/>"
+ "<circle cx=\"51\" cy=\"46\" r=\"13\" fill=\"#5059c9\"/>"
+ "<path fill=\"#7b83eb\" d=\"M19 18h26a7 7 0 0 1 7 7v21a7 7 0 0 1-7 7H19z\"/>"
+ "<rect x=\"7\" y=\"20\" width=\"34\" height=\"32\" rx=\"6\" fill=\"#5059c9\"/>"
+ "<path fill=\"#fff\" d=\"M14 27h20v5h-7v14h-6V32h-7z\"/></g>"
else
"<path d=\"M10.268 21a2 2 0 0 0 3.464 0M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326\""
+ " transform=\"translate(" + ($x | tostring) + " " + ($y | tostring) + ") scale(0.833333)\""
+ " fill=\"none\" stroke=\"" + $primary + "\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>"
end;
def card($record; $y; $colors):
(if $record.critical then $colors.urgent else $colors.active end) as $iconColor
| (cardHeight($record)) as $height
| "<rect x=\"24\" y=\"" + ($y | tostring) + "\" width=\"552\" height=\"" + ($height | tostring)
+ "\" rx=\"18\" fill=\"" + $colors.surface + "\"/>"
+ (if $record.critical then
"<rect x=\"25\" y=\"" + (($y + 1) | tostring) + "\" width=\"550\" height=\"" + (($height - 2) | tostring)
+ "\" rx=\"17\" fill=\"" + $colors.urgent + "\" fill-opacity=\"0.12\"/>"
else "" end)
+ "<rect x=\"36\" y=\"" + (($y + 12) | tostring) + "\" width=\"40\" height=\"40\" rx=\"12\" fill=\"" + $iconColor + "\"/>"
+ icon($record; 46; ($y + 22); $colors.primary)
+ "<text x=\"88\" y=\"" + (($y + 27) | tostring) + "\" fill=\"" + $colors.secondary + "\" font-size=\"10\">"
+ ($record.app | @html) + "</text>"
+ "<text x=\"562\" y=\"" + (($y + 27) | tostring) + "\" text-anchor=\"end\" fill=\"" + $colors.secondary + "\" font-size=\"10\">"
+ ($record.time | @html) + "</text>"
+ (if $record.summary == "" then "" else
"<text x=\"88\" y=\"" + (($y + 48) | tostring) + "\" fill=\"" + $colors.primary + "\" font-size=\"12\">"
+ ($record.summary | @html) + "</text>"
end)
+ "<rect x=\"24\" y=\"" + ($y | tostring) + "\" width=\"552\" height=\"" + ($height | tostring)
+ "\" rx=\"18\" fill=\"none\" stroke=\"" + $colors.border + "\" stroke-width=\"1\"/>";
(if $theme == "light" then
{surface: "#E8EBEF", border: "#D7DCE3", active: "#C9E1F7", primary: "#20242A", secondary: "#59616D", urgent: "#DA4939"}
else
{surface: "#2B303A", border: "#33404D", active: "#3E5978", primary: "#F8F9FB", secondary: "#B7BEC9", urgent: "#DA4939"}
end) as $colors
| (if type == "array" then . else [] end)
| map(select(type == "object" and ((.summary // "") | type == "string")))
| .[0:4]
| map(
{
app: ((.appName // "Notification") | tostring | clean | clip(32)),
summary: (if $privacy == "redact" then "Content hidden" else ((.summary // "") | clean | clip(58)) end),
critical: ((.urgency // "") == "critical"),
time: age(.time)
}
) as $records
| length as $total
| ($records | map(cardHeight(.)) | add // 0) as $recordHeight
| ($records | length) as $count
| ($recordHeight + (if $count > 0 then ($count - 1) * 10 else 0 end)) as $listHeight
| 64 as $startY
| (reduce $records[] as $record
({svg: "", y: $startY};
.svg += card($record; .y; $colors)
| .y += cardHeight($record) + 10
)) as $rendered
| "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"600\" height=\"600\" viewBox=\"0 0 600 600\" font-family=\"Hack Nerd Font Mono, Hack, monospace\">"
+ "<text x=\"24\" y=\"28\" fill=\"" + $colors.primary + "\" font-size=\"16\" font-weight=\"bold\">Notifications</text>"
+ "<text x=\"576\" y=\"28\" text-anchor=\"end\" fill=\"" + $colors.secondary + "\" font-size=\"12\">"
+ ($total | tostring) + (if $total == 1 then " message" else " messages" end) + "</text>"
+ $rendered.svg
+ (if $total > $count then
"<text x=\"24\" y=\"" + (($startY + $listHeight + 24) | tostring) + "\" fill=\"" + $colors.secondary + "\" font-size=\"11\">+" + (($total - $count) | tostring) + " more in history</text>"
else "" end)
+ "</svg>"
| if $privacy == "hide" then
"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"600\" height=\"600\"></svg>"
else . end
' > "$temporary_source"
if [[ -s "$source_file" && -s "$cache_file" ]] && cmp -s "$temporary_source" "$source_file"; then
rm -f "$temporary_source" "$temporary_png"
trap - EXIT
printf '%s\n' "$cache_file"
exit 0
fi
if command -v magick > /dev/null 2>&1; then
magick -background none "$temporary_source" "PNG32:$temporary_png"
else
convert -background none "$temporary_source" "PNG32:$temporary_png"
fi
if [[ ! -s "$source_file" ]] || ! cmp -s "$temporary_source" "$source_file"; then
mv -f "$temporary_source" "$source_file"
else
rm -f "$temporary_source"
fi
if [[ ! -s "$cache_file" ]] || ! cmp -s "$temporary_png" "$cache_file"; then
mv -f "$temporary_png" "$cache_file"
else
rm -f "$temporary_png"
fi
trap - EXIT
printf '%s\n' "$cache_file"