1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-04 12:52:06 -04:00

Add Notification Rules

- Additional right-click ops
- Allow for 3rd boy line on init notification popup
This commit is contained in:
purian23
2026-02-13 12:59:29 -05:00
committed by bbedward
parent be133b73c7
commit 9f13546b4d
6 changed files with 182 additions and 19 deletions

View File

@@ -749,7 +749,7 @@ Rectangle {
Menu {
id: notificationCardContextMenu
width: 220
width: 300
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
background: Rectangle {
@@ -760,7 +760,9 @@ Rectangle {
}
MenuItem {
text: I18n.tr("Mute popups for %1").arg(notificationGroup?.appName || I18n.tr("this app"))
id: muteUnmuteItem
readonly property bool isMuted: SettingsData.isAppMuted(notificationGroup?.appName || "", notificationGroup?.latestNotification?.desktopEntry || "")
text: isMuted ? I18n.tr("Unmute popups for %1").arg(notificationGroup?.appName || I18n.tr("this app")) : I18n.tr("Mute popups for %1").arg(notificationGroup?.appName || I18n.tr("this app"))
contentItem: StyledText {
text: parent.text
@@ -778,8 +780,12 @@ Rectangle {
onTriggered: {
const appName = notificationGroup?.appName || "";
const desktopEntry = notificationGroup?.latestNotification?.desktopEntry || "";
SettingsData.addMuteRuleForApp(appName, desktopEntry);
NotificationService.dismissGroup(notificationGroup?.key || "");
if (isMuted) {
SettingsData.removeMuteRuleForApp(appName, desktopEntry);
} else {
SettingsData.addMuteRuleForApp(appName, desktopEntry);
NotificationService.dismissGroup(notificationGroup?.key || "");
}
}
}

View File

@@ -28,7 +28,7 @@ PanelWindow {
readonly property real popupIconSize: compactMode ? 48 : 63
readonly property real contentSpacing: compactMode ? Theme.spacingXS : Theme.spacingS
readonly property real actionButtonHeight: compactMode ? 20 : 24
readonly property real collapsedContentHeight: popupIconSize
readonly property real collapsedContentHeight: popupIconSize + (compactMode ? 0 : Theme.fontSizeSmall * 1.2)
readonly property real basePopupHeight: cardPadding * 2 + collapsedContentHeight + actionButtonHeight + Theme.spacingS
signal entered
@@ -104,9 +104,9 @@ PanelWindow {
if (!descriptionExpanded)
return basePopupHeight;
const bodyTextHeight = bodyText.contentHeight || 0;
const twoLineHeight = Theme.fontSizeSmall * 1.2 * 2;
if (bodyTextHeight > twoLineHeight + 2)
return basePopupHeight + bodyTextHeight - twoLineHeight;
const collapsedBodyHeight = Theme.fontSizeSmall * 1.2 * (compactMode ? 1 : 3);
if (bodyTextHeight > collapsedBodyHeight + 2)
return basePopupHeight + bodyTextHeight - collapsedBodyHeight;
return basePopupHeight;
}
onHasValidDataChanged: {
@@ -317,8 +317,8 @@ PanelWindow {
id: notificationContent
readonly property real expandedTextHeight: bodyText.contentHeight || 0
readonly property real twoLineHeight: Theme.fontSizeSmall * 1.2 * 2
readonly property real extraHeight: (descriptionExpanded && expandedTextHeight > twoLineHeight + 2) ? (expandedTextHeight - twoLineHeight) : 0
readonly property real collapsedBodyHeight: Theme.fontSizeSmall * 1.2 * (compactMode ? 1 : 3)
readonly property real extraHeight: (descriptionExpanded && expandedTextHeight > collapsedBodyHeight + 2) ? (expandedTextHeight - collapsedBodyHeight) : 0
anchors.top: parent.top
anchors.left: parent.left
@@ -437,7 +437,7 @@ PanelWindow {
width: parent.width
elide: descriptionExpanded ? Text.ElideNone : Text.ElideRight
horizontalAlignment: Text.AlignLeft
maximumLineCount: descriptionExpanded ? -1 : (compactMode ? 1 : 2)
maximumLineCount: descriptionExpanded ? -1 : (compactMode ? 1 : 3)
wrapMode: Text.WordWrap
visible: text.length > 0
linkColor: Theme.primary
@@ -816,7 +816,7 @@ PanelWindow {
Menu {
id: popupContextMenu
width: 220
width: 300
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
background: Rectangle {
@@ -827,7 +827,9 @@ PanelWindow {
}
MenuItem {
text: I18n.tr("Mute popups for %1").arg(notificationData?.appName || I18n.tr("this app"))
id: muteUnmuteItem
readonly property bool isMuted: SettingsData.isAppMuted(notificationData?.appName || "", notificationData?.desktopEntry || "")
text: isMuted ? I18n.tr("Unmute popups for %1").arg(notificationData?.appName || I18n.tr("this app")) : I18n.tr("Mute popups for %1").arg(notificationData?.appName || I18n.tr("this app"))
contentItem: StyledText {
text: parent.text
@@ -845,9 +847,13 @@ PanelWindow {
onTriggered: {
const appName = notificationData?.appName || "";
const desktopEntry = notificationData?.desktopEntry || "";
SettingsData.addMuteRuleForApp(appName, desktopEntry);
if (notificationData && !exiting)
NotificationService.dismissNotification(notificationData);
if (isMuted) {
SettingsData.removeMuteRuleForApp(appName, desktopEntry);
} else {
SettingsData.addMuteRuleForApp(appName, desktopEntry);
if (notificationData && !exiting)
NotificationService.dismissNotification(notificationData);
}
}
}

View File

@@ -11,7 +11,7 @@ QtObject {
readonly property real cardPadding: compactMode ? Theme.spacingS : Theme.spacingM
readonly property real popupIconSize: compactMode ? 48 : 63
readonly property real actionButtonHeight: compactMode ? 20 : 24
readonly property real popupSpacing: 4
readonly property real popupSpacing: 8
readonly property int baseNotificationHeight: cardPadding * 2 + popupIconSize + actionButtonHeight + Theme.spacingS + popupSpacing
property int maxTargetNotifications: 4
property var popupWindows: [] // strong refs to windows (live until exitFinished)

View File

@@ -6,6 +6,16 @@ import qs.Modules.Settings.Widgets
Item {
id: root
readonly property var mutedRules: {
var rules = SettingsData.notificationRules || [];
var out = [];
for (var i = 0; i < rules.length; i++) {
if ((rules[i].action || "").toString().toLowerCase() === "mute")
out.push({ rule: rules[i], index: i });
}
return out;
}
readonly property var timeoutOptions: [
{
text: I18n.tr("Never"),
@@ -478,6 +488,7 @@ Item {
width: parent.width
compactMode: true
dropdownWidth: parent.width
popupWidth: 165
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"))
@@ -518,6 +529,7 @@ Item {
width: parent.width
compactMode: true
dropdownWidth: parent.width
popupWidth: 170
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"))
@@ -538,6 +550,7 @@ Item {
width: parent.width
compactMode: true
dropdownWidth: parent.width
popupWidth: 165
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"))
@@ -550,6 +563,95 @@ Item {
}
}
SettingsCard {
width: parent.width
iconName: "volume_off"
title: I18n.tr("Muted Apps")
settingKey: "mutedApps"
tags: ["notification", "mute", "unmute", "popup"]
Column {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: mutedRules.length > 0 ? I18n.tr("Apps with notification popups muted. Unmute or delete to remove.") : I18n.tr("No apps muted. Right-click a notification and choose \"Mute popups\" to add one here.")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
width: parent.width
bottomPadding: Theme.spacingS
}
Repeater {
model: mutedRules
delegate: Rectangle {
width: parent.width
height: mutedRow.implicitHeight + Theme.spacingS * 2
radius: Theme.cornerRadius
color: Theme.withAlpha(Theme.surfaceContainer, 0.5)
Row {
id: mutedRow
anchors.fill: parent
anchors.margins: Theme.spacingS
spacing: Theme.spacingM
StyledText {
id: mutedAppLabel
text: (modelData.rule && modelData.rule.pattern) ? modelData.rule.pattern : I18n.tr("Unknown")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: Math.max(0, parent.width - parent.spacing - mutedAppLabel.width - unmuteBtn.width - deleteBtn.width - Theme.spacingS * 5)
height: 1
}
DankButton {
id: unmuteBtn
text: I18n.tr("Unmute")
backgroundColor: Theme.surfaceContainer
textColor: Theme.primary
onClicked: SettingsData.removeNotificationRule(modelData.index)
}
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(modelData.index)
}
}
}
}
}
}
}
SettingsCard {
width: parent.width
iconName: "lock"