Show friendly app names and make dictation notifications toast-only
This commit is contained in:
parent
330353e07f
commit
547e087a5b
|
|
@ -14,11 +14,43 @@ export const dndIcon = Variable.derive([bind(notifd, "dontDisturb")], (dnd) =>
|
||||||
|
|
||||||
// every notification received this session is kept until it is explicitly
|
// every notification received this session is kept until it is explicitly
|
||||||
// cleared, so popups that time out remain in the dropdown's list. only
|
// cleared, so popups that time out remain in the dropdown's list. only
|
||||||
// notifications dismissed directly from their popup skip the list.
|
// notifications dismissed directly from their popup skip the list, and
|
||||||
|
// transient status toasts never enter it at all.
|
||||||
export const history = Variable<Notifd.Notification[]>([])
|
export const history = Variable<Notifd.Notification[]>([])
|
||||||
|
|
||||||
export const notifCount = bind(history).as((ns) => ns.length)
|
export const notifCount = bind(history).as((ns) => ns.length)
|
||||||
|
|
||||||
|
// apps whose notifications are transient status updates: they surface as
|
||||||
|
// toasts only and never enter the dropdown history or the bar count
|
||||||
|
const EPHEMERAL_APPS = new Set(["dictation"])
|
||||||
|
|
||||||
|
// irregular ids the generic capitalization rule can't fix up
|
||||||
|
const FRIENDLY_NAMES: Record<string, string> = {
|
||||||
|
"notify-send": "Notification",
|
||||||
|
}
|
||||||
|
|
||||||
|
// per-app icons for notifications that don't supply one
|
||||||
|
const APP_ICONS: Record<string, string> = {
|
||||||
|
dictation: "audio-input-microphone-symbolic",
|
||||||
|
}
|
||||||
|
|
||||||
|
// apps like discord report a bare binary id; make words of those while
|
||||||
|
// names with any uppercase ("Spotify") pass through untouched
|
||||||
|
function displayName(n: Notifd.Notification) {
|
||||||
|
const raw = n.app_name || "Notification"
|
||||||
|
|
||||||
|
const mapped = FRIENDLY_NAMES[raw.toLowerCase()]
|
||||||
|
if (mapped) return mapped
|
||||||
|
|
||||||
|
if (raw === raw.toLowerCase() && /[a-z]/.test(raw)) {
|
||||||
|
return raw
|
||||||
|
.split(/[-_ ]+/)
|
||||||
|
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
||||||
|
.join(" ")
|
||||||
|
}
|
||||||
|
return raw
|
||||||
|
}
|
||||||
|
|
||||||
export function DndToggle() {
|
export function DndToggle() {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
|
@ -49,6 +81,8 @@ notifd.connect("notified", (_, id: number) => {
|
||||||
const n = notifd.get_notification(id)
|
const n = notifd.get_notification(id)
|
||||||
if (!n) return
|
if (!n) return
|
||||||
|
|
||||||
|
if (EPHEMERAL_APPS.has(n.app_name.toLowerCase())) return
|
||||||
|
|
||||||
// re-notified ids update the existing entry instead of adding a duplicate
|
// re-notified ids update the existing entry instead of adding a duplicate
|
||||||
if (!history.get().some((m) => m.id === id)) {
|
if (!history.get().some((m) => m.id === id)) {
|
||||||
history.set([...history.get(), n])
|
history.set([...history.get(), n])
|
||||||
|
|
@ -99,6 +133,11 @@ function formatTime(n: Notifd.Notification) {
|
||||||
|
|
||||||
export function NotificationCard(n: Notifd.Notification, toast = false) {
|
export function NotificationCard(n: Notifd.Notification, toast = false) {
|
||||||
const critical = n.urgency === Notifd.Urgency.CRITICAL
|
const critical = n.urgency === Notifd.Urgency.CRITICAL
|
||||||
|
const appName = displayName(n)
|
||||||
|
const appIcon =
|
||||||
|
n.app_icon ||
|
||||||
|
APP_ICONS[appName.toLowerCase()] ||
|
||||||
|
"preferences-system-notifications-symbolic"
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
|
@ -113,13 +152,10 @@ export function NotificationCard(n: Notifd.Notification, toast = false) {
|
||||||
>
|
>
|
||||||
<box vertical>
|
<box vertical>
|
||||||
<box className="notif-header">
|
<box className="notif-header">
|
||||||
<icon
|
<icon pixelSize={16} icon={appIcon} />
|
||||||
pixelSize={16}
|
|
||||||
icon={n.app_icon || "preferences-system-notifications-symbolic"}
|
|
||||||
/>
|
|
||||||
<label
|
<label
|
||||||
className="notif-app-name"
|
className="notif-app-name"
|
||||||
label={n.app_name || "Notification"}
|
label={appName}
|
||||||
halign={Gtk.Align.START}
|
halign={Gtk.Align.START}
|
||||||
hexpand
|
hexpand
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,9 @@ let
|
||||||
wav="$dir/clip.wav"
|
wav="$dir/clip.wav"
|
||||||
|
|
||||||
notify() {
|
notify() {
|
||||||
notify-send -t 2500 "Dictation" "$1" 2>/dev/null || true
|
# -a sets the app name shown by the notification daemon; the bar
|
||||||
|
# treats "Dictation" as transient (toast only, never listed)
|
||||||
|
notify-send -a "Dictation" -t 2500 "$1" 2>/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
case "''${1:-}" in
|
case "''${1:-}" in
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue