mirror of
https://github.com/tuxdotrs/tshell.git
synced 2026-09-19 18:49:02 +05:30
feat(notifications): implement notification service
This commit is contained in:
117
modules/osd/NotificationCard.qml
Normal file
117
modules/osd/NotificationCard.qml
Normal file
@@ -0,0 +1,117 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Services.Notifications
|
||||
import qs.config
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property Notification notif
|
||||
readonly property bool critical: notif?.urgency === NotificationUrgency.Critical
|
||||
readonly property int timeoutDuration: {
|
||||
const seconds = Math.round((notif?.expireTimeout ?? 0) / 1000);
|
||||
return seconds > 0 ? seconds : 5;
|
||||
}
|
||||
readonly property string iconName: {
|
||||
if (!notif)
|
||||
return "";
|
||||
|
||||
const hints = notif.hints ?? {};
|
||||
const hinted = String(hints["image-path"] ?? hints["image_path"] ?? hints["icon_path"] ?? "");
|
||||
return notif.appIcon || notif.desktopEntry || hinted;
|
||||
}
|
||||
readonly property url themedIconUrl: iconName !== "" ? Quickshell.iconPath(iconName, false) : ""
|
||||
readonly property url iconUrl: `${Quickshell.shellPath("assets")}/icons/notification.svg`
|
||||
|
||||
implicitWidth: 360
|
||||
implicitHeight: content.implicitHeight + Appearance.padding * 2
|
||||
radius: Appearance.radius
|
||||
color: Appearance.colors.background
|
||||
border.width: critical ? 1 : 0
|
||||
border.color: Appearance.colors.accent
|
||||
|
||||
Timer {
|
||||
id: countdown
|
||||
|
||||
interval: root.timeoutDuration * 1000
|
||||
repeat: false
|
||||
running: !root.critical && !hovered.hovered && visible
|
||||
onTriggered: root.notif.expire()
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hovered
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: content
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: Appearance.padding
|
||||
spacing: Appearance.spacing
|
||||
|
||||
Item {
|
||||
width: 40
|
||||
height: 40
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: root.iconUrl
|
||||
fillMode: Image.PreserveAspectFit
|
||||
smooth: true
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: root.themedIconUrl
|
||||
visible: root.themedIconUrl !== "" && status === Image.Ready
|
||||
fillMode: Image.PreserveAspectFit
|
||||
smooth: true
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 2
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
Text {
|
||||
text: root.notif?.appName ?? ""
|
||||
color: Appearance.colors.accent
|
||||
font.family: Appearance.font.family
|
||||
font.pointSize: Appearance.font.pointSize - 2
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Text {
|
||||
text: root.notif?.summary ?? ""
|
||||
color: Appearance.colors.foreground
|
||||
font.family: Appearance.font.family
|
||||
font.pointSize: Appearance.font.pointSize
|
||||
font.weight: Font.DemiBold
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Text {
|
||||
text: root.notif?.body ?? ""
|
||||
visible: text !== ""
|
||||
color: Appearance.colors.foreground
|
||||
opacity: 0.8
|
||||
font.family: Appearance.font.family
|
||||
font.pointSize: Appearance.font.pointSize - 1
|
||||
wrapMode: Text.Wrap
|
||||
maximumLineCount: 3
|
||||
elide: Text.ElideRight
|
||||
textFormat: Text.PlainText
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user