import QtQuick import Quickshell import "../services" as S Row { id: root spacing: 6 visible: (S.Modules.lock.notifications ?? true) && _notifGroups.length > 0 readonly property var _notifGroups: { const notifs = S.NotifService.list.filter(n => n.state !== "dismissed"); const groups = {}; for (const n of notifs) { const key = n.appIcon || n.appName || "unknown"; if (!groups[key]) groups[key] = { icon: n.appIcon, name: n.appName, count: 0 }; groups[key].count++; } return Object.values(groups); } Repeater { model: root._notifGroups delegate: Rectangle { id: _pill required property var modelData width: _pillRow.implicitWidth + 12 height: 24 radius: 12 color: Qt.rgba(S.Theme.base01.r, S.Theme.base01.g, S.Theme.base01.b, 0.7) border.color: Qt.rgba(S.Theme.base03.r, S.Theme.base03.g, S.Theme.base03.b, 0.3) border.width: 1 HoverHandler { id: _pillHover } // App name tooltip Text { anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.top anchors.bottomMargin: 4 text: _pill.modelData.name || "" color: S.Theme.base04 font.pixelSize: S.Theme.fontSize - 2 font.family: S.Theme.fontFamily visible: _pillHover.hovered && text !== "" } Row { id: _pillRow anchors.centerIn: parent spacing: 4 Image { anchors.verticalCenter: parent.verticalCenter width: 14 height: 14 source: { const icon = _pill.modelData.icon; if (!icon) return ""; if (icon.startsWith("/")) return icon; return Quickshell.iconPath(icon) ?? ""; } sourceSize: Qt.size(14, 14) visible: source !== "" } Text { anchors.verticalCenter: parent.verticalCenter text: _pill.modelData.count > 1 ? _pill.modelData.count.toString() : "" color: S.Theme.base04 font.pixelSize: S.Theme.fontSize - 2 font.family: S.Theme.fontFamily visible: _pill.modelData.count > 1 } } } } }