feat: expandable notifs
This commit is contained in:
parent
f0e0569737
commit
60254019c8
4 changed files with 141 additions and 31 deletions
|
|
@ -31,7 +31,7 @@ Item {
|
||||||
implicitHeight: {
|
implicitHeight: {
|
||||||
let height = (count - 1) * spacing;
|
let height = (count - 1) * spacing;
|
||||||
for (let i = 0; i < count; i++)
|
for (let i = 0; i < count; i++)
|
||||||
height += itemAtIndex(i).height;
|
height += itemAtIndex(i).nonAnimHeight;
|
||||||
return Math.max(61, height);
|
return Math.max(61, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,10 @@ StyledRect {
|
||||||
readonly property bool hasImage: modelData.image.length > 0
|
readonly property bool hasImage: modelData.image.length > 0
|
||||||
readonly property bool hasAppIcon: modelData.appIcon.length > 0
|
readonly property bool hasAppIcon: modelData.appIcon.length > 0
|
||||||
readonly property int imageSize: summary.height + bodyPreview.height
|
readonly property int imageSize: summary.height + bodyPreview.height
|
||||||
|
readonly property int nonAnimHeight: summary.height + (root.expanded ? appName.height + body.height : bodyPreview.height) + inner.anchors.margins * 2
|
||||||
property bool expanded
|
property bool expanded
|
||||||
|
|
||||||
|
clip: true
|
||||||
color: Colours.palette.m3surfaceContainer
|
color: Colours.palette.m3surfaceContainer
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
implicitWidth: NotifsConfig.sizes.width
|
implicitWidth: NotifsConfig.sizes.width
|
||||||
|
|
@ -67,7 +69,11 @@ StyledRect {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.margins: Appearance.padding.normal
|
anchors.margins: Appearance.padding.normal
|
||||||
|
|
||||||
implicitHeight: summary.height + bodyPreview.height + anchors.margins * 2
|
implicitHeight: root.nonAnimHeight
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: image
|
id: image
|
||||||
|
|
@ -76,8 +82,7 @@ StyledRect {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.top: parent.top
|
||||||
anchors.verticalCenterOffset: -parent.anchors.margins
|
|
||||||
width: root.hasImage || root.hasAppIcon ? root.imageSize : 0
|
width: root.hasImage || root.hasAppIcon ? root.imageSize : 0
|
||||||
height: root.hasImage || root.hasAppIcon ? root.imageSize : 0
|
height: root.hasImage || root.hasAppIcon ? root.imageSize : 0
|
||||||
visible: root.hasImage || root.hasAppIcon
|
visible: root.hasImage || root.hasAppIcon
|
||||||
|
|
@ -95,16 +100,6 @@ StyledRect {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
states: State {
|
|
||||||
name: "expanded"
|
|
||||||
when: root.expanded
|
|
||||||
|
|
||||||
AnchorChanges {
|
|
||||||
anchors.verticalCenter: undefined
|
|
||||||
anchors.top: image.parent.top
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
|
@ -140,27 +135,76 @@ StyledRect {
|
||||||
colorizationColor: Colours.palette.m3onTertiaryContainer
|
colorizationColor: Colours.palette.m3onTertiaryContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
states: State {
|
StyledText {
|
||||||
name: "expanded"
|
id: appName
|
||||||
when: !root.hasImage && root.expanded
|
|
||||||
|
|
||||||
AnchorChanges {
|
anchors.top: parent.top
|
||||||
anchors.verticalCenter: undefined
|
anchors.left: image.right
|
||||||
anchors.top: image.parent.top
|
anchors.leftMargin: Appearance.spacing.smaller
|
||||||
}
|
|
||||||
|
animate: true
|
||||||
|
text: appNameMetrics.elidedText
|
||||||
|
maximumLineCount: 1
|
||||||
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
|
font.pointSize: Appearance.font.size.small
|
||||||
|
|
||||||
|
opacity: root.expanded ? 1 : 0
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: summary
|
id: summary
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: image.right
|
anchors.left: image.right
|
||||||
anchors.leftMargin: Appearance.spacing.small
|
anchors.leftMargin: Appearance.spacing.smaller
|
||||||
|
|
||||||
|
animate: true
|
||||||
|
text: summaryMetrics.elidedText
|
||||||
|
maximumLineCount: 1
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "expanded"
|
||||||
|
when: root.expanded
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: summary
|
||||||
|
anchors.top: appName.bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transitions: Transition {
|
||||||
|
AnchorAnimation {
|
||||||
|
duration: Appearance.anim.durations.normal
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: summaryMetrics
|
||||||
|
|
||||||
text: root.modelData.summary
|
text: root.modelData.summary
|
||||||
maximumLineCount: 1
|
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 {
|
StyledText {
|
||||||
|
|
@ -173,6 +217,24 @@ StyledRect {
|
||||||
text: "•"
|
text: "•"
|
||||||
color: Colours.palette.m3onSurfaceVariant
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
font.pointSize: Appearance.font.size.small
|
font.pointSize: Appearance.font.size.small
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "expanded"
|
||||||
|
when: root.expanded
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|
@ -189,21 +251,31 @@ StyledRect {
|
||||||
font.pointSize: Appearance.font.size.small
|
font.pointSize: Appearance.font.size.small
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
Item {
|
||||||
id: expandBtn
|
id: expandBtn
|
||||||
|
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
||||||
MaterialIcon {
|
implicitWidth: expandIcon.height
|
||||||
animate: true
|
implicitHeight: expandIcon.height
|
||||||
text: root.expanded ? "expand_less" : "expand_more"
|
|
||||||
font.pointSize: Appearance.font.size.smaller
|
StateLayer {
|
||||||
|
radius: Appearance.rounding.full
|
||||||
|
|
||||||
|
function onClicked() {
|
||||||
|
root.expanded = !root.expanded;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MaterialIcon {
|
||||||
anchors.fill: parent
|
id: expandIcon
|
||||||
onClicked: root.expanded = !root.expanded
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
animate: true
|
||||||
|
text: root.expanded ? "expand_less" : "expand_more"
|
||||||
|
font.pointSize: Appearance.font.size.normal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,9 +287,16 @@ StyledRect {
|
||||||
anchors.top: summary.bottom
|
anchors.top: summary.bottom
|
||||||
anchors.rightMargin: Appearance.spacing.small
|
anchors.rightMargin: Appearance.spacing.small
|
||||||
|
|
||||||
|
animate: true
|
||||||
text: bodyPreviewMetrics.elidedText
|
text: bodyPreviewMetrics.elidedText
|
||||||
color: Colours.palette.m3onSurfaceVariant
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
font.pointSize: Appearance.font.size.small
|
font.pointSize: Appearance.font.size.small
|
||||||
|
|
||||||
|
opacity: root.expanded ? 0 : 1
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextMetrics {
|
TextMetrics {
|
||||||
|
|
@ -229,5 +308,32 @@ StyledRect {
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
elideWidth: bodyPreview.width
|
elideWidth: bodyPreview.width
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: body
|
||||||
|
|
||||||
|
anchors.left: summary.left
|
||||||
|
anchors.right: expandBtn.left
|
||||||
|
anchors.top: summary.bottom
|
||||||
|
anchors.rightMargin: Appearance.spacing.small
|
||||||
|
|
||||||
|
animate: true
|
||||||
|
text: root.modelData.body
|
||||||
|
color: Colours.palette.m3onSurfaceVariant
|
||||||
|
font.pointSize: Appearance.font.size.small
|
||||||
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||||
|
|
||||||
|
opacity: root.expanded ? 1 : 0
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Anim: NumberAnimation {
|
||||||
|
duration: Appearance.anim.durations.normal
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import "root:/config"
|
import "root:/config"
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
|
@ -52,6 +53,7 @@ Singleton {
|
||||||
readonly property string summary: notification.summary
|
readonly property string summary: notification.summary
|
||||||
readonly property string body: notification.body
|
readonly property string body: notification.body
|
||||||
readonly property string appIcon: notification.appIcon
|
readonly property string appIcon: notification.appIcon
|
||||||
|
readonly property string appName: notification.appName
|
||||||
readonly property string image: notification.image
|
readonly property string image: notification.image
|
||||||
|
|
||||||
readonly property Timer timer: Timer {
|
readonly property Timer timer: Timer {
|
||||||
|
|
@ -64,6 +66,7 @@ Singleton {
|
||||||
target: notif.notification
|
target: notif.notification
|
||||||
|
|
||||||
function onClosed(): void {
|
function onClosed(): void {
|
||||||
|
root.list.splice(root.list.indexOf(notif), 1);
|
||||||
notif.destroy();
|
notif.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ Rectangle {
|
||||||
property bool hovered
|
property bool hovered
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|
||||||
onEntered: hovered = true
|
onEntered: hovered = true
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue