summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorSoramane <61896496+soramanew@users.noreply.github.com>2025-07-16 17:41:51 +1000
committerSoramane <61896496+soramanew@users.noreply.github.com>2025-07-16 17:41:51 +1000
commit88c628a777b94b1774ff21c886fe0d2a2cb6bcf5 (patch)
tree3158e90d4511430f67942fd7ec96ca0d4e328f0b /modules
parentnotifs: use app2unit for links (diff)
downloadcaelestia-shell-88c628a777b94b1774ff21c886fe0d2a2cb6bcf5.tar.gz
caelestia-shell-88c628a777b94b1774ff21c886fe0d2a2cb6bcf5.tar.bz2
caelestia-shell-88c628a777b94b1774ff21c886fe0d2a2cb6bcf5.zip
notifs: fix interactions
Diffstat (limited to 'modules')
-rw-r--r--modules/notifications/Notification.qml580
1 files changed, 290 insertions, 290 deletions
diff --git a/modules/notifications/Notification.qml b/modules/notifications/Notification.qml
index 85d81d9..87e23a1 100644
--- a/modules/notifications/Notification.qml
+++ b/modules/notifications/Notification.qml
@@ -27,6 +27,14 @@ StyledRect {
x: Config.notifs.sizes.width
Component.onCompleted: x = 0
+ Behavior on x {
+ NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasizedDecel
+ }
+ }
+
RetainableLock {
object: root.modelData.notification
locked: true
@@ -73,409 +81,401 @@ StyledRect {
if (actions?.length === 1)
actions[0].invoke();
}
- }
- Behavior on x {
- NumberAnimation {
- duration: Appearance.anim.durations.normal
- easing.type: Easing.BezierSpline
- easing.bezierCurve: Appearance.anim.curves.emphasizedDecel
- }
- }
-
- Item {
- id: inner
+ Item {
+ id: inner
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.margins: Appearance.padding.normal
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.margins: Appearance.padding.normal
- implicitHeight: root.nonAnimHeight
+ implicitHeight: root.nonAnimHeight
- Behavior on implicitHeight {
- Anim {
- duration: Appearance.anim.durations.expressiveDefaultSpatial
- easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
+ Behavior on implicitHeight {
+ Anim {
+ duration: Appearance.anim.durations.expressiveDefaultSpatial
+ easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
+ }
}
- }
- Loader {
- id: image
+ Loader {
+ id: image
- active: root.hasImage
- asynchronous: true
+ active: root.hasImage
+ asynchronous: true
- anchors.left: parent.left
- anchors.top: parent.top
- width: Config.notifs.sizes.image
- height: Config.notifs.sizes.image
- visible: root.hasImage || root.hasAppIcon
+ anchors.left: parent.left
+ anchors.top: parent.top
+ width: Config.notifs.sizes.image
+ height: Config.notifs.sizes.image
+ visible: root.hasImage || root.hasAppIcon
- sourceComponent: ClippingRectangle {
- radius: Appearance.rounding.full
- implicitWidth: Config.notifs.sizes.image
- implicitHeight: Config.notifs.sizes.image
+ sourceComponent: ClippingRectangle {
+ radius: Appearance.rounding.full
+ implicitWidth: Config.notifs.sizes.image
+ implicitHeight: Config.notifs.sizes.image
- Image {
- anchors.fill: parent
- source: Qt.resolvedUrl(root.modelData.image)
- fillMode: Image.PreserveAspectCrop
- cache: false
- asynchronous: true
+ Image {
+ anchors.fill: parent
+ source: Qt.resolvedUrl(root.modelData.image)
+ fillMode: Image.PreserveAspectCrop
+ cache: false
+ asynchronous: true
+ }
}
}
- }
- Loader {
- id: appIcon
+ Loader {
+ id: appIcon
- active: root.hasAppIcon || !root.hasImage
- asynchronous: true
+ active: root.hasAppIcon || !root.hasImage
+ asynchronous: true
- anchors.horizontalCenter: root.hasImage ? undefined : image.horizontalCenter
- anchors.verticalCenter: root.hasImage ? undefined : image.verticalCenter
- anchors.right: root.hasImage ? image.right : undefined
- anchors.bottom: root.hasImage ? image.bottom : undefined
+ anchors.horizontalCenter: root.hasImage ? undefined : image.horizontalCenter
+ anchors.verticalCenter: root.hasImage ? undefined : image.verticalCenter
+ anchors.right: root.hasImage ? image.right : undefined
+ anchors.bottom: root.hasImage ? image.bottom : undefined
- sourceComponent: StyledRect {
- radius: Appearance.rounding.full
- color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3error : root.modelData.urgency === NotificationUrgency.Low ? Colours.palette.m3surfaceContainerHighest : Colours.palette.m3tertiaryContainer
- implicitWidth: root.hasImage ? Config.notifs.sizes.badge : Config.notifs.sizes.image
- implicitHeight: root.hasImage ? Config.notifs.sizes.badge : Config.notifs.sizes.image
+ sourceComponent: StyledRect {
+ radius: Appearance.rounding.full
+ color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3error : root.modelData.urgency === NotificationUrgency.Low ? Colours.palette.m3surfaceContainerHighest : Colours.palette.m3tertiaryContainer
+ implicitWidth: root.hasImage ? Config.notifs.sizes.badge : Config.notifs.sizes.image
+ implicitHeight: root.hasImage ? Config.notifs.sizes.badge : Config.notifs.sizes.image
- Loader {
- id: icon
+ Loader {
+ id: icon
- active: root.hasAppIcon
- asynchronous: true
+ active: root.hasAppIcon
+ asynchronous: true
- anchors.centerIn: parent
+ anchors.centerIn: parent
- width: Math.round(parent.width * 0.6)
- height: Math.round(parent.width * 0.6)
+ width: Math.round(parent.width * 0.6)
+ height: Math.round(parent.width * 0.6)
- sourceComponent: IconImage {
- anchors.fill: parent
- source: Quickshell.iconPath(root.modelData.appIcon)
- asynchronous: true
+ sourceComponent: IconImage {
+ anchors.fill: parent
+ source: Quickshell.iconPath(root.modelData.appIcon)
+ asynchronous: true
- layer.enabled: root.modelData.appIcon.endsWith("symbolic")
- layer.effect: Colouriser {
- colorizationColor: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? Colours.palette.m3onSurface : Colours.palette.m3onTertiaryContainer
+ layer.enabled: root.modelData.appIcon.endsWith("symbolic")
+ layer.effect: Colouriser {
+ colorizationColor: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? Colours.palette.m3onSurface : Colours.palette.m3onTertiaryContainer
+ }
}
}
- }
- Loader {
- active: !root.hasAppIcon
- asynchronous: true
- anchors.centerIn: parent
- anchors.horizontalCenterOffset: -Appearance.font.size.large * 0.02
- anchors.verticalCenterOffset: Appearance.font.size.large * 0.02
+ Loader {
+ active: !root.hasAppIcon
+ asynchronous: true
+ anchors.centerIn: parent
+ anchors.horizontalCenterOffset: -Appearance.font.size.large * 0.02
+ anchors.verticalCenterOffset: Appearance.font.size.large * 0.02
- sourceComponent: MaterialIcon {
- text: Icons.getNotifIcon(root.modelData.summary.toLowerCase(), root.modelData.urgency)
+ sourceComponent: MaterialIcon {
+ text: Icons.getNotifIcon(root.modelData.summary.toLowerCase(), root.modelData.urgency)
- color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? Colours.palette.m3onSurface : Colours.palette.m3onTertiaryContainer
- font.pointSize: Appearance.font.size.large
+ color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? Colours.palette.m3onSurface : Colours.palette.m3onTertiaryContainer
+ font.pointSize: Appearance.font.size.large
+ }
}
}
}
- }
- StyledText {
- id: appName
+ StyledText {
+ id: appName
- anchors.top: parent.top
- anchors.left: image.right
- anchors.leftMargin: Appearance.spacing.smaller
+ anchors.top: parent.top
+ anchors.left: image.right
+ anchors.leftMargin: Appearance.spacing.smaller
- animate: true
- text: appNameMetrics.elidedText
- maximumLineCount: 1
- color: Colours.palette.m3onSurfaceVariant
- font.pointSize: Appearance.font.size.small
+ animate: true
+ text: appNameMetrics.elidedText
+ maximumLineCount: 1
+ color: Colours.palette.m3onSurfaceVariant
+ font.pointSize: Appearance.font.size.small
- opacity: root.expanded ? 1 : 0
+ opacity: root.expanded ? 1 : 0
- Behavior on opacity {
- Anim {}
+ Behavior on opacity {
+ Anim {}
+ }
}
- }
- TextMetrics {
- id: appNameMetrics
+ TextMetrics {
+ id: appNameMetrics
- text: root.modelData.appName
- font.family: appName.font.family
- font.pointSize: appName.font.pointSize
- elide: Text.ElideRight
- elideWidth: expandBtn.x - time.width - timeSep.width - summary.x - Appearance.spacing.small * 3
- }
+ text: root.modelData.appName
+ font.family: appName.font.family
+ font.pointSize: appName.font.pointSize
+ elide: Text.ElideRight
+ elideWidth: expandBtn.x - time.width - timeSep.width - summary.x - Appearance.spacing.small * 3
+ }
- StyledText {
- id: summary
+ StyledText {
+ id: summary
- anchors.top: parent.top
- anchors.left: image.right
- anchors.leftMargin: Appearance.spacing.smaller
+ anchors.top: parent.top
+ anchors.left: image.right
+ anchors.leftMargin: Appearance.spacing.smaller
- animate: true
- text: summaryMetrics.elidedText
- maximumLineCount: 1
- height: implicitHeight
+ animate: true
+ text: summaryMetrics.elidedText
+ maximumLineCount: 1
+ height: implicitHeight
- states: State {
- name: "expanded"
- when: root.expanded
+ states: State {
+ name: "expanded"
+ when: root.expanded
- PropertyChanges {
- summary.maximumLineCount: undefined
- }
+ PropertyChanges {
+ summary.maximumLineCount: undefined
+ }
- AnchorChanges {
- target: summary
- anchors.top: appName.bottom
+ AnchorChanges {
+ target: summary
+ anchors.top: appName.bottom
+ }
}
- }
- transitions: Transition {
- PropertyAction {
- target: summary
- property: "maximumLineCount"
- }
- AnchorAnimation {
- duration: Appearance.anim.durations.normal
- easing.type: Easing.BezierSpline
- easing.bezierCurve: Appearance.anim.curves.standard
+ transitions: Transition {
+ PropertyAction {
+ target: summary
+ property: "maximumLineCount"
+ }
+ AnchorAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.standard
+ }
}
- }
- Behavior on height {
- Anim {}
+ Behavior on height {
+ Anim {}
+ }
}
- }
- TextMetrics {
- id: summaryMetrics
+ TextMetrics {
+ id: summaryMetrics
- text: root.modelData.summary
- font.family: summary.font.family
- font.pointSize: summary.font.pointSize
- elide: Text.ElideRight
- elideWidth: expandBtn.x - time.width - timeSep.width - summary.x - Appearance.spacing.small * 3
- }
+ text: root.modelData.summary
+ font.family: summary.font.family
+ font.pointSize: summary.font.pointSize
+ elide: Text.ElideRight
+ elideWidth: expandBtn.x - time.width - timeSep.width - summary.x - Appearance.spacing.small * 3
+ }
- StyledText {
- id: timeSep
+ StyledText {
+ id: timeSep
- anchors.top: parent.top
- anchors.left: summary.right
- anchors.leftMargin: Appearance.spacing.small
+ anchors.top: parent.top
+ anchors.left: summary.right
+ anchors.leftMargin: Appearance.spacing.small
- text: "•"
- color: Colours.palette.m3onSurfaceVariant
- font.pointSize: Appearance.font.size.small
+ text: "•"
+ color: Colours.palette.m3onSurfaceVariant
+ font.pointSize: Appearance.font.size.small
- states: State {
- name: "expanded"
- when: root.expanded
+ states: State {
+ name: "expanded"
+ when: root.expanded
- AnchorChanges {
- target: timeSep
- anchors.left: appName.right
+ AnchorChanges {
+ target: timeSep
+ anchors.left: appName.right
+ }
}
- }
- transitions: Transition {
- AnchorAnimation {
- duration: Appearance.anim.durations.normal
- easing.type: Easing.BezierSpline
- easing.bezierCurve: Appearance.anim.curves.standard
+ transitions: Transition {
+ AnchorAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.standard
+ }
}
}
- }
- StyledText {
- id: time
+ StyledText {
+ id: time
- anchors.top: parent.top
- anchors.left: timeSep.right
- anchors.leftMargin: Appearance.spacing.small
+ anchors.top: parent.top
+ anchors.left: timeSep.right
+ anchors.leftMargin: Appearance.spacing.small
- animate: true
- horizontalAlignment: Text.AlignLeft
- text: root.modelData.timeStr
- color: Colours.palette.m3onSurfaceVariant
- font.pointSize: Appearance.font.size.small
- }
+ animate: true
+ horizontalAlignment: Text.AlignLeft
+ text: root.modelData.timeStr
+ color: Colours.palette.m3onSurfaceVariant
+ font.pointSize: Appearance.font.size.small
+ }
- Item {
- id: expandBtn
+ Item {
+ id: expandBtn
- anchors.right: parent.right
- anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.top: parent.top
- implicitWidth: expandIcon.height
- implicitHeight: expandIcon.height
+ implicitWidth: expandIcon.height
+ implicitHeight: expandIcon.height
- StateLayer {
- radius: Appearance.rounding.full
- color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
+ StateLayer {
+ radius: Appearance.rounding.full
+ color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
- function onClicked() {
- root.expanded = !root.expanded;
+ function onClicked() {
+ root.expanded = !root.expanded;
+ }
}
- }
- MaterialIcon {
- id: expandIcon
+ MaterialIcon {
+ id: expandIcon
- anchors.centerIn: parent
+ anchors.centerIn: parent
- animate: true
- text: root.expanded ? "expand_less" : "expand_more"
- font.pointSize: Appearance.font.size.normal
+ animate: true
+ text: root.expanded ? "expand_less" : "expand_more"
+ font.pointSize: Appearance.font.size.normal
+ }
}
- }
- StyledText {
- id: bodyPreview
+ StyledText {
+ id: bodyPreview
- anchors.left: summary.left
- anchors.right: expandBtn.left
- anchors.top: summary.bottom
- anchors.rightMargin: Appearance.spacing.small
+ anchors.left: summary.left
+ anchors.right: expandBtn.left
+ anchors.top: summary.bottom
+ anchors.rightMargin: Appearance.spacing.small
- animate: true
- textFormat: Text.MarkdownText
- text: bodyPreviewMetrics.elidedText
- color: Colours.palette.m3onSurfaceVariant
- font.pointSize: Appearance.font.size.small
+ animate: true
+ textFormat: Text.MarkdownText
+ text: bodyPreviewMetrics.elidedText
+ color: Colours.palette.m3onSurfaceVariant
+ font.pointSize: Appearance.font.size.small
- opacity: root.expanded ? 0 : 1
+ opacity: root.expanded ? 0 : 1
- Behavior on opacity {
- Anim {}
+ Behavior on opacity {
+ Anim {}
+ }
}
- }
- TextMetrics {
- id: bodyPreviewMetrics
+ TextMetrics {
+ id: bodyPreviewMetrics
- text: root.modelData.body
- font.family: bodyPreview.font.family
- font.pointSize: bodyPreview.font.pointSize
- elide: Text.ElideRight
- elideWidth: bodyPreview.width
- }
+ text: root.modelData.body
+ font.family: bodyPreview.font.family
+ font.pointSize: bodyPreview.font.pointSize
+ elide: Text.ElideRight
+ elideWidth: bodyPreview.width
+ }
- StyledText {
- id: body
+ StyledText {
+ id: body
- anchors.left: summary.left
- anchors.right: expandBtn.left
- anchors.top: summary.bottom
- anchors.rightMargin: Appearance.spacing.small
+ anchors.left: summary.left
+ anchors.right: expandBtn.left
+ anchors.top: summary.bottom
+ anchors.rightMargin: Appearance.spacing.small
- animate: true
- textFormat: Text.MarkdownText
- text: root.modelData.body
- color: Colours.palette.m3onSurfaceVariant
- font.pointSize: Appearance.font.size.small
- wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ animate: true
+ textFormat: Text.MarkdownText
+ text: root.modelData.body
+ color: Colours.palette.m3onSurfaceVariant
+ font.pointSize: Appearance.font.size.small
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
- onLinkActivated: link => {
- if (!root.expanded)
- return;
+ onLinkActivated: link => {
+ if (!root.expanded)
+ return;
- Quickshell.execDetached(["app2unit", "-O", "--", link]);
- root.modelData.notification.dismiss(); // TODO: change back to popup when notif dock impled
- }
+ Quickshell.execDetached(["app2unit", "-O", "--", link]);
+ root.modelData.notification.dismiss(); // TODO: change back to popup when notif dock impled
+ }
- opacity: root.expanded ? 1 : 0
+ opacity: root.expanded ? 1 : 0
- Behavior on opacity {
- Anim {}
+ Behavior on opacity {
+ Anim {}
+ }
}
- }
- RowLayout {
- id: actions
+ RowLayout {
+ id: actions
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: body.bottom
- anchors.topMargin: Appearance.spacing.small
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: body.bottom
+ anchors.topMargin: Appearance.spacing.small
- spacing: Appearance.spacing.smaller
+ spacing: Appearance.spacing.smaller
- opacity: root.expanded ? 1 : 0
+ opacity: root.expanded ? 1 : 0
- Behavior on opacity {
- Anim {}
- }
+ Behavior on opacity {
+ Anim {}
+ }
- Action {
- modelData: QtObject {
- readonly property string text: qsTr("Close")
- function invoke(): void {
- root.modelData.notification.dismiss();
+ Action {
+ modelData: QtObject {
+ readonly property string text: qsTr("Close")
+ function invoke(): void {
+ root.modelData.notification.dismiss();
+ }
}
}
- }
- Repeater {
- model: root.modelData.actions
+ Repeater {
+ model: root.modelData.actions
- delegate: Component {
- Action {}
+ delegate: Component {
+ Action {}
+ }
}
}
}
- }
- component Action: StyledRect {
- id: action
+ component Action: StyledRect {
+ id: action
- required property var modelData
+ required property var modelData
- radius: Appearance.rounding.full
- color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3secondary : Colours.palette.m3surfaceContainerHigh
+ radius: Appearance.rounding.full
+ color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3secondary : Colours.palette.m3surfaceContainerHigh
- Layout.preferredWidth: actionText.width + Appearance.padding.normal * 2
- Layout.preferredHeight: actionText.height + Appearance.padding.small * 2
- implicitWidth: actionText.width + Appearance.padding.normal * 2
- implicitHeight: actionText.height + Appearance.padding.small * 2
+ Layout.preferredWidth: actionText.width + Appearance.padding.normal * 2
+ Layout.preferredHeight: actionText.height + Appearance.padding.small * 2
+ implicitWidth: actionText.width + Appearance.padding.normal * 2
+ implicitHeight: actionText.height + Appearance.padding.small * 2
- StateLayer {
- radius: Appearance.rounding.full
- color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondary : Colours.palette.m3onSurface
+ StateLayer {
+ radius: Appearance.rounding.full
+ color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondary : Colours.palette.m3onSurface
- function onClicked(): void {
- action.modelData.invoke();
+ function onClicked(): void {
+ action.modelData.invoke();
+ }
}
- }
- StyledText {
- id: actionText
+ StyledText {
+ id: actionText
- anchors.centerIn: parent
- text: actionTextMetrics.elidedText
- color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondary : Colours.palette.m3onSurfaceVariant
- font.pointSize: Appearance.font.size.small
- }
+ anchors.centerIn: parent
+ text: actionTextMetrics.elidedText
+ color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondary : Colours.palette.m3onSurfaceVariant
+ font.pointSize: Appearance.font.size.small
+ }
- TextMetrics {
- id: actionTextMetrics
+ TextMetrics {
+ id: actionTextMetrics
- text: action.modelData.text
- font.family: actionText.font.family
- font.pointSize: actionText.font.pointSize
- elide: Text.ElideRight
- elideWidth: {
- const numActions = root.modelData.actions.length + 1;
- return (inner.width - actions.spacing * (numActions - 1)) / numActions - Appearance.padding.normal * 2;
+ text: action.modelData.text
+ font.family: actionText.font.family
+ font.pointSize: actionText.font.pointSize
+ elide: Text.ElideRight
+ elideWidth: {
+ const numActions = root.modelData.actions.length + 1;
+ return (inner.width - actions.spacing * (numActions - 1)) / numActions - Appearance.padding.normal * 2;
+ }
}
}
}