diff --git a/notification-test/Notif.qml b/notification-test/Notif.qml deleted file mode 100644 index 9e749b2..0000000 --- a/notification-test/Notif.qml +++ /dev/null @@ -1,155 +0,0 @@ -import Quickshell -import Quickshell.Widgets -import Quickshell.Wayland -import QtQuick.Layouts -import QtQuick -import Quickshell.Services.Notifications - -PanelWindow { - id: root - color: "transparent" - anchors { - top: true - right: true - left: true - bottom: true - } - mask: Region { item: backgroundRect } - exclusionMode: ExclusionMode.Ignore - WlrLayershell.layer: WlrLayer.Overlay - required property Notification notif - required property int centerX - required property list notifIndex - property int index: notifIndex.indexOf(notif.id) - signal notifDestroy() - - Component.onCompleted: { - openAnim.start(); - } - - Timer { - id: timeout - interval: 5000 - onTriggered: { - closeAnim.start(); - } - } - - NumberAnimation { - id: openAnim - target: backgroundRect - property: "x" - from: root.centerX - to: root.centerX - backgroundRect.implicitWidth - 20 - duration: 200 - easing.type: Easing.InOutQuad - onStopped: { timeout.start(); } - } - - NumberAnimation { - id: closeAnim - target: backgroundRect - property: "x" - from: root.centerX - backgroundRect.implicitWidth - 20 - to: root.centerX - duration: 200 - easing.type: Easing.InOutQuad - onStopped: { - root.destroy(); - root.notifDestroy(); - } - } - - Rectangle { - id: backgroundRect - implicitWidth: 400 - implicitHeight: 80 - x: root.centerX - implicitWidth - 20 - y: 34 + 20 + ( root.index * ( implicitHeight + 10 )) - color: "#801a1a1a" - border.color: "#555555" - radius: 8 - - Behavior on y { - NumberAnimation { - duration: 200 - easing.type: Easing.InOutQuad - } - } - - RowLayout { - anchors.fill: parent - anchors.margins: 8 - IconImage { - source: root.notif.image - Layout.preferredWidth: 64 - Layout.preferredHeight: 64 - Layout.alignment: Qt.AlignHCenter | Qt.AlignLeft - visible: root.notif.image !== "" - } - - ColumnLayout { - Layout.fillWidth: true - Layout.leftMargin: root.notif.image !== "" ? 0 : 16 - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - - Text { - text: root.notif.appName - color: "white" - font.bold: true - font.pointSize: 12 - elide: Text.ElideRight - wrapMode: Text.NoWrap - Layout.fillWidth: true - } - - Text { - text: root.notif.summary - color: "white" - font.pointSize: 10 - elide: Text.ElideRight - wrapMode: Text.WordWrap - Layout.fillWidth: true - } - - Text { - text: root.notif.body - color: "#dddddd" - font.pointSize: 8 - elide: Text.ElideRight - wrapMode: Text.WordWrap - Layout.fillWidth: true - Layout.fillHeight: true - } - } - } - - Rectangle { - anchors.right: parent.right - anchors.top: parent.top - anchors.rightMargin: 6 - anchors.topMargin: 6 - width: 18 - height: 18 - color: closeArea.containsMouse ? "#FF6077" : "transparent" - radius: 9 - - Text { - anchors.centerIn: parent - text: "✕" - color: closeArea.containsMouse ? "white" : "#888888" - font.pointSize: 12 - } - - MouseArea { - id: closeArea - anchors.fill: parent - hoverEnabled: true - onClicked: { - root.notif.dismiss(); - root.visible = false; - } - } - } - } -} diff --git a/notification-test/NotificationCenter.qml b/notification-test/NotificationCenter.qml deleted file mode 100644 index ab62ce2..0000000 --- a/notification-test/NotificationCenter.qml +++ /dev/null @@ -1,449 +0,0 @@ -import Quickshell -import Quickshell.Hyprland -import Quickshell.Widgets -import Quickshell.Io -import QtQuick.Layouts -import QtQuick.Controls.FluentWinUI3 -import QtQuick.Effects -import QtQuick -import Quickshell.Services.Notifications - -PanelWindow { - id: root - color: "transparent" - anchors { - top: true - right: true - left: true - bottom: true - } - required property list notifications - property bool centerShown: false - property alias posX: backgroundRect.x - property alias doNotDisturb: dndSwitch.checked - visible: false - - IpcHandler { - id: ipcHandler - target: "root" - - function showCenter(): void { root.centerShown = !root.centerShown; } - } - - onVisibleChanged: { - if ( root.visible ) { - showAnimation.start(); - } - } - - onCenterShownChanged: { - if ( !root.centerShown ) { - closeAnimation.start(); - closeTimer.start(); - } else { - root.visible = true; - } - } - - Timer { - id: closeTimer - interval: 300 - onTriggered: { - root.visible = false; - } - } - - NumberAnimation { - id: showAnimation - target: backgroundRect - property: "x" - from: Screen.width - to: Screen.width - backgroundRect.implicitWidth - 10 - duration: 300 - easing.type: Easing.OutCubic - } - - NumberAnimation { - id: closeAnimation - target: backgroundRect - property: "x" - from: Screen.width - backgroundRect.implicitWidth - 10 - to: Screen.width - duration: 300 - easing.type: Easing.OutCubic - } - - QtObject { - id: groupedData - property var groups: ({}) - - function updateGroups() { - var newGroups = {}; - for ( var i = 0; i < root.notifications.length; i++ ) { - var notif = root.notifications[ i ]; - var appName = notif.appName || "Unknown"; - if ( !newGroups[ appName ]) { - newGroups[ appName ] = []; - } - newGroups[ appName ].push( notif ); - } - // Sort notifications within each group (latest first) - for ( var app in newGroups ) { - newGroups[ app ].sort(( a, b ) => b.receivedTime - a.receivedTime ); - } - groups = newGroups; - groupsChanged(); - } - - Component.onCompleted: updateGroups() - } - - Connections { - target: root - function onNotificationsChanged() { - groupedData.updateGroups(); - } - } - - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton - onClicked: { - if ( root.centerShown ) { - root.centerShown = false; - } - } - } - - Rectangle { - id: backgroundRect - y: 10 - x: Screen.width - implicitWidth: 400 - implicitHeight: root.height - 20 - color: "#801a1a1a" - radius: 8 - border.color: "#555555" - border.width: 1 - ColumnLayout { - anchors.fill: parent - anchors.margins: 10 - spacing: 10 - - RowLayout { - Layout.fillWidth: true - Switch { - id: dndSwitch - Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter - Layout.fillWidth: true - text: "Do Not Disturb" - } - RowLayout { - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - Text { - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - text: "Clear all" - color: "white" - } - Rectangle { - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - Layout.preferredWidth: 30 - Layout.preferredHeight: 30 - color: clearArea.containsMouse ? "#15FFFFFF" : "transparent" - radius: 4 - Text { - anchors.centerIn: parent - text: "\ue0b8" - font.family: "Material Symbols Rounded" - font.pointSize: 18 - color: "white" - } - MouseArea { - id: clearArea - anchors.fill: parent - hoverEnabled: true - onClicked: { - for ( var app in groupedData.groups ) { - groupedData.groups[ app ].forEach( function( n ) { n.dismiss(); }); - } - } - } - } - } - } - - Rectangle { - color: "#333333" - Layout.preferredHeight: 1 - Layout.fillWidth: true - } - - Flickable { - Layout.fillWidth: true - Layout.fillHeight: true - contentHeight: notificationColumn.implicitHeight - clip: true - - Column { - id: notificationColumn - width: parent.width - spacing: 10 - - add: Transition { - NumberAnimation { - properties: "x"; - duration: 300; - easing.type: Easing.OutCubic - } - } - - move: Transition { - NumberAnimation { - properties: "y,x"; - duration: 200; - easing.type: Easing.OutCubic - } - } - - Repeater { - model: Object.keys( groupedData.groups ) - Column { - id: groupColumn - required property string modelData - property var notifications: groupedData.groups[ modelData ] - width: parent.width - spacing: 10 - - property bool shouldShow: false - property bool isExpanded: false - - move: Transition { - NumberAnimation { - properties: "y,x"; - duration: 100; - easing.type: Easing.OutCubic - } - } - - RowLayout { - width: parent.width - height: 30 - - Text { - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.leftMargin: 5 - text: groupColumn.modelData - color: "white" - font.pointSize: 14 - font.bold: true - } - - Rectangle { - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - Layout.fillHeight: true - Layout.preferredWidth: 30 - color: collapseArea.containsMouse ? "#15FFFFFF" : "transparent" - radius: 4 - visible: groupColumn.isExpanded - Text { - anchors.centerIn: parent - text: "\ue944" - font.family: "Material Symbols Rounded" - font.pointSize: 18 - color: "white" - } - MouseArea { - id: collapseArea - anchors.fill: parent - hoverEnabled: true - onClicked: { - groupColumn.isExpanded = false; - } - } - } - } - - Repeater { - model: groupColumn.notifications - Rectangle { - id: groupHeader - required property var modelData - required property var index - width: parent.width - height: groupColumn.isExpanded ? ( modelData.actions.length > 1 ? 130 : 80 ) : 80 - color: "#801a1a1a" - border.color: "#555555" - border.width: 1 - radius: 8 - visible: groupColumn.notifications[0].id === modelData.id || groupColumn.isExpanded - - // NumberAnimation { - // id: expandAnim - // target: groupHeader - // property: "y" - // duration: 300 - // easing.type: Easing.OutCubic - // from: (( groupHeader.height / 2 ) * index ) - // to: (( groupHeader.height + 60 ) * index ) - // onStarted: { - // groupColumn.shouldShow = true; - // } - // } - // - // NumberAnimation { - // id: collapseAnim - // target: groupHeader - // property: "y" - // duration: 300 - // easing.type: Easing.OutCubic - // from: (( groupHeader.height + 60 ) * index ) - // to: (( groupHeader.height / 2 ) * index ) - // onStopped: { - // groupColumn.isExpanded = false; - // } - // } - - Connections { - target: groupColumn - function onShouldShowChanged() { - if ( !shouldShow ) { - // collapseAnim.start(); - } - } - } - - onVisibleChanged: { - if ( visible ) { - // expandAnim.start(); - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - if ( groupColumn.isExpanded ) { - if ( groupHeader.modelData.actions.length === 1 ) { - groupHeader.modelData.actions[0].invoke(); - } - } else { - groupColumn.isExpanded = true; - } - } - } - - Column { - anchors.fill: parent - anchors.margins: 10 - RowLayout { - height: 80 - width: parent.width - spacing: 10 - - IconImage { - source: groupHeader.modelData.image - Layout.preferredWidth: 48 - Layout.preferredHeight: 48 - Layout.alignment: Qt.AlignTop | Qt.AlignLeft - Layout.topMargin: 5 - } - - ColumnLayout { - Layout.fillWidth: true - Layout.fillHeight: true - spacing: 4 - - Text { - text: groupHeader.modelData.summary - color: "white" - font.bold: true - font.pointSize: 12 - elide: Text.ElideRight - Layout.fillWidth: true - } - - Text { - text: groupHeader.modelData.body - font.pointSize: 10 - color: "#dddddd" - elide: Text.ElideRight - Layout.fillWidth: true - Layout.fillHeight: true - } - } - - Text { - text: groupColumn.notifications.length > 1 ? ( groupColumn.isExpanded ? "" : "(" + groupColumn.notifications.length + ")" ) : "" - font.pointSize: 10 - color: "#666666" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - } - - } - - RowLayout { - spacing: 2 - visible: groupColumn.isExpanded && groupHeader.modelData.actions.length > 1 - height: 15 - width: parent.width - - Repeater { - model: groupHeader.modelData.actions - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: 30 - required property var modelData - color: buttonArea.containsMouse ? "#15FFFFFF" : "#09FFFFFF" - radius: 4 - Text { - anchors.centerIn: parent - text: modelData.text - color: "white" - font.pointSize: 12 - } - MouseArea { - id: buttonArea - anchors.fill: parent - hoverEnabled: true - onClicked: { - modelData.invoke(); - } - } - } - } - } - } - Rectangle { - anchors.right: parent.right - anchors.top: parent.top - anchors.rightMargin: 6 - anchors.topMargin: 6 - width: 18 - height: 18 - color: closeArea.containsMouse ? "#FF6077" : "transparent" - radius: 9 - - Text { - anchors.centerIn: parent - text: "✕" - color: closeArea.containsMouse ? "white" : "#888888" - font.pointSize: 12 - } - - MouseArea { - id: closeArea - anchors.fill: parent - hoverEnabled: true - onClicked: { - groupColumn.isExpanded ? groupColumn.notifications[0].dismiss() : groupColumn.notifications.forEach( function( n ) { n.dismiss(); }); - } - } - } - } - } - } - } - } - } - } - } -} diff --git a/notification-test/shell.qml b/notification-test/shell.qml deleted file mode 100644 index 372d8bc..0000000 --- a/notification-test/shell.qml +++ /dev/null @@ -1,39 +0,0 @@ -pragma ComponentBehavior: Bound -import Quickshell -import Quickshell.Services.Notifications -import QtQuick - -Scope { - id: root - property list notifIds: [] - NotificationServer { - id: notificationServer - imageSupported: true - actionsSupported: true - persistenceSupported: true - bodyImagesSupported: true - bodySupported: true - onNotification: { - notification.tracked = true; - notification.receivedTime = Date.now(); - root.notifIds.push(notification.id); - notificationComponent.createObject(root, { notif: notification, visible: !notificationCenter.doNotDisturb }); - } - } - - Component { - id: notificationComponent - Notif { - centerX: notificationCenter.posX - notifIndex: root.notifIds - onNotifDestroy: { - root.notifIds.shift(); - } - } - } - - NotificationCenter { - id: notificationCenter - notifications: notificationServer.trackedNotifications.values - } -}