mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-15 07:35:20 -04:00
feat(notifications): add opt-in timeout progress bar on popups (#2587)
Adds a thin bar pinned to the bottom of the notification card that drains full->empty over the auto-dismiss timer, as a visual countdown to dismissal. Opt-in via notificationShowTimeoutBar (default off), with a toggle in Settings > Notifications. Shown for any timed notification (timer.interval > 0, including timed criticals); inset by the corner radius, and frozen while hovered or during the exit animation. Plain Rectangle - no offscreen textures or shader passes. A Connections on the timer resets the bar on every (re)start, including the in-place restart on a deduped notification. Co-authored-by: bogdan-velicu <hydrotech074@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -727,6 +727,51 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
|
||||
// Timeout progress bar: drains as the dismiss timer runs; inset by
|
||||
// the corner radius and frozen while hovered or during exit.
|
||||
Rectangle {
|
||||
id: timeoutBar
|
||||
|
||||
readonly property bool active: SettingsData.notificationShowTimeoutBar && notificationData && notificationData.timer && notificationData.timer.interval > 0
|
||||
property real progress: 1
|
||||
readonly property real surfaceRadius: win.connectedFrameMode ? Theme.connectedSurfaceRadius : Theme.cornerRadius
|
||||
|
||||
visible: active && progress > 0
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: surfaceRadius
|
||||
anchors.bottom: parent.bottom
|
||||
width: Math.max(0, parent.width - surfaceRadius * 2) * progress
|
||||
height: Math.max(2, Theme.snap(3, win.dpr))
|
||||
radius: height / 2
|
||||
z: 50
|
||||
opacity: 0.9
|
||||
color: notificationData && notificationData.urgency === NotificationUrgency.Critical ? Theme.error : Theme.primary
|
||||
|
||||
NumberAnimation {
|
||||
id: progressAnim
|
||||
target: timeoutBar
|
||||
property: "progress"
|
||||
from: 1
|
||||
to: 0
|
||||
duration: (notificationData && notificationData.timer && notificationData.timer.interval > 0) ? notificationData.timer.interval : 5000
|
||||
running: timeoutBar.active && notificationData && notificationData.timer && notificationData.timer.running && !win.exiting
|
||||
easing.type: Easing.Linear
|
||||
}
|
||||
|
||||
// Reset to full on every (re)start, including an in-place
|
||||
// restart on a deduped notification (running stays true, so the
|
||||
// bound animation alone wouldn't re-fire).
|
||||
Connections {
|
||||
target: timeoutBar.active ? notificationData.timer : null
|
||||
function onRunningChanged() {
|
||||
if (notificationData && notificationData.timer && notificationData.timer.running && !win.exiting) {
|
||||
timeoutBar.progress = 1;
|
||||
progressAnim.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LayoutMirroring.enabled: I18n.isRtl
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
|
||||
Reference in New Issue
Block a user