C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 11s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 12s
JS/TS / lint (pull_request) Successful in 10s
Python / static (pull_request) Failing after 27s
Rust / build (pull_request) Successful in 54s
Python / verify (pull_request) Failing after 1m26s
Rust / fmt (pull_request) Successful in 46s
Rust / clippy (pull_request) Successful in 1m6s
220 lines
5.0 KiB
QML
220 lines
5.0 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import Quickshell
|
|
import Quickshell.Widgets
|
|
import QtQuick
|
|
import ZShell.Components
|
|
import ZShell.Config
|
|
import ZShell.Services
|
|
import qs.Components
|
|
import qs.Components.Notifs
|
|
import qs.Daemons
|
|
import qs.Helpers
|
|
import qs.Services
|
|
|
|
Item {
|
|
id: root
|
|
|
|
readonly property int padding: Tokens.padding.smaller
|
|
required property Item panels
|
|
required property ScreenState screenState
|
|
|
|
anchors.bottom: parent.bottom
|
|
anchors.right: parent.right
|
|
anchors.top: parent.top
|
|
implicitHeight: {
|
|
if (list.count === 0)
|
|
return 0;
|
|
|
|
let height = list.layoutHeight;
|
|
|
|
if (panels.popouts.hasCurrent && (panels.popouts.currentCenter + (panels.popouts.current?.width / 2)) > panels.notifications.x)
|
|
return 0;
|
|
|
|
if (screenState.dashboard && (panels.dashboard.x + panels.dashboard.width >= panels.notifications.x))
|
|
return 0;
|
|
|
|
if (screenState.osd) {
|
|
const h = panels.osd.y - Tokens.spacing.small * 2 - padding * 2;
|
|
if (height > h)
|
|
height = h;
|
|
}
|
|
|
|
return Math.min(((QsWindow.window as QsWindow)?.screen?.height ?? 0) - 1 * 2, height + padding * 2);
|
|
}
|
|
|
|
implicitWidth: Config.notifs.sizes.width + padding * 2
|
|
|
|
Behavior on implicitHeight {
|
|
Anim {}
|
|
}
|
|
|
|
Item {
|
|
anchors.fill: parent
|
|
anchors.margins: root.padding
|
|
clip: true
|
|
|
|
KineticFlickable {
|
|
id: view
|
|
|
|
anchors.fill: parent
|
|
|
|
contentHeight: list.implicitHeight
|
|
contentWidth: width
|
|
flickableDirection: Flickable.VerticalFlick
|
|
|
|
LazyListView {
|
|
id: list
|
|
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
implicitHeight: contentHeight
|
|
|
|
spacing: Tokens.spacing.medium
|
|
readyDelay: 1
|
|
cacheBuffer: (QsWindow.window as QsWindow)?.screen.height ?? 0
|
|
removeDuration: Tokens.anim.durations.normal
|
|
|
|
useCustomViewport: true
|
|
viewport: Qt.rect(0, view.contentY, width, view.height)
|
|
|
|
model: ScriptModel {
|
|
values: {
|
|
if (!Config.notifs.showInFullscreen) {
|
|
if (Hypr.monitorFor(root.panels.screen).activeWorkspace?.toplevels.values.some(t => t.lastIpcObject.fullscreen > 1) ?? false)
|
|
return [];
|
|
}
|
|
return [...NotifServer.popupGroups];
|
|
}
|
|
}
|
|
|
|
delegate: NotifWrapper {}
|
|
|
|
onViewportAdjustNeeded: d => {
|
|
if (contentYAnim.running)
|
|
contentYAnim.complete();
|
|
contentYAnim.to = Math.max(0, view.contentY + d);
|
|
contentYAnim.start();
|
|
}
|
|
|
|
Anim {
|
|
id: contentYAnim
|
|
|
|
target: view
|
|
property: "contentY"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
component Anim: NumberAnimation {
|
|
duration: Tokens.anim.durations.expressiveDefaultSpatial
|
|
easing: Tokens.anim.expressiveDefaultSpatial
|
|
}
|
|
component NotifWrapper: Item {
|
|
id: wrapper
|
|
|
|
required property NotificationGroup modelData
|
|
property bool expanded: Config.notifs.openExpanded
|
|
readonly property bool holding: area.containsMouse || area.pressed || card.rowPressed
|
|
|
|
function forEachPopup(fn: var): void {
|
|
for (const n of [...card.notifs])
|
|
fn(n);
|
|
}
|
|
|
|
function holdPopups(): void {
|
|
forEachPopup(n => n.holdPopup());
|
|
}
|
|
|
|
LazyListView.trackViewport: !expanded && card.nonAnimHeight < card.implicitHeight
|
|
LazyListView.preferredHeight: LazyListView.removing ? 0 : card.nonAnimHeight
|
|
LazyListView.visibleHeight: LazyListView.removing ? 0 : card.implicitHeight
|
|
LazyListView.onRemovingChanged: {
|
|
if (!wrapper.LazyListView.removing)
|
|
return;
|
|
|
|
slideOut.to = (area.x >= 0 ? root.implicitWidth : -root.implicitWidth) * 2;
|
|
slideOut.start();
|
|
}
|
|
|
|
implicitWidth: area.implicitWidth
|
|
implicitHeight: card.implicitHeight
|
|
|
|
enabled: !LazyListView.removing
|
|
z: LazyListView.removing ? 1 : 0
|
|
|
|
onHoldingChanged: {
|
|
if (holding)
|
|
holdPopups();
|
|
else
|
|
forEachPopup(n => n.releasePopup());
|
|
}
|
|
|
|
Connections {
|
|
function onNotifsChanged(): void {
|
|
if (wrapper.holding)
|
|
wrapper.holdPopups();
|
|
}
|
|
|
|
target: wrapper.modelData
|
|
}
|
|
|
|
Anim {
|
|
id: slideOut
|
|
|
|
target: area
|
|
property: "x"
|
|
duration: Tokens.anim.durations.normal
|
|
easing: Tokens.anim.emphasized
|
|
}
|
|
|
|
Item {
|
|
anchors.top: parent.top
|
|
|
|
implicitWidth: area.implicitWidth
|
|
implicitHeight: card.implicitHeight
|
|
clip: true
|
|
|
|
NotifSwipeArea {
|
|
id: area
|
|
|
|
implicitWidth: root.implicitWidth - root.padding * 2
|
|
implicitHeight: card.implicitHeight
|
|
x: wrapper.LazyListView.adding ? implicitWidth : 0
|
|
|
|
expanded: wrapper.expanded
|
|
|
|
onRequestExpand: expand => wrapper.expanded = expand
|
|
onSwiped: wrapper.forEachPopup(n => n.dismissPopup())
|
|
onDismissed: wrapper.forEachPopup(n => n.dismiss())
|
|
onClicked: event => {
|
|
if (!Config.notifs.actionOnClick || event.button !== Qt.LeftButton || card.notifs.length !== 1)
|
|
return;
|
|
|
|
const actions = card.notifs[0].actions;
|
|
if (actions.length === 1)
|
|
actions[0].invoke();
|
|
}
|
|
|
|
NotifGroupCard {
|
|
id: card
|
|
|
|
group: wrapper.modelData
|
|
container: view
|
|
expanded: wrapper.expanded
|
|
onRequestExpand: expand => wrapper.expanded = expand
|
|
onSwiped: notif => notif.dismissPopup()
|
|
onLinkActivated: notif => notif.dismissPopup()
|
|
}
|
|
}
|
|
}
|
|
|
|
Behavior on y {
|
|
enabled: wrapper.LazyListView.ready
|
|
|
|
Anim {}
|
|
}
|
|
}
|
|
}
|