1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-25 05:52:50 -05:00

notifications: add support for none, count, app name, and full detail

for lock screen
fixes #557
This commit is contained in:
bbedward
2026-01-05 12:22:05 -05:00
parent 850e5b6572
commit 824792cca7
21 changed files with 6081 additions and 461 deletions

View File

@@ -348,10 +348,305 @@ Item {
opacity: 0.9
}
Item {
id: lockNotificationPanel
readonly property int notificationMode: SettingsData.lockScreenNotificationMode
readonly property var notifications: NotificationService.groupedNotifications
readonly property int totalCount: {
let count = 0;
for (const group of notifications) {
count += group.count || 0;
}
return count;
}
readonly property bool hasNotifications: totalCount > 0
readonly property var appNameGroups: {
const groups = {};
for (const group of notifications) {
const appName = (group.appName || "Unknown").toLowerCase();
if (!groups[appName]) {
groups[appName] = {
appName: group.appName || I18n.tr("Unknown"),
count: 0,
latestNotification: group.latestNotification
};
}
groups[appName].count += group.count || 0;
if (group.latestNotification && (!groups[appName].latestNotification || group.latestNotification.time > groups[appName].latestNotification.time)) {
groups[appName].latestNotification = group.latestNotification;
}
}
return Object.values(groups).sort((a, b) => b.count - a.count);
}
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: dateText.visible ? dateText.bottom : clockContainer.bottom
anchors.topMargin: Theme.spacingM
width: Math.min(380, parent.width - Theme.spacingXL * 2)
height: notificationMode === 0 || !hasNotifications ? 0 : contentLoader.height
visible: notificationMode > 0 && hasNotifications
clip: true
Behavior on height {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.standardEasing
}
}
Loader {
id: contentLoader
anchors.left: parent.left
anchors.right: parent.right
active: lockNotificationPanel.notificationMode > 0 && lockNotificationPanel.hasNotifications
sourceComponent: {
switch (lockNotificationPanel.notificationMode) {
case 1:
return countOnlyComponent;
case 2:
return appNamesComponent;
case 3:
return fullContentComponent;
default:
return null;
}
}
}
Component {
id: countOnlyComponent
Rectangle {
width: parent.width
height: 44
radius: Theme.cornerRadius
color: Qt.rgba(0, 0, 0, 0.3)
border.color: Qt.rgba(1, 1, 1, 0.1)
border.width: 1
Row {
anchors.centerIn: parent
spacing: Theme.spacingS
DankIcon {
name: "notifications"
size: Theme.iconSize
color: "white"
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: lockNotificationPanel.totalCount === 1 ? I18n.tr("1 notification") : I18n.tr("%1 notifications").arg(lockNotificationPanel.totalCount)
font.pixelSize: Theme.fontSizeMedium
color: "white"
anchors.verticalCenter: parent.verticalCenter
}
}
}
}
Component {
id: appNamesComponent
Rectangle {
width: parent.width
height: Math.min(appNamesColumn.implicitHeight + Theme.spacingM * 2, 200)
radius: Theme.cornerRadius
color: Qt.rgba(0, 0, 0, 0.3)
border.color: Qt.rgba(1, 1, 1, 0.1)
border.width: 1
clip: true
Flickable {
anchors.fill: parent
anchors.margins: Theme.spacingM
contentHeight: appNamesColumn.implicitHeight
clip: true
boundsBehavior: Flickable.StopAtBounds
Column {
id: appNamesColumn
width: parent.width
spacing: Theme.spacingS
Repeater {
model: lockNotificationPanel.appNameGroups.slice(0, 5)
Row {
required property var modelData
width: parent.width
spacing: Theme.spacingS
DankIcon {
name: "notifications"
size: Theme.iconSize - 4
color: "white"
opacity: 0.8
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: modelData.appName || I18n.tr("Unknown")
font.pixelSize: Theme.fontSizeMedium
color: "white"
elide: Text.ElideRight
width: parent.width - Theme.iconSize - countBadge.width - Theme.spacingS * 2
anchors.verticalCenter: parent.verticalCenter
}
Rectangle {
id: countBadge
width: countText.implicitWidth + Theme.spacingS * 2
height: 20
radius: 10
color: Qt.rgba(1, 1, 1, 0.2)
visible: modelData.count > 1
anchors.verticalCenter: parent.verticalCenter
StyledText {
id: countText
anchors.centerIn: parent
text: modelData.count > 99 ? "99+" : modelData.count.toString()
font.pixelSize: Theme.fontSizeSmall
color: "white"
}
}
}
}
StyledText {
visible: lockNotificationPanel.appNameGroups.length > 5
text: I18n.tr("+ %1 more").arg(lockNotificationPanel.appNameGroups.length - 5)
font.pixelSize: Theme.fontSizeSmall
color: "white"
opacity: 0.7
}
}
}
}
}
Component {
id: fullContentComponent
Rectangle {
width: parent.width
height: Math.min(fullContentColumn.implicitHeight + Theme.spacingM * 2, 280)
radius: Theme.cornerRadius
color: Qt.rgba(0, 0, 0, 0.3)
border.color: Qt.rgba(1, 1, 1, 0.1)
border.width: 1
clip: true
Flickable {
anchors.fill: parent
anchors.margins: Theme.spacingM
contentHeight: fullContentColumn.implicitHeight
clip: true
boundsBehavior: Flickable.StopAtBounds
Column {
id: fullContentColumn
width: parent.width
spacing: Theme.spacingM
Repeater {
model: {
const items = [];
for (const group of lockNotificationPanel.appNameGroups) {
if (group.latestNotification && items.length < 5) {
items.push(group.latestNotification);
}
}
return items;
}
Rectangle {
required property var modelData
required property int index
width: parent.width
height: notifContent.implicitHeight + Theme.spacingS * 2
radius: Theme.cornerRadius - 4
color: Qt.rgba(1, 1, 1, 0.05)
Column {
id: notifContent
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: Theme.spacingS
spacing: 2
Row {
width: parent.width
spacing: Theme.spacingXS
StyledText {
text: modelData.appName || I18n.tr("Unknown")
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: "white"
opacity: 0.7
elide: Text.ElideRight
width: parent.width - timeText.implicitWidth - Theme.spacingXS
}
StyledText {
id: timeText
text: modelData.timeStr || ""
font.pixelSize: Theme.fontSizeSmall
color: "white"
opacity: 0.5
}
}
StyledText {
width: parent.width
text: modelData.summary || ""
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: "white"
elide: Text.ElideRight
maximumLineCount: 1
visible: text.length > 0
}
StyledText {
width: parent.width
text: {
const body = modelData.body || "";
return body.replace(/<[^>]*>/g, '').replace(/\n/g, ' ');
}
font.pixelSize: Theme.fontSizeSmall
color: "white"
opacity: 0.8
elide: Text.ElideRight
maximumLineCount: 2
wrapMode: Text.WordWrap
visible: text.length > 0
}
}
}
}
StyledText {
visible: lockNotificationPanel.appNameGroups.length > 5
text: I18n.tr("+ %1 more").arg(lockNotificationPanel.appNameGroups.length - 5)
font.pixelSize: Theme.fontSizeSmall
color: "white"
opacity: 0.7
}
}
}
}
}
}
ColumnLayout {
id: passwordLayout
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: dateText.visible ? dateText.bottom : clockContainer.bottom
anchors.top: lockNotificationPanel.visible ? lockNotificationPanel.bottom : (dateText.visible ? dateText.bottom : clockContainer.bottom)
anchors.topMargin: Theme.spacingL
spacing: Theme.spacingM
width: 380

View File

@@ -622,9 +622,9 @@ Rectangle {
anchors.rightMargin: 16
anchors.bottom: parent.bottom
anchors.bottomMargin: 8
width: clearText.width + 16
height: clearText.height + 8
radius: 6
width: Math.max(clearText.implicitWidth + 12, 50)
height: 24
radius: 4
color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent"
StyledText {

View File

@@ -75,6 +75,21 @@ Item {
checked: SettingsData.lockScreenShowPasswordField
onToggled: checked => SettingsData.set("lockScreenShowPasswordField", checked)
}
SettingsDropdownRow {
settingKey: "lockScreenNotificationMode"
tags: ["lock", "screen", "notification", "notifications", "privacy"]
text: I18n.tr("Notification Display", "lock screen notification privacy setting")
description: I18n.tr("Control what notification information is shown on the lock screen", "lock screen notification privacy setting")
options: [I18n.tr("Disabled", "lock screen notification mode option"), I18n.tr("Count Only", "lock screen notification mode option"), I18n.tr("App Names", "lock screen notification mode option"), I18n.tr("Full Content", "lock screen notification mode option")]
currentValue: options[SettingsData.lockScreenNotificationMode] || options[0]
onValueChanged: value => {
const idx = options.indexOf(value);
if (idx >= 0) {
SettingsData.set("lockScreenNotificationMode", idx);
}
}
}
}
SettingsCard {

View File

@@ -162,6 +162,28 @@ Item {
}
}
SettingsCard {
width: parent.width
iconName: "lock"
title: I18n.tr("Lock Screen", "lock screen notifications settings card")
settingKey: "lockScreenNotifications"
SettingsDropdownRow {
settingKey: "lockScreenNotificationMode"
tags: ["lock", "screen", "notification", "notifications", "privacy"]
text: I18n.tr("Notification Display", "lock screen notification privacy setting")
description: I18n.tr("Control what notification information is shown on the lock screen", "lock screen notification privacy setting")
options: [I18n.tr("Disabled", "lock screen notification mode option"), I18n.tr("Count Only", "lock screen notification mode option"), I18n.tr("App Names", "lock screen notification mode option"), I18n.tr("Full Content", "lock screen notification mode option")]
currentValue: options[SettingsData.lockScreenNotificationMode] || options[0]
onValueChanged: value => {
const idx = options.indexOf(value);
if (idx >= 0) {
SettingsData.set("lockScreenNotificationMode", idx);
}
}
}
}
SettingsCard {
width: parent.width
iconName: "timer"