right sidebar: cleaner notification implementation

This commit is contained in:
end-4 2025-05-22 13:35:38 +02:00
parent 1261d5033e
commit cfc8cc30b6
2 changed files with 74 additions and 84 deletions

View file

@ -21,7 +21,6 @@ Item {
property bool expanded: false
property bool enableAnimation: true
property int notificationListSpacing: 5
property bool ready: false
property int defaultTimeoutValue: 5000
property var notificationXAnimation: Appearance.animation.elementMoveEnter
@ -29,18 +28,9 @@ Item {
Layout.fillWidth: true
clip: !popup
implicitHeight: ready ? notificationColumnLayout.implicitHeight + notificationListSpacing : 0
Behavior on implicitHeight {
enabled: enableAnimation
NumberAnimation {
duration: Appearance.animation.elementMoveFast.duration
easing.type: Appearance.animation.elementMoveFast.type
easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve
}
}
implicitHeight: notificationColumnLayout.implicitHeight + notificationListSpacing
Component.onCompleted: {
root.ready = true
if (popup) timeoutTimer.start()
}
@ -89,7 +79,6 @@ Item {
onTriggered: {
notificationRowWrapper.anchors.top = undefined
notificationRowWrapper.anchors.bottom = root.bottom
implicitHeight = 0
destroyTimer2.start()
}
}
@ -99,7 +88,7 @@ Item {
interval: Appearance.animation.elementMoveFast.duration
repeat: false
onTriggered: {
root.destroy()
Notifications.discardNotification(notificationObject.id);
}
}
@ -109,7 +98,7 @@ Item {
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
onClicked: (mouse) => {
if (mouse.button == Qt.MiddleButton)
Notifications.discardNotification(notificationObject.id);
root.destroyWithAnimation()
else if (mouse.button == Qt.RightButton)
root.toggleExpanded()
}
@ -141,7 +130,7 @@ Item {
if (mouse.button === Qt.LeftButton) {
if (notificationRowWrapper.x > dragConfirmThreshold) {
root.notificationXAnimation = Appearance.animation.elementMoveEnter
Notifications.discardNotification(notificationObject.id);
root.destroyWithAnimation()
} else {
// Animate back if not far enough
root.notificationXAnimation = Appearance.animation.elementMoveFast
@ -583,7 +572,7 @@ Item {
(contentItem.implicitWidth + leftPadding + rightPadding)
onClicked: {
Notifications.discardNotification(notificationObject.id);
root.destroyWithAnimation()
}
contentItem: MaterialSymbol {

View file

@ -5,67 +5,14 @@ import Qt5Compat.GraphicalEffects
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Widgets
Item {
id: root
property Component notifComponent: NotificationWidget {}
property list<NotificationWidget> notificationWidgetList: []
// Signal handlers to add/remove notifications
Connections {
target: Notifications
function onInitDone() {
// notificationRepeater.model = Notifications.list.slice().reverse()
Notifications.list.slice().reverse().forEach((notification) => {
const notif = root.notifComponent.createObject(columnLayout, { notificationObject: notification });
notificationWidgetList.push(notif)
})
}
function onNotify(notification) {
// notificationRepeater.model = [notification, ...notificationRepeater.model]
const notif = root.notifComponent.createObject(columnLayout, { notificationObject: notification });
notificationWidgetList.unshift(notif)
// Remove stuff from t he column, add back
for (let i = 0; i < notificationWidgetList.length; i++) {
if (notificationWidgetList[i].parent === columnLayout) {
notificationWidgetList[i].parent = null;
}
}
// Add notification widgets to the column
for (let i = 0; i < notificationWidgetList.length; i++) {
if (notificationWidgetList[i].parent === null) {
notificationWidgetList[i].parent = columnLayout;
}
}
}
function onDiscard(id) {
for (let i = notificationWidgetList.length - 1; i >= 0; i--) {
const widget = notificationWidgetList[i];
if (widget && widget.notificationObject && widget.notificationObject.id === id) {
widget.destroyWithAnimation();
notificationWidgetList.splice(i, 1);
}
}
}
function onDiscardAll() {
for (let i = notificationWidgetList.length - 1; i >= 0; i--) {
const widget = notificationWidgetList[i];
if (widget && widget.notificationObject) {
widget.destroyWithAnimation();
}
}
notificationWidgetList = [];
}
}
Flickable { // Scrollable window
id: flickable
ListView { // Scrollable window
id: listview
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
@ -76,28 +23,82 @@ Item {
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle {
width: flickable.width
height: flickable.height
width: listview.width
height: listview.height
radius: Appearance.rounding.normal
}
}
ColumnLayout { // Scrollable window content
id: columnLayout
anchors.left: parent.left
anchors.right: parent.right
spacing: 0 // The widgets themselves have margins for spacing
add: Transition {
animations: [
Appearance.animation.elementMove.numberAnimation.createObject(this, {
properties: "opacity,scale",
from: 0,
to: 1,
}),
]
}
// Notifications are added by the above signal handlers
addDisplaced: Transition {
animations: [
Appearance.animation.elementMove.numberAnimation.createObject(this, {
property: "y",
}),
Appearance.animation.elementMove.numberAnimation.createObject(this, {
properties: "opacity,scale",
to: 1,
}),
]
}
displaced: Transition {
animations: [
Appearance.animation.elementMove.numberAnimation.createObject(this, {
property: "y",
}),
]
}
move: Transition {
animations: [
Appearance.animation.elementMove.numberAnimation.createObject(this, {
property: "y",
}),
]
}
remove: Transition {
animations: [
Appearance.animation.elementMove.numberAnimation.createObject(this, {
property: "x",
to: listview.width,
}),
Appearance.animation.elementMove.numberAnimation.createObject(this, {
property: "opacity",
to: 0,
})
]
}
model: ScriptModel {
values: Notifications.list.slice().reverse()
}
delegate: NotificationWidget {
required property var modelData
id: notificationWidget
// anchors.horizontalCenter: parent.horizontalCenter
anchors.left: parent?.left
anchors.right: parent?.right
Layout.fillWidth: true
notificationObject: modelData
}
}
// Placeholder when list is empty
Item {
anchors.fill: flickable
anchors.fill: listview
visible: opacity > 0
opacity: (root.notificationWidgetList.length === 0) ? 1 : 0
opacity: (Notifications.list.length === 0) ? 1 : 0
Behavior on opacity {
NumberAnimation {
@ -137,9 +138,9 @@ Item {
Layout.alignment: Qt.AlignVCenter
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: `${notificationWidgetList.length} notification${notificationWidgetList.length > 1 ? "s" : ""}`
text: `${Notifications.list.length} notifications`
opacity: notificationWidgetList.length > 0 ? 1 : 0
opacity: Notifications.list.length > 0 ? 1 : 0
visible: opacity > 0
Behavior on opacity {
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)