157 lines
3.7 KiB
QML
157 lines
3.7 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import Quickshell
|
|
import QtQuick
|
|
import QtQuick.Layouts
|
|
import ZShell.Components
|
|
import qs.Components
|
|
import qs.Config
|
|
import qs.Modules
|
|
import qs.Daemons
|
|
|
|
LazyListView {
|
|
id: root
|
|
|
|
required property Flickable container
|
|
required property bool expanded
|
|
required property list<var> notifs
|
|
required property Props props
|
|
required property PersistentProperties visibilities
|
|
|
|
signal requestToggleExpand(expand: bool)
|
|
|
|
Layout.fillWidth: true
|
|
asynchronous: true
|
|
cacheBuffer: 400
|
|
implicitHeight: contentHeight
|
|
readyDelay: 1
|
|
removeDuration: Appearance.anim.durations.normal
|
|
spacing: Math.round(Appearance.spacing.small / 2)
|
|
useCustomViewport: true
|
|
viewport: {
|
|
tWatcher.transform; // mapToItem is not reactive so use this to trigger updates
|
|
return Qt.rect(0, container.contentY - mapToItem(container.contentItem, 0, 0).y, width, container.height);
|
|
}
|
|
|
|
delegate: Component {
|
|
MouseArea {
|
|
id: notif
|
|
|
|
required property int index
|
|
required property NotifServer.Notif modelData
|
|
property int startY
|
|
|
|
LazyListView.preferredHeight: modelData?.closed || LazyListView.removing ? 0 : notifInner.nonAnimHeight
|
|
LazyListView.visibleHeight: modelData?.closed || LazyListView.removing ? 0 : notifInner.implicitHeight
|
|
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
|
cursorShape: notifInner.body?.hoveredLink ? Qt.PointingHandCursor : pressed ? Qt.ClosedHandCursor : undefined
|
|
drag.axis: Drag.XAxis
|
|
drag.target: this
|
|
enabled: !(modelData?.closed ?? true)
|
|
hoverEnabled: true
|
|
implicitHeight: notifInner.implicitHeight
|
|
opacity: LazyListView.removing || LazyListView.adding ? 0 : 1
|
|
preventStealing: !root.expanded
|
|
scale: LazyListView.removing || LazyListView.adding ? 0.7 : 1
|
|
|
|
Behavior on opacity {
|
|
Anim {
|
|
}
|
|
}
|
|
Behavior on scale {
|
|
Anim {
|
|
}
|
|
}
|
|
Behavior on x {
|
|
Anim {
|
|
duration: MaterialEasing.expressiveEffectsTime
|
|
easing.bezierCurve: MaterialEasing.expressiveEffects
|
|
}
|
|
}
|
|
Behavior on y {
|
|
enabled: notif.LazyListView.ready
|
|
|
|
Anim {
|
|
duration: MaterialEasing.expressiveEffectsTime
|
|
easing.bezierCurve: MaterialEasing.expressiveEffects
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: modelData?.lock(this)
|
|
Component.onDestruction: modelData?.unlock(this)
|
|
onPositionChanged: event => {
|
|
if (pressed && !root.expanded) {
|
|
const diffY = event.y - startY;
|
|
if (Math.abs(diffY) > Config.notifs.expandThreshold)
|
|
root.requestToggleExpand(diffY > 0);
|
|
}
|
|
}
|
|
onPressed: event => {
|
|
startY = event.y;
|
|
if (event.button === Qt.RightButton)
|
|
root.requestToggleExpand(!root.expanded);
|
|
else if (event.button === Qt.MiddleButton)
|
|
modelData?.close();
|
|
}
|
|
onReleased: event => {
|
|
if (Math.abs(x) < width * Config.notifs.clearThreshold)
|
|
x = 0;
|
|
else
|
|
modelData?.close();
|
|
}
|
|
|
|
ParallelAnimation {
|
|
running: notif.modelData?.closed ?? false
|
|
|
|
onFinished: notif.modelData?.unlock(notif)
|
|
|
|
Anim {
|
|
property: "opacity"
|
|
target: notif
|
|
to: 0
|
|
}
|
|
|
|
Anim {
|
|
property: "x"
|
|
target: notif
|
|
to: notif.x >= 0 ? notif.width : -notif.width
|
|
}
|
|
}
|
|
|
|
Notif {
|
|
id: notifInner
|
|
|
|
anchors.fill: parent
|
|
expanded: root.expanded
|
|
modelData: notif.modelData
|
|
props: root.props
|
|
visibilities: root.visibilities
|
|
}
|
|
}
|
|
}
|
|
model: ScriptModel {
|
|
values: {
|
|
if (root.expanded)
|
|
return root.notifs;
|
|
|
|
let count = 0;
|
|
let i = 0;
|
|
const previewNum = Config.notifs.groupPreviewNum;
|
|
while (i < root.notifs.length && count < previewNum) {
|
|
if (!(root.notifs[i]?.closed ?? true))
|
|
count++;
|
|
i++;
|
|
}
|
|
|
|
return root.notifs.slice(0, i);
|
|
}
|
|
}
|
|
|
|
TransformWatcher {
|
|
id: tWatcher
|
|
|
|
a: root.container.contentItem
|
|
b: root
|
|
}
|
|
}
|