diff options
| -rw-r--r-- | notifications/NotificationBalloon.qml | 9 | ||||
| -rw-r--r-- | shared/NotifyConfig.js | 10 | ||||
| -rw-r--r-- | shared/test_notify_config.js | 14 |
3 files changed, 25 insertions, 8 deletions
diff --git a/notifications/NotificationBalloon.qml b/notifications/NotificationBalloon.qml index 6a674b8..b5af3ab 100644 --- a/notifications/NotificationBalloon.qml +++ b/notifications/NotificationBalloon.qml @@ -32,13 +32,8 @@ Rectangle { // everything; a muted app and DND are config.json's call (DND passes // critical unless dndPassCritical is off). The drawer still lists what // was withheld, because a list the user opened is not an interruption. - visible: { - if (Notify.drawerOpen) return false; - if (Notify.snoozeUntil > b.now) return false; - if (NC.withheld(Notify.config, b.notification, Notify.dnd)) return false; - if (b.notification.expires !== 0 && b.now >= b.notification.expires) return false; - return true; - } + visible: NC.shown(Notify.config, b.notification, Notify.dnd, Notify.drawerOpen, + Notify.snoozeUntil, b.now) width: parent ? parent.width : 340 implicitHeight: texts.implicitHeight + 20 + (preview.visible ? preview.height + 8 : 0) diff --git a/shared/NotifyConfig.js b/shared/NotifyConfig.js index 143168f..6fc98e6 100644 --- a/shared/NotifyConfig.js +++ b/shared/NotifyConfig.js @@ -71,6 +71,16 @@ function withheld(cfg, n, dnd) { return dnd && !(n.urgency === "critical" && cfg.dndPassCritical); } +// Whether a queued notification's balloon is on screen at `now`: the drawer +// and snooze withhold everything, then mute and DND, then its own expiry. +// The balloon shell and the desktop companion both ask this, so they cannot +// disagree about what is showing. +function shown(cfg, n, dnd, drawerOpen, snoozeUntil, now) { + if (drawerOpen || snoozeUntil > now) return false; + if (withheld(cfg, n, dnd)) return false; + return n.expires === 0 || now < n.expires; +} + // The file a balloon plays, "" for none: the app's suppress-sound wins, then // the app's own sound (notifyd resolved its hints), then the urgency's. function soundFor(cfg, n) { diff --git a/shared/test_notify_config.js b/shared/test_notify_config.js index c7bc2cc..4e8db23 100644 --- a/shared/test_notify_config.js +++ b/shared/test_notify_config.js @@ -18,7 +18,7 @@ const assert = require("assert"); const src = fs.readFileSync(__dirname + "/NotifyConfig.js", "utf8") .replace(/^\.pragma library$/m, ""); -const C = new Function(src + "\nreturn { defaults, resolve, withheld, soundFor };")(); +const C = new Function(src + "\nreturn { defaults, resolve, withheld, soundFor, shown };")(); // Nothing, or garbage, is the defaults. assert.deepStrictEqual(C.resolve(undefined), C.defaults()); @@ -64,4 +64,16 @@ assert.strictEqual(C.soundFor(sc, sn("critical", "/app.oga", true)), ""); // An old daemon publishes neither field. assert.strictEqual(C.soundFor(sc, { app: "x", urgency: "critical" }), "/c.oga"); +// On screen: the drawer, snooze, mute, DND and expiry, in one check that +// the balloons and the desktop companion share. +const live = { app: "ok", urgency: "normal", expires: 0 }; +assert.strictEqual(C.shown(cfg, live, false, false, 0, 5000), true); +assert.strictEqual(C.shown(cfg, live, false, true, 0, 5000), false); // drawer open +assert.strictEqual(C.shown(cfg, live, false, false, 6000, 5000), false); // snoozed +assert.strictEqual(C.shown(cfg, { app: "spam", urgency: "normal", expires: 0 }, false, false, 0, 5000), false); +assert.strictEqual(C.shown(cfg, live, true, false, 0, 5000), false); // DND +const timed = { app: "ok", urgency: "normal", expires: 5000 }; +assert.strictEqual(C.shown(cfg, timed, false, false, 0, 4999), true); +assert.strictEqual(C.shown(cfg, timed, false, false, 0, 5000), false); // expired + console.log("ok"); |
