feat: expire progress bar on popup notifs

This commit is contained in:
2026-11-09 21:39:21 +01:00
parent e49ecabf62
commit 37e0429563
5 changed files with 324 additions and 153 deletions
+76 -9
View File
@@ -10,6 +10,7 @@ import qs.Components
import qs.Components.Notifs
import qs.Daemons
import qs.Helpers
import qs.Services
Item {
id: root
@@ -109,10 +110,6 @@ Item {
}
}
component Anim: NumberAnimation {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
}
component NotifWrapper: Item {
id: wrapper
@@ -125,8 +122,8 @@ Item {
fn(n);
}
function holdPopups(): void {
forEachPopup(n => n.holdPopup());
function holdGroupExpiry(): void {
wrapper.modelData.holdExpiry();
}
LazyListView.trackViewport: !expanded && card.nonAnimHeight < card.implicitHeight
@@ -148,15 +145,33 @@ Item {
onHoldingChanged: {
if (holding)
holdPopups();
holdGroupExpiry();
else
forEachPopup(n => n.releasePopup());
wrapper.modelData.releaseExpiry();
}
Connections {
function onNotifsChanged(): void {
if (wrapper.holding)
wrapper.holdPopups();
wrapper.holdGroupExpiry();
}
function onExpireTimerRestarted(): void {
if (expireProgress.running)
expireProgress.stop();
expireProgressReset.start();
}
function onExpirePausedChanged(): void {
if (wrapper.modelData.expirePaused) {
if (expireProgress.running)
expireProgress.pause();
} else {
if (expireProgress.running)
expireProgress.resume();
else
expireProgress.start();
}
}
target: wrapper.modelData
@@ -171,6 +186,39 @@ Item {
easing: Tokens.anim.emphasized
}
Anim {
id: expireProgressReset
readonly property bool nPaused: wrapper.modelData.expirePaused
target: progress
property: "implicitWidth"
type: Anim.FastEffects
to: nPaused ? area.width : area.width * (1 - duration / expireProgress.duration)
onFinished: {
if (nPaused)
expireProgress.duration = wrapper.modelData.expireTimeout;
else
expireProgress.duration = wrapper.modelData.expireTimeout - expireProgressReset.duration;
expireProgress.from = to;
if (!nPaused)
expireProgress.start();
}
}
Anim {
id: expireProgress
running: wrapper.modelData.expireActive
target: progress
property: "implicitWidth"
duration: wrapper.modelData.expireTimeout
easing.type: Easing.Linear
from: area.width
to: 0
}
Item {
anchors.top: parent.top
@@ -208,6 +256,25 @@ Item {
onRequestExpand: expand => wrapper.expanded = expand
onSwiped: notif => notif.dismissPopup()
onLinkActivated: notif => notif.dismissPopup()
bottomPadding: Config.notifs.expire ? progress.implicitHeight : 0
}
CustomClippingRect {
anchors.fill: parent
radius: Tokens.rounding.large
visible: Config.notifs.expire
CustomRect {
id: progress
anchors.bottom: parent.bottom
anchors.right: parent.right
implicitWidth: parent.width
implicitHeight: 6
color: Colors.palette.m3outlineVariant
}
}
}
}