1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-06-08 04:09:15 -04:00

refactor(Notifications): further support for duplicate notification logic

- New setting to stack or suppress identical alerts (on by default)
Closes #2334
This commit is contained in:
purian23
2026-05-24 22:22:34 -04:00
parent 6093c37b41
commit d9525908f1
6 changed files with 122 additions and 38 deletions
+66 -21
View File
@@ -35,6 +35,8 @@ Singleton {
property int maxIngressPerSecond: 20
property double _lastIngressSec: 0
property int _ingressCountThisSec: 0
readonly property int notificationDedupBurstMs: 5000
property var _recentDedupKeys: []
property var _dismissQueue: []
property int _dismissBatchSize: 8
@@ -291,18 +293,58 @@ Singleton {
return Date.now() / 1000.0;
}
function _normalizeDedupText(text) {
if (!text)
return "";
let normalized = text.toString();
normalized = normalized.replace(/<img\b[^>]*>/gi, "");
normalized = normalized.replace(/<[^>]+>/g, "");
normalized = normalized.replace(/\s+/g, " ").trim();
return normalized.toLowerCase();
}
function _dedupAppId(source) {
if (!source)
return "";
const desktopEntry = (source.desktopEntry || "").toString().trim().toLowerCase();
if (desktopEntry)
return desktopEntry;
return (source.appName || "").toString().trim().toLowerCase();
}
function _notificationDedupKey(source) {
if (!source)
return "";
const app = (source.appName || source.desktopEntry || "").toString();
const summary = (source.summary || "").toString();
const body = (source.body || "").toString();
const app = _dedupAppId(source);
const summary = _normalizeDedupText(source.summary);
const body = _normalizeDedupText(source.body);
const urgency = typeof source.urgency === "number" ? source.urgency : NotificationUrgency.Normal;
const icon = (source.appIcon || "").toString();
if (!app && !summary && !body)
return "";
const sep = "";
return app + sep + summary + sep + body + sep + urgency + sep + icon;
return app + sep + summary + sep + body + sep + urgency;
}
function _pruneRecentDedupKeys() {
const cutoff = Date.now() - notificationDedupBurstMs;
_recentDedupKeys = _recentDedupKeys.filter(entry => entry && entry.atMs >= cutoff);
}
function _hasRecentDuplicate(key) {
if (!key)
return false;
_pruneRecentDedupKeys();
return _recentDedupKeys.some(entry => entry && entry.key === key);
}
function _recordDedupKey(key) {
if (!key)
return;
_pruneRecentDedupKeys();
_recentDedupKeys.push({
"key": key,
"atMs": Date.now()
});
}
function _findActiveDuplicate(notif) {
@@ -310,17 +352,14 @@ Singleton {
if (!key)
return null;
for (const w of visibleNotifications) {
for (const w of allWrappers) {
if (!w || !w.notification || !w.popup)
continue;
if (_notificationDedupKey(w.notification) === key)
return w;
}
for (const w of notificationQueue) {
if (!w || !w.notification)
if (_notificationDedupKey(w.notification) !== key)
continue;
if (_notificationDedupKey(w.notification) === key)
if (visibleNotifications.indexOf(w) !== -1 || notificationQueue.indexOf(w) !== -1)
return w;
if (w.timer && w.timer.running)
return w;
}
@@ -637,14 +676,17 @@ Singleton {
return;
}
const duplicate = _findActiveDuplicate(notif);
if (duplicate) {
if (duplicate.timer && duplicate.timer.running)
duplicate.timer.restart();
try {
notif.dismiss();
} catch (e) {}
return;
if (SettingsData.notificationDedupeEnabled) {
const dedupKey = _notificationDedupKey(notif);
const duplicate = _findActiveDuplicate(notif);
if (duplicate || _hasRecentDuplicate(dedupKey)) {
if (duplicate && duplicate.timer && duplicate.timer.running)
duplicate.timer.restart();
try {
notif.dismiss();
} catch (e) {}
return;
}
}
if (!_ingressAllowed(policy.urgency)) {
@@ -686,6 +728,9 @@ Singleton {
});
if (wrapper) {
if (SettingsData.notificationDedupeEnabled)
_recordDedupKey(_notificationDedupKey(notif));
root.allWrappers.push(wrapper);
if (shouldKeepInCenter) {
root.notifications.push(wrapper);