mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-04 04:42:05 -04:00
feat(notifications): add configurable notification rules (#1655)
This commit is contained in:
@@ -504,6 +504,7 @@ Singleton {
|
||||
property bool notificationHistorySaveLow: true
|
||||
property bool notificationHistorySaveNormal: true
|
||||
property bool notificationHistorySaveCritical: true
|
||||
property var notificationRules: []
|
||||
|
||||
property bool osdAlwaysShowValue: false
|
||||
property int osdPosition: SettingsData.Position.BottomCenter
|
||||
@@ -2134,6 +2135,56 @@ Singleton {
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function addNotificationRule() {
|
||||
var rules = JSON.parse(JSON.stringify(notificationRules || []));
|
||||
rules.push({
|
||||
enabled: true,
|
||||
field: "appName",
|
||||
pattern: "",
|
||||
matchType: "contains",
|
||||
action: "mute",
|
||||
urgency: "default"
|
||||
});
|
||||
notificationRules = rules;
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function updateNotificationRule(index, ruleData) {
|
||||
var rules = JSON.parse(JSON.stringify(notificationRules || []));
|
||||
if (index < 0 || index >= rules.length)
|
||||
return;
|
||||
var existing = rules[index] || {};
|
||||
rules[index] = Object.assign({}, existing, ruleData || {});
|
||||
notificationRules = rules;
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function updateNotificationRuleField(index, key, value) {
|
||||
if (key === undefined || key === null || key === "")
|
||||
return;
|
||||
var patch = {};
|
||||
patch[key] = value;
|
||||
updateNotificationRule(index, patch);
|
||||
}
|
||||
|
||||
function removeNotificationRule(index) {
|
||||
var rules = JSON.parse(JSON.stringify(notificationRules || []));
|
||||
if (index < 0 || index >= rules.length)
|
||||
return;
|
||||
rules.splice(index, 1);
|
||||
notificationRules = rules;
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function getDefaultNotificationRules() {
|
||||
return Spec.SPEC.notificationRules.def;
|
||||
}
|
||||
|
||||
function resetNotificationRules() {
|
||||
notificationRules = JSON.parse(JSON.stringify(Spec.SPEC.notificationRules.def));
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function getDefaultAppIdSubstitutions() {
|
||||
return Spec.SPEC.appIdSubstitutions.def;
|
||||
}
|
||||
|
||||
@@ -330,6 +330,7 @@ var SPEC = {
|
||||
notificationHistorySaveLow: { def: true },
|
||||
notificationHistorySaveNormal: { def: true },
|
||||
notificationHistorySaveCritical: { def: true },
|
||||
notificationRules: { def: [] },
|
||||
|
||||
osdAlwaysShowValue: { def: false },
|
||||
osdPosition: { def: 5 },
|
||||
|
||||
@@ -153,12 +153,12 @@ QtObject {
|
||||
if (!wrapper || !wrapper.notification) {
|
||||
return false;
|
||||
}
|
||||
const incomingUrgency = wrapper.notification.urgency || 0;
|
||||
const incomingUrgency = wrapper.urgency || 0;
|
||||
for (const p of activeWindows) {
|
||||
if (!p.notificationData || !p.notificationData.notification) {
|
||||
continue;
|
||||
}
|
||||
const existingUrgency = p.notificationData.notification.urgency || 0;
|
||||
const existingUrgency = p.notificationData.urgency || 0;
|
||||
if (existingUrgency < incomingUrgency) {
|
||||
return true;
|
||||
}
|
||||
@@ -188,10 +188,9 @@ QtObject {
|
||||
}
|
||||
|
||||
function _selectPopupToRemove(activeWindows, incomingWrapper) {
|
||||
const incomingUrgency = (incomingWrapper && incomingWrapper.notification) ? incomingWrapper.notification.urgency || 0 : 0;
|
||||
const sortedWindows = activeWindows.slice().sort((a, b) => {
|
||||
const aUrgency = (a.notificationData && a.notificationData.notification) ? a.notificationData.notification.urgency || 0 : 0;
|
||||
const bUrgency = (b.notificationData && b.notificationData.notification) ? b.notificationData.notification.urgency || 0 : 0;
|
||||
const aUrgency = (a.notificationData) ? a.notificationData.urgency || 0 : 0;
|
||||
const bUrgency = (b.notificationData) ? b.notificationData.urgency || 0 : 0;
|
||||
if (aUrgency !== bUrgency) {
|
||||
return aUrgency - bUrgency;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,82 @@ Item {
|
||||
}
|
||||
]
|
||||
|
||||
readonly property var notificationRuleFieldOptions: [
|
||||
{
|
||||
value: "appName",
|
||||
label: I18n.tr("App Names", "notification rule match field option")
|
||||
},
|
||||
{
|
||||
value: "desktopEntry",
|
||||
label: I18n.tr("Desktop Entry", "notification rule match field option")
|
||||
},
|
||||
{
|
||||
value: "summary",
|
||||
label: I18n.tr("Summary", "notification rule match field option")
|
||||
},
|
||||
{
|
||||
value: "body",
|
||||
label: I18n.tr("Body", "notification rule match field option")
|
||||
}
|
||||
]
|
||||
|
||||
readonly property var notificationRuleMatchTypeOptions: [
|
||||
{
|
||||
value: "contains",
|
||||
label: I18n.tr("Contains", "notification rule match type option")
|
||||
},
|
||||
{
|
||||
value: "exact",
|
||||
label: I18n.tr("Exact", "notification rule match type option")
|
||||
},
|
||||
{
|
||||
value: "regex",
|
||||
label: I18n.tr("Regex", "notification rule match type option")
|
||||
}
|
||||
]
|
||||
|
||||
readonly property var notificationRuleActionOptions: [
|
||||
{
|
||||
value: "default",
|
||||
label: I18n.tr("Default", "notification rule action option")
|
||||
},
|
||||
{
|
||||
value: "mute",
|
||||
label: I18n.tr("Mute Popups", "notification rule action option")
|
||||
},
|
||||
{
|
||||
value: "ignore",
|
||||
label: I18n.tr("Ignore Completely", "notification rule action option")
|
||||
},
|
||||
{
|
||||
value: "popup_only",
|
||||
label: I18n.tr("Popup Only", "notification rule action option")
|
||||
},
|
||||
{
|
||||
value: "no_history",
|
||||
label: I18n.tr("No History", "notification rule action option")
|
||||
}
|
||||
]
|
||||
|
||||
readonly property var notificationRuleUrgencyOptions: [
|
||||
{
|
||||
value: "default",
|
||||
label: I18n.tr("Default", "notification rule urgency option")
|
||||
},
|
||||
{
|
||||
value: "low",
|
||||
label: I18n.tr("Low Priority", "notification rule urgency option")
|
||||
},
|
||||
{
|
||||
value: "normal",
|
||||
label: I18n.tr("Normal Priority", "notification rule urgency option")
|
||||
},
|
||||
{
|
||||
value: "critical",
|
||||
label: I18n.tr("Critical Priority", "notification rule urgency option")
|
||||
}
|
||||
]
|
||||
|
||||
function getTimeoutText(value) {
|
||||
if (value === undefined || value === null || isNaN(value))
|
||||
return I18n.tr("5 seconds");
|
||||
@@ -73,6 +149,22 @@ Item {
|
||||
return Math.round(value / 60000) + " " + I18n.tr("minutes");
|
||||
}
|
||||
|
||||
function getRuleOptionLabel(options, value, fallback) {
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
if (options[i].value === value)
|
||||
return options[i].label;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
function getRuleOptionValue(options, label, fallback) {
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
if (options[i].label === label)
|
||||
return options[i].value;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
DankFlickable {
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
@@ -165,6 +257,228 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
width: parent.width
|
||||
iconName: "rule_settings"
|
||||
title: I18n.tr("Notification Rules")
|
||||
settingKey: "notificationRules"
|
||||
tags: ["notification", "rules", "mute", "ignore", "priority", "regex", "history"]
|
||||
collapsible: true
|
||||
expanded: false
|
||||
|
||||
headerActions: [
|
||||
DankActionButton {
|
||||
buttonSize: 36
|
||||
iconName: "restart_alt"
|
||||
iconSize: 20
|
||||
visible: JSON.stringify(SettingsData.notificationRules) !== JSON.stringify(SettingsData.getDefaultNotificationRules())
|
||||
backgroundColor: Theme.surfaceContainer
|
||||
iconColor: Theme.surfaceVariantText
|
||||
onClicked: SettingsData.resetNotificationRules()
|
||||
},
|
||||
DankActionButton {
|
||||
buttonSize: 36
|
||||
iconName: "add"
|
||||
iconSize: 20
|
||||
backgroundColor: Theme.surfaceContainer
|
||||
iconColor: Theme.primary
|
||||
onClicked: SettingsData.addNotificationRule()
|
||||
}
|
||||
]
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Create rules to mute, ignore, hide from history, or override notification priority.")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
wrapMode: Text.WordWrap
|
||||
width: parent.width
|
||||
bottomPadding: Theme.spacingS
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: SettingsData.notificationRules
|
||||
|
||||
delegate: Rectangle {
|
||||
id: ruleItem
|
||||
width: parent.width
|
||||
height: ruleColumn.implicitHeight + Theme.spacingM
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.withAlpha(Theme.surfaceContainer, 0.5)
|
||||
|
||||
Column {
|
||||
id: ruleColumn
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingS
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
StyledText {
|
||||
id: ruleLabel
|
||||
text: I18n.tr("Rule") + " " + (index + 1)
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Item {
|
||||
width: Math.max(0, parent.width - ruleLabel.implicitWidth - enableToggle.width - deleteBtn.width - Theme.spacingS * 3)
|
||||
height: 1
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: enableToggle
|
||||
width: 40
|
||||
height: 24
|
||||
hideText: true
|
||||
checked: modelData.enabled !== false
|
||||
onToggled: checked => SettingsData.updateNotificationRuleField(index, "enabled", checked)
|
||||
}
|
||||
|
||||
Item {
|
||||
id: deleteBtn
|
||||
width: 28
|
||||
height: 28
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: Theme.cornerRadius
|
||||
color: deleteArea.containsMouse ? Theme.withAlpha(Theme.error, 0.2) : "transparent"
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: "delete"
|
||||
size: 18
|
||||
color: deleteArea.containsMouse ? Theme.error : Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: deleteArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: SettingsData.removeNotificationRule(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: 2
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Pattern")
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankTextField {
|
||||
width: parent.width
|
||||
text: modelData.pattern || ""
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
placeholderText: I18n.tr("Pattern")
|
||||
onEditingFinished: SettingsData.updateNotificationRuleField(index, "pattern", text)
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Column {
|
||||
width: (parent.width - Theme.spacingS * 3) / 4
|
||||
spacing: 2
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Field")
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
width: parent.width
|
||||
compactMode: true
|
||||
dropdownWidth: parent.width
|
||||
currentValue: root.getRuleOptionLabel(root.notificationRuleFieldOptions, modelData.field, root.notificationRuleFieldOptions[0].label)
|
||||
options: root.notificationRuleFieldOptions.map(o => o.label)
|
||||
onValueChanged: value => SettingsData.updateNotificationRuleField(index, "field", root.getRuleOptionValue(root.notificationRuleFieldOptions, value, "appName"))
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: (parent.width - Theme.spacingS * 3) / 4
|
||||
spacing: 2
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Type")
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
width: parent.width
|
||||
compactMode: true
|
||||
dropdownWidth: parent.width
|
||||
currentValue: root.getRuleOptionLabel(root.notificationRuleMatchTypeOptions, modelData.matchType, root.notificationRuleMatchTypeOptions[0].label)
|
||||
options: root.notificationRuleMatchTypeOptions.map(o => o.label)
|
||||
onValueChanged: value => SettingsData.updateNotificationRuleField(index, "matchType", root.getRuleOptionValue(root.notificationRuleMatchTypeOptions, value, "contains"))
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: (parent.width - Theme.spacingS * 3) / 4
|
||||
spacing: 2
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Action")
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
width: parent.width
|
||||
compactMode: true
|
||||
dropdownWidth: parent.width
|
||||
currentValue: root.getRuleOptionLabel(root.notificationRuleActionOptions, modelData.action, root.notificationRuleActionOptions[0].label)
|
||||
options: root.notificationRuleActionOptions.map(o => o.label)
|
||||
onValueChanged: value => SettingsData.updateNotificationRuleField(index, "action", root.getRuleOptionValue(root.notificationRuleActionOptions, value, "default"))
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: (parent.width - Theme.spacingS * 3) / 4
|
||||
spacing: 2
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Priority")
|
||||
font.pixelSize: Theme.fontSizeSmall - 1
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
width: parent.width
|
||||
compactMode: true
|
||||
dropdownWidth: parent.width
|
||||
currentValue: root.getRuleOptionLabel(root.notificationRuleUrgencyOptions, modelData.urgency, root.notificationRuleUrgencyOptions[0].label)
|
||||
options: root.notificationRuleUrgencyOptions.map(o => o.label)
|
||||
onValueChanged: value => SettingsData.updateNotificationRuleField(index, "urgency", root.getRuleOptionValue(root.notificationRuleUrgencyOptions, value, "default"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
width: parent.width
|
||||
iconName: "lock"
|
||||
|
||||
@@ -260,14 +260,14 @@ Singleton {
|
||||
return Date.now() / 1000.0;
|
||||
}
|
||||
|
||||
function _ingressAllowed(notif) {
|
||||
function _ingressAllowed(urgency) {
|
||||
const t = _nowSec();
|
||||
if (t - _lastIngressSec >= 1.0) {
|
||||
_lastIngressSec = t;
|
||||
_ingressCountThisSec = 0;
|
||||
}
|
||||
_ingressCountThisSec += 1;
|
||||
if (notif.urgency === NotificationUrgency.Critical) {
|
||||
if (urgency === NotificationUrgency.Critical) {
|
||||
return true;
|
||||
}
|
||||
return _ingressCountThisSec <= maxIngressPerSecond;
|
||||
@@ -294,11 +294,13 @@ Singleton {
|
||||
|
||||
function _initWrapperPersistence(wrapper) {
|
||||
const timeoutMs = wrapper.timer ? wrapper.timer.interval : 5000;
|
||||
const isCritical = wrapper.notification && wrapper.notification.urgency === NotificationUrgency.Critical;
|
||||
const isCritical = wrapper && wrapper.urgency === NotificationUrgency.Critical;
|
||||
wrapper.isPersistent = isCritical || (timeoutMs === 0);
|
||||
}
|
||||
|
||||
function _shouldSaveToHistory(urgency) {
|
||||
function _shouldSaveToHistory(urgency, forceDisable) {
|
||||
if (forceDisable === true)
|
||||
return false;
|
||||
if (!SettingsData.notificationHistoryEnabled)
|
||||
return false;
|
||||
switch (urgency) {
|
||||
@@ -311,6 +313,126 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
function _resolveAppNameForRule(notif) {
|
||||
if (!notif)
|
||||
return "";
|
||||
if (notif.appName && notif.appName !== "")
|
||||
return notif.appName;
|
||||
const entry = DesktopEntries.heuristicLookup(notif.desktopEntry);
|
||||
if (entry && entry.name)
|
||||
return entry.name;
|
||||
return "";
|
||||
}
|
||||
|
||||
function _ruleFieldValue(field, info) {
|
||||
switch ((field || "").toString()) {
|
||||
case "desktopEntry":
|
||||
return info.desktopEntry;
|
||||
case "summary":
|
||||
return info.summary;
|
||||
case "body":
|
||||
return info.body;
|
||||
case "appName":
|
||||
default:
|
||||
return info.appName;
|
||||
}
|
||||
}
|
||||
|
||||
function _coerceRuleUrgency(value, fallbackUrgency) {
|
||||
if (typeof value === "number" && value >= NotificationUrgency.Low && value <= NotificationUrgency.Critical)
|
||||
return value;
|
||||
|
||||
const mapped = (value || "default").toString().toLowerCase();
|
||||
switch (mapped) {
|
||||
case "low":
|
||||
return NotificationUrgency.Low;
|
||||
case "normal":
|
||||
return NotificationUrgency.Normal;
|
||||
case "critical":
|
||||
return NotificationUrgency.Critical;
|
||||
default:
|
||||
return fallbackUrgency;
|
||||
}
|
||||
}
|
||||
|
||||
function _matchesNotificationRule(rule, info) {
|
||||
if (!rule)
|
||||
return false;
|
||||
if (rule.enabled === false)
|
||||
return false;
|
||||
|
||||
const pattern = (rule.pattern || "").toString();
|
||||
if (!pattern.trim())
|
||||
return false;
|
||||
|
||||
const value = (_ruleFieldValue(rule.field, info) || "").toString();
|
||||
const matchType = (rule.matchType || "contains").toString().toLowerCase();
|
||||
|
||||
if (matchType === "exact")
|
||||
return value.toLowerCase() === pattern.toLowerCase();
|
||||
if (matchType === "regex") {
|
||||
try {
|
||||
return new RegExp(pattern, "i").test(value);
|
||||
} catch (e) {
|
||||
console.warn("NotificationService: invalid notification rule regex:", pattern);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return value.toLowerCase().includes(pattern.toLowerCase());
|
||||
}
|
||||
|
||||
function _evaluateNotificationPolicy(notif) {
|
||||
const baseUrgency = typeof notif.urgency === "number" ? notif.urgency : NotificationUrgency.Normal;
|
||||
const policy = {
|
||||
"drop": false,
|
||||
"disablePopup": false,
|
||||
"hideFromCenter": false,
|
||||
"disableHistory": false,
|
||||
"urgency": baseUrgency
|
||||
};
|
||||
|
||||
const rules = SettingsData.notificationRules || [];
|
||||
if (!rules.length)
|
||||
return policy;
|
||||
|
||||
const info = {
|
||||
"appName": _resolveAppNameForRule(notif),
|
||||
"desktopEntry": notif.desktopEntry || "",
|
||||
"summary": notif.summary || "",
|
||||
"body": notif.body || ""
|
||||
};
|
||||
|
||||
for (const rule of rules) {
|
||||
if (!_matchesNotificationRule(rule, info))
|
||||
continue;
|
||||
|
||||
const action = (rule.action || "default").toString().toLowerCase();
|
||||
switch (action) {
|
||||
case "ignore":
|
||||
policy.drop = true;
|
||||
break;
|
||||
case "mute":
|
||||
policy.disablePopup = true;
|
||||
break;
|
||||
case "popup_only":
|
||||
policy.hideFromCenter = true;
|
||||
policy.disableHistory = true;
|
||||
break;
|
||||
case "no_history":
|
||||
policy.disableHistory = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
policy.urgency = _coerceRuleUrgency(rule.urgency, policy.urgency);
|
||||
return policy;
|
||||
}
|
||||
|
||||
return policy;
|
||||
}
|
||||
|
||||
function pruneHistory() {
|
||||
const maxAgeDays = SettingsData.notificationHistoryMaxAgeDays;
|
||||
if (maxAgeDays <= 0)
|
||||
@@ -440,8 +562,16 @@ Singleton {
|
||||
onNotification: notif => {
|
||||
notif.tracked = true;
|
||||
|
||||
if (!_ingressAllowed(notif)) {
|
||||
if (notif.urgency !== NotificationUrgency.Critical) {
|
||||
const policy = _evaluateNotificationPolicy(notif);
|
||||
if (policy.drop) {
|
||||
try {
|
||||
notif.dismiss();
|
||||
} catch (e) {}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_ingressAllowed(policy.urgency)) {
|
||||
if (policy.urgency !== NotificationUrgency.Critical) {
|
||||
try {
|
||||
notif.dismiss();
|
||||
} catch (e) {}
|
||||
@@ -450,25 +580,35 @@ Singleton {
|
||||
}
|
||||
|
||||
if (SettingsData.soundsEnabled && SettingsData.soundNewNotification) {
|
||||
if (notif.urgency === NotificationUrgency.Critical) {
|
||||
if (policy.urgency === NotificationUrgency.Critical) {
|
||||
AudioService.playCriticalNotificationSound();
|
||||
} else {
|
||||
AudioService.playNormalNotificationSound();
|
||||
}
|
||||
}
|
||||
|
||||
const shouldShowPopup = !root.popupsDisabled && !SessionData.doNotDisturb;
|
||||
const shouldShowPopup = !root.popupsDisabled && !SessionData.doNotDisturb && !policy.disablePopup;
|
||||
const isTransient = notif.transient;
|
||||
const shouldKeepInCenter = !isTransient && !policy.hideFromCenter;
|
||||
|
||||
if (!shouldShowPopup && !shouldKeepInCenter) {
|
||||
try {
|
||||
notif.dismiss();
|
||||
} catch (e) {}
|
||||
return;
|
||||
}
|
||||
|
||||
const wrapper = notifComponent.createObject(root, {
|
||||
"popup": shouldShowPopup,
|
||||
"notification": notif
|
||||
"notification": notif,
|
||||
"urgencyOverride": policy.urgency
|
||||
});
|
||||
|
||||
if (wrapper) {
|
||||
root.allWrappers.push(wrapper);
|
||||
if (!isTransient) {
|
||||
if (shouldKeepInCenter) {
|
||||
root.notifications.push(wrapper);
|
||||
if (_shouldSaveToHistory(notif.urgency)) {
|
||||
if (_shouldSaveToHistory(wrapper.urgency, policy.disableHistory)) {
|
||||
root.addToHistory(wrapper);
|
||||
}
|
||||
}
|
||||
@@ -505,7 +645,7 @@ Singleton {
|
||||
interval: {
|
||||
if (!wrapper.notification)
|
||||
return 5000;
|
||||
switch (wrapper.notification.urgency) {
|
||||
switch (wrapper.urgency) {
|
||||
case NotificationUrgency.Low:
|
||||
return SettingsData.notificationTimeoutLow;
|
||||
case NotificationUrgency.Critical:
|
||||
@@ -600,7 +740,8 @@ Singleton {
|
||||
return "";
|
||||
return Paths.strip(image);
|
||||
}
|
||||
readonly property int urgency: notification?.urgency ?? 1
|
||||
property int urgencyOverride: notification?.urgency ?? NotificationUrgency.Normal
|
||||
readonly property int urgency: urgencyOverride
|
||||
readonly property list<NotificationAction> actions: notification?.actions ?? []
|
||||
|
||||
readonly property Connections conn: Connections {
|
||||
|
||||
Reference in New Issue
Block a user