import QtQuick import Quickshell import Quickshell.Services.Notifications import "." as M import "../services" as S import "../applets" as C M.PinnableSection { id: root spacing: S.Theme.moduleSpacing _panelHovered: hoverPanel.panelHovered readonly property bool hasUrgent: S.NotifService.list.some(n => n.urgency === NotificationUrgency.Critical && n.state !== "dismissed") M.BarIcon { icon: { if (S.NotifService.dnd) return S.NotifService.count > 0 ? "\uDB80\uDCA0" : "\uDB82\uDE93"; return S.NotifService.count > 0 ? "\uDB84\uDD6B" : "\uDB80\uDC9C"; } color: S.NotifService.dnd ? S.Theme.base04 : root.accentColor anchors.verticalCenter: parent.verticalCenter TapHandler { onTapped: root._pinned = !root._pinned } } M.BarLabel { id: countLabel label: S.NotifService.count > 0 ? String(S.NotifService.count) + (root.hasUrgent ? "!" : "") : "" color: root.hasUrgent ? S.Theme.base08 : root.accentColor anchors.verticalCenter: parent.verticalCenter TapHandler { onTapped: root._pinned = !root._pinned } transform: Scale { id: countScale origin.x: countLabel.width / 2 origin.y: countLabel.height / 2 xScale: 1 yScale: 1 } SequentialAnimation { id: popAnim NumberAnimation { target: countScale properties: "xScale,yScale" to: 1.4 duration: 100 easing.type: Easing.OutQuad } NumberAnimation { target: countScale properties: "xScale,yScale" to: 1.0 duration: 200 easing.type: Easing.OutElastic } } } Connections { target: S.NotifService function onCountChanged() { if (S.NotifService.count > 0 && !S.Theme.reducedMotion) popAnim.start(); } } // Right-click DND quick toggle TapHandler { acceptedButtons: Qt.RightButton onTapped: S.NotifService.toggleDnd() } M.HoverPanel { id: hoverPanel showPanel: root._showPanel screen: QsWindow.window?.screen ?? null anchorItem: root accentColor: root.accentColor panelNamespace: "nova-notifications" panelTitle: "Notifications" contentWidth: 350 titleActionsComponent: Component { Row { spacing: 8 // DND toggle Text { text: S.NotifService.dnd ? "\uDB82\uDE93" : "\uDB80\uDC9C" color: S.NotifService.dnd ? S.Theme.base09 : S.Theme.base04 font.pixelSize: S.Theme.fontSize font.family: S.Theme.iconFontFamily anchors.verticalCenter: parent.verticalCenter HoverHandler { cursorShape: Qt.PointingHandCursor } TapHandler { onTapped: S.NotifService.toggleDnd() } } // Clear all Text { text: "\uF1F8" color: _clearHover.hovered ? S.Theme.base08 : S.Theme.base04 font.pixelSize: S.Theme.fontSize font.family: S.Theme.iconFontFamily anchors.verticalCenter: parent.verticalCenter visible: S.NotifService.count > 0 HoverHandler { id: _clearHover cursorShape: Qt.PointingHandCursor } TapHandler { onTapped: _notifApplet.cascadeDismiss() } } } } C.NotifApplet { id: _notifApplet width: hoverPanel.contentWidth contentWidth: hoverPanel.contentWidth accentColor: root.accentColor } } }