support for action buttons in notifications

This commit is contained in:
Marco Martin 2020-11-18 18:18:24 +01:00 committed by Bhushan Shah
parent 94609d2590
commit 894d4a3b72

View file

@ -21,6 +21,7 @@ import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.12 import QtGraphicalEffects 1.12
import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.notificationmanager 1.1 as Notifications import org.kde.notificationmanager 1.1 as Notifications
@ -32,6 +33,7 @@ import "../components"
// meant to be temporary, until the notifications components in plasma-workspace are available to used // meant to be temporary, until the notifications components in plasma-workspace are available to used
// https://invent.kde.org/plasma/plasma-workspace/-/blob/master/applets/notifications/package/contents/ui/NotificationItem.qml // https://invent.kde.org/plasma/plasma-workspace/-/blob/master/applets/notifications/package/contents/ui/NotificationItem.qml
Item { Item {
id: notificationItem
property var notification property var notification
anchors.left: parent.left anchors.left: parent.left
@ -39,7 +41,7 @@ Item {
height: notifLayout.height + units.gridUnit height: notifLayout.height + units.gridUnit
opacity: 1 - Math.min(1, 1.5 * Math.abs(rect.x) / width) // opacity during dismiss swipe opacity: 1 - Math.min(1, 1.5 * Math.abs(rect.x) / width) // opacity during dismiss swipe
// notification // notification
Rectangle { Rectangle {
id: rect id: rect
@ -52,10 +54,8 @@ Item {
border.color: "#bdbdbd" border.color: "#bdbdbd"
border.width: 1 border.width: 1
ColumnLayout {
RowLayout {
id: notifLayout id: notifLayout
height: textLayout.height
anchors { anchors {
left: parent.left left: parent.left
leftMargin: units.gridUnit * 0.5 leftMargin: units.gridUnit * 0.5
@ -63,82 +63,124 @@ Item {
rightMargin: units.gridUnit * 0.5 rightMargin: units.gridUnit * 0.5
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
} }
spacing: units.smallSpacing / 2 RowLayout {
// notif body
ColumnLayout {
id: textLayout
Layout.fillWidth: true Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft spacing: units.smallSpacing / 2
spacing: units.gridUnit / 2 // notif body
ColumnLayout {
Label { id: textLayout
text: notification.summary
color: "#212121"
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: implicitHeight Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
maximumLineCount: 3 spacing: units.gridUnit / 2
wrapMode: Text.WordWrap
elide: Text.ElideRight Label {
font.pointSize: 11 text: notification.summary
color: "#212121"
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
maximumLineCount: 3
wrapMode: Text.WordWrap
elide: Text.ElideRight
font.pointSize: 11
}
Label {
text: notification.body
color: "#616161"
Layout.fillWidth: true
wrapMode: Text.WordWrap
elide: Text.ElideRight
font.pointSize: 10
}
} }
Label {
text: notification.body // notification icon
color: "#616161" Item {
Layout.fillWidth: true id: iconContainer
wrapMode: Text.WordWrap
elide: Text.ElideRight Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
font.pointSize: 10 Layout.preferredWidth: units.iconSizes.large
Layout.preferredHeight: units.iconSizes.large
Layout.topMargin: units.smallSpacing
Layout.bottomMargin: units.smallSpacing
visible: iconItem.active || imageItem.active
PlasmaCore.IconItem {
id: iconItem
// don't show two identical icons
readonly property bool active: valid && source != notification.applicationIconSource
anchors.fill: parent
usesPlasmaTheme: false
smooth: true
source: {
let icon = notification.icon;
if (typeof icon !== "string") return "";
if (icon === "dialog-information") return "";
return icon;
}
visible: active
}
KQCAddons.QImageItem {
id: imageItem
readonly property bool active: !null && nativeWidth > 0
anchors.fill: parent
smooth: true
fillMode: KQCAddons.QImageItem.PreserveAspectFit
visible: active
image: typeof notification.icon === "object" ? notification.icon : undefined
}
} }
} }
// notification icon
Item {
id: iconContainer
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight Flow {
Layout.preferredWidth: units.iconSizes.large id: actionsflow
Layout.preferredHeight: units.iconSizes.large Layout.fillWidth: true
Layout.topMargin: units.smallSpacing spacing: units.smallSpacing
Layout.bottomMargin: units.smallSpacing layoutDirection: Qt.RightToLeft
Repeater {
id: actionRepeater
visible: iconItem.active || imageItem.active model: {
var buttons = [];
var actionNames = (notificationItem.notification.actionNames || []);
var actionLabels = (notificationItem.notification.actionLabels || []);
// HACK We want the actions to be right-aligned but Flow also reverses
for (var i = actionNames.length - 1; i >= 0; --i) {
buttons.push({
actionName: actionNames[i],
label: actionLabels[i]
});
}
PlasmaCore.IconItem { return buttons;
id: iconItem
// don't show two identical icons
readonly property bool active: valid && source != notification.applicationIconSource
anchors.fill: parent
usesPlasmaTheme: false
smooth: true
source: {
let icon = notification.icon;
if (typeof icon !== "string") return "";
if (icon === "dialog-information") return "";
return icon;
} }
visible: active
}
KQCAddons.QImageItem { PlasmaComponents3.ToolButton {
id: imageItem flat: false
readonly property bool active: !null && nativeWidth > 0 // why does it spit "cannot assign undefined to string" when a notification becomes expired?
anchors.fill: parent text: modelData.label || ""
smooth: true
fillMode: KQCAddons.QImageItem.PreserveAspectFit onClicked: {
visible: active notifModel.invokeAction(notificationItem.notification.notificationId, modelData.actionName);
image: typeof notification.icon === "object" ? notification.icon : undefined }
}
} }
} }
} }
// swipe gesture for dismissing notification (left/right) // swipe gesture for dismissing notification (left/right)
MouseArea { MouseArea {
id: dismissSwipe id: dismissSwipe
anchors.fill: parent anchors.fill: parent
drag.axis: Drag.XAxis drag.axis: Drag.XAxis
drag.target: rect drag.target: rect
onPressed: {
let pos = mapToItem(actionsflow, mouse.x, mouse.y);
if (actionsflow.childAt(pos.x, pos.y)) {
mouse.accepted = false;
}
}
onReleased: { onReleased: {
if (Math.abs(rect.x) > width / 2) { // dismiss notification when finished swipe if (Math.abs(rect.x) > width / 2) { // dismiss notification when finished swipe
notifModel.close(notification.id); notifModel.close(notification.id);