mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-28 15:32:50 -05:00
@@ -18,12 +18,12 @@ DankListView {
|
|||||||
|
|
||||||
onIsUserScrollingChanged: {
|
onIsUserScrollingChanged: {
|
||||||
if (isUserScrolling && keyboardController && keyboardController.keyboardNavigationActive) {
|
if (isUserScrolling && keyboardController && keyboardController.keyboardNavigationActive) {
|
||||||
autoScrollDisabled = true
|
autoScrollDisabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function enableAutoScroll() {
|
function enableAutoScroll() {
|
||||||
autoScrollDisabled = false
|
autoScrollDisabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
@@ -33,7 +33,7 @@ DankListView {
|
|||||||
repeat: true
|
repeat: true
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled) {
|
if (keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled) {
|
||||||
keyboardController.ensureVisible()
|
keyboardController.ensureVisible();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,48 +46,105 @@ DankListView {
|
|||||||
|
|
||||||
onModelChanged: {
|
onModelChanged: {
|
||||||
if (!keyboardController || !keyboardController.keyboardNavigationActive) {
|
if (!keyboardController || !keyboardController.keyboardNavigationActive) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
keyboardController.rebuildFlatNavigation()
|
keyboardController.rebuildFlatNavigation();
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
if (keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled) {
|
if (keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled) {
|
||||||
keyboardController.ensureVisible()
|
keyboardController.ensureVisible();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
|
id: delegateRoot
|
||||||
required property var modelData
|
required property var modelData
|
||||||
required property int index
|
required property int index
|
||||||
|
|
||||||
readonly property bool isExpanded: (NotificationService.expandedGroups[modelData && modelData.key] || false)
|
readonly property bool isExpanded: (NotificationService.expandedGroups[modelData && modelData.key] || false)
|
||||||
|
property real swipeOffset: 0
|
||||||
|
property bool isDismissing: false
|
||||||
|
readonly property real dismissThreshold: width * 0.35
|
||||||
|
|
||||||
width: ListView.view.width
|
width: ListView.view.width
|
||||||
height: notificationCard.height
|
height: isDismissing ? 0 : notificationCard.height
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Behavior on height {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NotificationCard {
|
NotificationCard {
|
||||||
id: notificationCard
|
id: notificationCard
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
x: delegateRoot.swipeOffset
|
||||||
notificationGroup: modelData
|
notificationGroup: modelData
|
||||||
keyboardNavigationActive: listView.keyboardActive
|
keyboardNavigationActive: listView.keyboardActive
|
||||||
|
opacity: 1 - Math.abs(delegateRoot.swipeOffset) / (delegateRoot.width * 0.5)
|
||||||
|
|
||||||
isGroupSelected: {
|
isGroupSelected: {
|
||||||
if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive) {
|
if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive)
|
||||||
return false
|
return false;
|
||||||
}
|
keyboardController.selectionVersion;
|
||||||
keyboardController.selectionVersion
|
const selection = keyboardController.getCurrentSelection();
|
||||||
const selection = keyboardController.getCurrentSelection()
|
return selection.type === "group" && selection.groupIndex === index;
|
||||||
return selection.type === "group" && selection.groupIndex === index
|
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedNotificationIndex: {
|
selectedNotificationIndex: {
|
||||||
if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive) {
|
if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive)
|
||||||
return -1
|
return -1;
|
||||||
}
|
keyboardController.selectionVersion;
|
||||||
keyboardController.selectionVersion
|
const selection = keyboardController.getCurrentSelection();
|
||||||
const selection = keyboardController.getCurrentSelection()
|
return (selection.type === "notification" && selection.groupIndex === index) ? selection.notificationIndex : -1;
|
||||||
return (selection.type === "notification" && selection.groupIndex === index) ? selection.notificationIndex : -1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on x {
|
||||||
|
enabled: !swipeDragHandler.active
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DragHandler {
|
||||||
|
id: swipeDragHandler
|
||||||
|
target: null
|
||||||
|
yAxis.enabled: false
|
||||||
|
xAxis.enabled: true
|
||||||
|
|
||||||
|
onActiveChanged: {
|
||||||
|
if (active || delegateRoot.isDismissing)
|
||||||
|
return;
|
||||||
|
if (Math.abs(delegateRoot.swipeOffset) > delegateRoot.dismissThreshold) {
|
||||||
|
delegateRoot.isDismissing = true;
|
||||||
|
delegateRoot.swipeOffset = delegateRoot.swipeOffset > 0 ? delegateRoot.width : -delegateRoot.width;
|
||||||
|
dismissTimer.start();
|
||||||
|
} else {
|
||||||
|
delegateRoot.swipeOffset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTranslationChanged: {
|
||||||
|
if (delegateRoot.isDismissing)
|
||||||
|
return;
|
||||||
|
delegateRoot.swipeOffset = translation.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: dismissTimer
|
||||||
|
interval: Theme.shortDuration
|
||||||
|
onTriggered: NotificationService.dismissGroup(delegateRoot.modelData?.key || "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,42 +153,42 @@ DankListView {
|
|||||||
|
|
||||||
function onGroupedNotificationsChanged() {
|
function onGroupedNotificationsChanged() {
|
||||||
if (!keyboardController) {
|
if (!keyboardController) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyboardController.isTogglingGroup) {
|
if (keyboardController.isTogglingGroup) {
|
||||||
keyboardController.rebuildFlatNavigation()
|
keyboardController.rebuildFlatNavigation();
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
keyboardController.rebuildFlatNavigation()
|
keyboardController.rebuildFlatNavigation();
|
||||||
|
|
||||||
if (keyboardController.keyboardNavigationActive) {
|
if (keyboardController.keyboardNavigationActive) {
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
if (!autoScrollDisabled) {
|
if (!autoScrollDisabled) {
|
||||||
keyboardController.ensureVisible()
|
keyboardController.ensureVisible();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onExpandedGroupsChanged() {
|
function onExpandedGroupsChanged() {
|
||||||
if (keyboardController && keyboardController.keyboardNavigationActive) {
|
if (keyboardController && keyboardController.keyboardNavigationActive) {
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
if (!autoScrollDisabled) {
|
if (!autoScrollDisabled) {
|
||||||
keyboardController.ensureVisible()
|
keyboardController.ensureVisible();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onExpandedMessagesChanged() {
|
function onExpandedMessagesChanged() {
|
||||||
if (keyboardController && keyboardController.keyboardNavigationActive) {
|
if (keyboardController && keyboardController.keyboardNavigationActive) {
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
if (!autoScrollDisabled) {
|
if (!autoScrollDisabled) {
|
||||||
keyboardController.ensureVisible()
|
keyboardController.ensureVisible();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import QtQuick.Effects
|
|||||||
import QtQuick.Shapes
|
import QtQuick.Shapes
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Widgets
|
|
||||||
import Quickshell.Services.Notifications
|
import Quickshell.Services.Notifications
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
@@ -29,63 +28,63 @@ PanelWindow {
|
|||||||
|
|
||||||
function startExit() {
|
function startExit() {
|
||||||
if (exiting || _isDestroying) {
|
if (exiting || _isDestroying) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
exiting = true
|
exiting = true;
|
||||||
exitAnim.restart()
|
exitAnim.restart();
|
||||||
exitWatchdog.restart()
|
exitWatchdog.restart();
|
||||||
if (NotificationService.removeFromVisibleNotifications)
|
if (NotificationService.removeFromVisibleNotifications)
|
||||||
NotificationService.removeFromVisibleNotifications(win.notificationData)
|
NotificationService.removeFromVisibleNotifications(win.notificationData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function forceExit() {
|
function forceExit() {
|
||||||
if (_isDestroying) {
|
if (_isDestroying) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
_isDestroying = true
|
_isDestroying = true;
|
||||||
exiting = true
|
exiting = true;
|
||||||
visible = false
|
visible = false;
|
||||||
exitWatchdog.stop()
|
exitWatchdog.stop();
|
||||||
finalizeExit("forced")
|
finalizeExit("forced");
|
||||||
}
|
}
|
||||||
|
|
||||||
function finalizeExit(reason) {
|
function finalizeExit(reason) {
|
||||||
if (_finalized) {
|
if (_finalized) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_finalized = true
|
_finalized = true;
|
||||||
_isDestroying = true
|
_isDestroying = true;
|
||||||
exitWatchdog.stop()
|
exitWatchdog.stop();
|
||||||
wrapperConn.enabled = false
|
wrapperConn.enabled = false;
|
||||||
wrapperConn.target = null
|
wrapperConn.target = null;
|
||||||
win.exitFinished()
|
win.exitFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
visible: hasValidData
|
visible: hasValidData
|
||||||
WlrLayershell.layer: {
|
WlrLayershell.layer: {
|
||||||
const envLayer = Quickshell.env("DMS_NOTIFICATION_LAYER")
|
const envLayer = Quickshell.env("DMS_NOTIFICATION_LAYER");
|
||||||
if (envLayer) {
|
if (envLayer) {
|
||||||
switch (envLayer) {
|
switch (envLayer) {
|
||||||
case "bottom":
|
case "bottom":
|
||||||
return WlrLayershell.Bottom
|
return WlrLayershell.Bottom;
|
||||||
case "overlay":
|
case "overlay":
|
||||||
return WlrLayershell.Overlay
|
return WlrLayershell.Overlay;
|
||||||
case "background":
|
case "background":
|
||||||
return WlrLayershell.Background
|
return WlrLayershell.Background;
|
||||||
case "top":
|
case "top":
|
||||||
return WlrLayershell.Top
|
return WlrLayershell.Top;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!notificationData)
|
if (!notificationData)
|
||||||
return WlrLayershell.Top
|
return WlrLayershell.Top;
|
||||||
|
|
||||||
SettingsData.notificationOverlayEnabled
|
SettingsData.notificationOverlayEnabled;
|
||||||
|
|
||||||
const shouldUseOverlay = (SettingsData.notificationOverlayEnabled) || (notificationData.urgency === NotificationUrgency.Critical)
|
const shouldUseOverlay = (SettingsData.notificationOverlayEnabled) || (notificationData.urgency === NotificationUrgency.Critical);
|
||||||
|
|
||||||
return shouldUseOverlay ? WlrLayershell.Overlay : WlrLayershell.Top
|
return shouldUseOverlay ? WlrLayershell.Overlay : WlrLayershell.Top;
|
||||||
}
|
}
|
||||||
WlrLayershell.exclusiveZone: -1
|
WlrLayershell.exclusiveZone: -1
|
||||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||||
@@ -94,32 +93,32 @@ PanelWindow {
|
|||||||
implicitHeight: 122
|
implicitHeight: 122
|
||||||
onHasValidDataChanged: {
|
onHasValidDataChanged: {
|
||||||
if (!hasValidData && !exiting && !_isDestroying) {
|
if (!hasValidData && !exiting && !_isDestroying) {
|
||||||
forceExit()
|
forceExit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (hasValidData) {
|
if (hasValidData) {
|
||||||
Qt.callLater(() => enterX.restart())
|
Qt.callLater(() => enterX.restart());
|
||||||
} else {
|
} else {
|
||||||
forceExit()
|
forceExit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onNotificationDataChanged: {
|
onNotificationDataChanged: {
|
||||||
if (!_isDestroying) {
|
if (!_isDestroying) {
|
||||||
wrapperConn.target = win.notificationData || null
|
wrapperConn.target = win.notificationData || null;
|
||||||
notificationConn.target = (win.notificationData && win.notificationData.notification && win.notificationData.notification.Retainable) || null
|
notificationConn.target = (win.notificationData && win.notificationData.notification && win.notificationData.notification.Retainable) || null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onEntered: {
|
onEntered: {
|
||||||
if (!_isDestroying) {
|
if (!_isDestroying) {
|
||||||
enterDelay.start()
|
enterDelay.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
_isDestroying = true
|
_isDestroying = true;
|
||||||
exitWatchdog.stop()
|
exitWatchdog.stop();
|
||||||
if (notificationData && notificationData.timer) {
|
if (notificationData && notificationData.timer) {
|
||||||
notificationData.timer.stop()
|
notificationData.timer.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,54 +137,66 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getBarInfo() {
|
function getBarInfo() {
|
||||||
if (!screen) return { topBar: 0, bottomBar: 0, leftBar: 0, rightBar: 0 }
|
if (!screen)
|
||||||
|
return {
|
||||||
|
topBar: 0,
|
||||||
|
bottomBar: 0,
|
||||||
|
leftBar: 0,
|
||||||
|
rightBar: 0
|
||||||
|
};
|
||||||
return SettingsData.getAdjacentBarInfo(screen, SettingsData.notificationPopupPosition, {
|
return SettingsData.getAdjacentBarInfo(screen, SettingsData.notificationPopupPosition, {
|
||||||
id: "notification-popup",
|
id: "notification-popup",
|
||||||
screenPreferences: [screen.name],
|
screenPreferences: [screen.name],
|
||||||
autoHide: false
|
autoHide: false
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTopMargin() {
|
function getTopMargin() {
|
||||||
const popupPos = SettingsData.notificationPopupPosition
|
const popupPos = SettingsData.notificationPopupPosition;
|
||||||
const isTop = isTopCenter || popupPos === SettingsData.Position.Top || popupPos === SettingsData.Position.Left
|
const isTop = isTopCenter || popupPos === SettingsData.Position.Top || popupPos === SettingsData.Position.Left;
|
||||||
if (!isTop) return 0
|
if (!isTop)
|
||||||
|
return 0;
|
||||||
|
|
||||||
const barInfo = getBarInfo()
|
const barInfo = getBarInfo();
|
||||||
const base = barInfo.topBar > 0 ? barInfo.topBar : Theme.popupDistance
|
const base = barInfo.topBar > 0 ? barInfo.topBar : Theme.popupDistance;
|
||||||
return base + screenY
|
return base + screenY;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBottomMargin() {
|
function getBottomMargin() {
|
||||||
const popupPos = SettingsData.notificationPopupPosition
|
const popupPos = SettingsData.notificationPopupPosition;
|
||||||
const isBottom = popupPos === SettingsData.Position.Bottom || popupPos === SettingsData.Position.Right
|
const isBottom = popupPos === SettingsData.Position.Bottom || popupPos === SettingsData.Position.Right;
|
||||||
if (!isBottom) return 0
|
if (!isBottom)
|
||||||
|
return 0;
|
||||||
|
|
||||||
const barInfo = getBarInfo()
|
const barInfo = getBarInfo();
|
||||||
const base = barInfo.bottomBar > 0 ? barInfo.bottomBar : Theme.popupDistance
|
const base = barInfo.bottomBar > 0 ? barInfo.bottomBar : Theme.popupDistance;
|
||||||
return base + screenY
|
return base + screenY;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLeftMargin() {
|
function getLeftMargin() {
|
||||||
if (isTopCenter) return (screen.width - implicitWidth) / 2
|
if (isTopCenter)
|
||||||
|
return (screen.width - implicitWidth) / 2;
|
||||||
|
|
||||||
const popupPos = SettingsData.notificationPopupPosition
|
const popupPos = SettingsData.notificationPopupPosition;
|
||||||
const isLeft = popupPos === SettingsData.Position.Left || popupPos === SettingsData.Position.Bottom
|
const isLeft = popupPos === SettingsData.Position.Left || popupPos === SettingsData.Position.Bottom;
|
||||||
if (!isLeft) return 0
|
if (!isLeft)
|
||||||
|
return 0;
|
||||||
|
|
||||||
const barInfo = getBarInfo()
|
const barInfo = getBarInfo();
|
||||||
return barInfo.leftBar > 0 ? barInfo.leftBar : Theme.popupDistance
|
return barInfo.leftBar > 0 ? barInfo.leftBar : Theme.popupDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRightMargin() {
|
function getRightMargin() {
|
||||||
if (isTopCenter) return 0
|
if (isTopCenter)
|
||||||
|
return 0;
|
||||||
|
|
||||||
const popupPos = SettingsData.notificationPopupPosition
|
const popupPos = SettingsData.notificationPopupPosition;
|
||||||
const isRight = popupPos === SettingsData.Position.Top || popupPos === SettingsData.Position.Right
|
const isRight = popupPos === SettingsData.Position.Top || popupPos === SettingsData.Position.Right;
|
||||||
if (!isRight) return 0
|
if (!isRight)
|
||||||
|
return 0;
|
||||||
|
|
||||||
const barInfo = getBarInfo()
|
const barInfo = getBarInfo();
|
||||||
return barInfo.rightBar > 0 ? barInfo.rightBar : Theme.popupDistance
|
return barInfo.rightBar > 0 ? barInfo.rightBar : Theme.popupDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property real dpr: CompositorService.getScreenScale(win.screen)
|
readonly property real dpr: CompositorService.getScreenScale(win.screen)
|
||||||
@@ -201,6 +212,11 @@ PanelWindow {
|
|||||||
height: alignedHeight
|
height: alignedHeight
|
||||||
visible: win.hasValidData
|
visible: win.hasValidData
|
||||||
|
|
||||||
|
property real swipeOffset: 0
|
||||||
|
readonly property real dismissThreshold: isTopCenter ? height * 0.4 : width * 0.35
|
||||||
|
readonly property bool swipeActive: swipeDragHandler.active
|
||||||
|
property bool swipeDismissing: false
|
||||||
|
|
||||||
property real shadowBlurPx: 10
|
property real shadowBlurPx: 10
|
||||||
property real shadowSpreadPx: 0
|
property real shadowSpreadPx: 0
|
||||||
property real shadowBaseAlpha: 0.60
|
property real shadowBaseAlpha: 0.60
|
||||||
@@ -227,8 +243,8 @@ PanelWindow {
|
|||||||
shadowBlur: Math.max(0, Math.min(1, content.shadowBlurPx / bgShadowLayer.blurMax))
|
shadowBlur: Math.max(0, Math.min(1, content.shadowBlurPx / bgShadowLayer.blurMax))
|
||||||
shadowScale: 1 + (2 * content.shadowSpreadPx) / Math.max(1, Math.min(bgShadowLayer.width, bgShadowLayer.height))
|
shadowScale: 1 + (2 * content.shadowSpreadPx) / Math.max(1, Math.min(bgShadowLayer.width, bgShadowLayer.height))
|
||||||
shadowColor: {
|
shadowColor: {
|
||||||
const baseColor = Theme.isLightMode ? Qt.rgba(0, 0, 0, 1) : Theme.surfaceContainerHighest
|
const baseColor = Theme.isLightMode ? Qt.rgba(0, 0, 0, 1) : Theme.surfaceContainerHighest;
|
||||||
return Theme.withAlpha(baseColor, content.effectiveShadowAlpha)
|
return Theme.withAlpha(baseColor, content.effectiveShadowAlpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,14 +266,46 @@ PanelWindow {
|
|||||||
startX: backgroundShape.radius
|
startX: backgroundShape.radius
|
||||||
startY: 0
|
startY: 0
|
||||||
|
|
||||||
PathLine { x: backgroundShape.width - backgroundShape.radius; y: 0 }
|
PathLine {
|
||||||
PathQuad { x: backgroundShape.width; y: backgroundShape.radius; controlX: backgroundShape.width; controlY: 0 }
|
x: backgroundShape.width - backgroundShape.radius
|
||||||
PathLine { x: backgroundShape.width; y: backgroundShape.height - backgroundShape.radius }
|
y: 0
|
||||||
PathQuad { x: backgroundShape.width - backgroundShape.radius; y: backgroundShape.height; controlX: backgroundShape.width; controlY: backgroundShape.height }
|
}
|
||||||
PathLine { x: backgroundShape.radius; y: backgroundShape.height }
|
PathQuad {
|
||||||
PathQuad { x: 0; y: backgroundShape.height - backgroundShape.radius; controlX: 0; controlY: backgroundShape.height }
|
x: backgroundShape.width
|
||||||
PathLine { x: 0; y: backgroundShape.radius }
|
y: backgroundShape.radius
|
||||||
PathQuad { x: backgroundShape.radius; y: 0; controlX: 0; controlY: 0 }
|
controlX: backgroundShape.width
|
||||||
|
controlY: 0
|
||||||
|
}
|
||||||
|
PathLine {
|
||||||
|
x: backgroundShape.width
|
||||||
|
y: backgroundShape.height - backgroundShape.radius
|
||||||
|
}
|
||||||
|
PathQuad {
|
||||||
|
x: backgroundShape.width - backgroundShape.radius
|
||||||
|
y: backgroundShape.height
|
||||||
|
controlX: backgroundShape.width
|
||||||
|
controlY: backgroundShape.height
|
||||||
|
}
|
||||||
|
PathLine {
|
||||||
|
x: backgroundShape.radius
|
||||||
|
y: backgroundShape.height
|
||||||
|
}
|
||||||
|
PathQuad {
|
||||||
|
x: 0
|
||||||
|
y: backgroundShape.height - backgroundShape.radius
|
||||||
|
controlX: 0
|
||||||
|
controlY: backgroundShape.height
|
||||||
|
}
|
||||||
|
PathLine {
|
||||||
|
x: 0
|
||||||
|
y: backgroundShape.radius
|
||||||
|
}
|
||||||
|
PathQuad {
|
||||||
|
x: backgroundShape.radius
|
||||||
|
y: 0
|
||||||
|
controlX: 0
|
||||||
|
controlY: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,26 +366,26 @@ PanelWindow {
|
|||||||
|
|
||||||
imageSource: {
|
imageSource: {
|
||||||
if (!notificationData)
|
if (!notificationData)
|
||||||
return ""
|
return "";
|
||||||
|
|
||||||
if (hasNotificationImage)
|
if (hasNotificationImage)
|
||||||
return notificationData.cleanImage || ""
|
return notificationData.cleanImage || "";
|
||||||
|
|
||||||
if (notificationData.appIcon) {
|
if (notificationData.appIcon) {
|
||||||
const appIcon = notificationData.appIcon
|
const appIcon = notificationData.appIcon;
|
||||||
if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://"))
|
if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://"))
|
||||||
return appIcon
|
return appIcon;
|
||||||
|
|
||||||
return Quickshell.iconPath(appIcon, true)
|
return Quickshell.iconPath(appIcon, true);
|
||||||
}
|
}
|
||||||
return ""
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
hasImage: hasNotificationImage
|
hasImage: hasNotificationImage
|
||||||
fallbackIcon: ""
|
fallbackIcon: ""
|
||||||
fallbackText: {
|
fallbackText: {
|
||||||
const appName = notificationData?.appName || "?"
|
const appName = notificationData?.appName || "?";
|
||||||
return appName.charAt(0).toUpperCase()
|
return appName.charAt(0).toUpperCase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,14 +415,14 @@ PanelWindow {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
text: {
|
text: {
|
||||||
if (!notificationData)
|
if (!notificationData)
|
||||||
return ""
|
return "";
|
||||||
|
|
||||||
const appName = notificationData.appName || ""
|
const appName = notificationData.appName || "";
|
||||||
const timeStr = notificationData.timeStr || ""
|
const timeStr = notificationData.timeStr || "";
|
||||||
if (timeStr.length > 0)
|
if (timeStr.length > 0)
|
||||||
return appName + " • " + timeStr
|
return appName + " • " + timeStr;
|
||||||
else
|
else
|
||||||
return appName
|
return appName;
|
||||||
}
|
}
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
@@ -405,8 +453,8 @@ PanelWindow {
|
|||||||
visible: text.length > 0
|
visible: text.length > 0
|
||||||
linkColor: Theme.primary
|
linkColor: Theme.primary
|
||||||
onLinkActivated: link => {
|
onLinkActivated: link => {
|
||||||
return Qt.openUrlExternally(link)
|
return Qt.openUrlExternally(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -432,7 +480,7 @@ PanelWindow {
|
|||||||
z: 15
|
z: 15
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (notificationData && !win.exiting)
|
if (notificationData && !win.exiting)
|
||||||
notificationData.popup = false
|
notificationData.popup = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,10 +523,10 @@ PanelWindow {
|
|||||||
onExited: parent.isHovered = false
|
onExited: parent.isHovered = false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (modelData && modelData.invoke)
|
if (modelData && modelData.invoke)
|
||||||
modelData.invoke()
|
modelData.invoke();
|
||||||
|
|
||||||
if (notificationData && !win.exiting)
|
if (notificationData && !win.exiting)
|
||||||
notificationData.popup = false
|
notificationData.popup = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -519,7 +567,7 @@ PanelWindow {
|
|||||||
onExited: clearButton.isHovered = false
|
onExited: clearButton.isHovered = false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (notificationData && !win.exiting)
|
if (notificationData && !win.exiting)
|
||||||
NotificationService.dismissNotification(notificationData)
|
NotificationService.dismissNotification(notificationData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -534,40 +582,108 @@ PanelWindow {
|
|||||||
z: -1
|
z: -1
|
||||||
onEntered: {
|
onEntered: {
|
||||||
if (notificationData && notificationData.timer)
|
if (notificationData && notificationData.timer)
|
||||||
notificationData.timer.stop()
|
notificationData.timer.stop();
|
||||||
}
|
}
|
||||||
onExited: {
|
onExited: {
|
||||||
if (notificationData && notificationData.popup && notificationData.timer)
|
if (notificationData && notificationData.popup && notificationData.timer)
|
||||||
notificationData.timer.restart()
|
notificationData.timer.restart();
|
||||||
}
|
}
|
||||||
onClicked: (mouse) => {
|
onClicked: mouse => {
|
||||||
if (!notificationData || win.exiting)
|
if (!notificationData || win.exiting)
|
||||||
return
|
return;
|
||||||
|
|
||||||
if (mouse.button === Qt.RightButton) {
|
if (mouse.button === Qt.RightButton) {
|
||||||
NotificationService.dismissNotification(notificationData)
|
NotificationService.dismissNotification(notificationData);
|
||||||
} else if (mouse.button === Qt.LeftButton) {
|
} else if (mouse.button === Qt.LeftButton) {
|
||||||
if (notificationData.actions && notificationData.actions.length > 0) {
|
if (notificationData.actions && notificationData.actions.length > 0) {
|
||||||
notificationData.actions[0].invoke()
|
notificationData.actions[0].invoke();
|
||||||
NotificationService.dismissNotification(notificationData)
|
NotificationService.dismissNotification(notificationData);
|
||||||
} else {
|
} else {
|
||||||
notificationData.popup = false
|
notificationData.popup = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transform: Translate {
|
DragHandler {
|
||||||
id: tx
|
id: swipeDragHandler
|
||||||
|
target: null
|
||||||
|
xAxis.enabled: !isTopCenter
|
||||||
|
yAxis.enabled: isTopCenter
|
||||||
|
|
||||||
x: {
|
onActiveChanged: {
|
||||||
if (isTopCenter) return 0
|
if (active || win.exiting || content.swipeDismissing)
|
||||||
const isLeft = SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom
|
return;
|
||||||
return isLeft ? -Anims.slidePx : Anims.slidePx
|
|
||||||
|
if (Math.abs(content.swipeOffset) > content.dismissThreshold) {
|
||||||
|
content.swipeDismissing = true;
|
||||||
|
swipeDismissAnim.start();
|
||||||
|
} else {
|
||||||
|
content.swipeOffset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTranslationChanged: {
|
||||||
|
if (win.exiting)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const raw = isTopCenter ? translation.y : translation.x;
|
||||||
|
if (isTopCenter) {
|
||||||
|
content.swipeOffset = Math.min(0, raw);
|
||||||
|
} else {
|
||||||
|
const isLeft = SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom;
|
||||||
|
content.swipeOffset = isLeft ? Math.min(0, raw) : Math.max(0, raw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
y: isTopCenter ? -Anims.slidePx : 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opacity: 1 - Math.abs(content.swipeOffset) / (isTopCenter ? content.height : content.width * 0.6)
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
enabled: !content.swipeActive
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on swipeOffset {
|
||||||
|
enabled: !content.swipeActive && !content.swipeDismissing
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
id: swipeDismissAnim
|
||||||
|
target: content
|
||||||
|
property: "swipeOffset"
|
||||||
|
to: isTopCenter ? -content.height : (SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom ? -content.width : content.width)
|
||||||
|
duration: Anims.durShort
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
onStopped: {
|
||||||
|
NotificationService.dismissNotification(notificationData);
|
||||||
|
win.forceExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transform: [
|
||||||
|
Translate {
|
||||||
|
id: swipeTx
|
||||||
|
x: isTopCenter ? 0 : content.swipeOffset
|
||||||
|
y: isTopCenter ? content.swipeOffset : 0
|
||||||
|
},
|
||||||
|
Translate {
|
||||||
|
id: tx
|
||||||
|
x: {
|
||||||
|
if (isTopCenter)
|
||||||
|
return 0;
|
||||||
|
const isLeft = SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom;
|
||||||
|
return isLeft ? -Anims.slidePx : Anims.slidePx;
|
||||||
|
}
|
||||||
|
y: isTopCenter ? -Anims.slidePx : 0
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -576,9 +692,10 @@ PanelWindow {
|
|||||||
target: tx
|
target: tx
|
||||||
property: isTopCenter ? "y" : "x"
|
property: isTopCenter ? "y" : "x"
|
||||||
from: {
|
from: {
|
||||||
if (isTopCenter) return -Anims.slidePx
|
if (isTopCenter)
|
||||||
const isLeft = SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom
|
return -Anims.slidePx;
|
||||||
return isLeft ? -Anims.slidePx : Anims.slidePx
|
const isLeft = SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom;
|
||||||
|
return isLeft ? -Anims.slidePx : Anims.slidePx;
|
||||||
}
|
}
|
||||||
to: 0
|
to: 0
|
||||||
duration: Anims.durMed
|
duration: Anims.durMed
|
||||||
@@ -587,9 +704,11 @@ PanelWindow {
|
|||||||
onStopped: {
|
onStopped: {
|
||||||
if (!win.exiting && !win._isDestroying) {
|
if (!win.exiting && !win._isDestroying) {
|
||||||
if (isTopCenter) {
|
if (isTopCenter) {
|
||||||
if (Math.abs(tx.y) < 0.5) win.entered()
|
if (Math.abs(tx.y) < 0.5)
|
||||||
|
win.entered();
|
||||||
} else {
|
} else {
|
||||||
if (Math.abs(tx.x) < 0.5) win.entered()
|
if (Math.abs(tx.x) < 0.5)
|
||||||
|
win.entered();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -605,9 +724,10 @@ PanelWindow {
|
|||||||
property: isTopCenter ? "y" : "x"
|
property: isTopCenter ? "y" : "x"
|
||||||
from: 0
|
from: 0
|
||||||
to: {
|
to: {
|
||||||
if (isTopCenter) return -Anims.slidePx
|
if (isTopCenter)
|
||||||
const isLeft = SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom
|
return -Anims.slidePx;
|
||||||
return isLeft ? -Anims.slidePx : Anims.slidePx
|
const isLeft = SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom;
|
||||||
|
return isLeft ? -Anims.slidePx : Anims.slidePx;
|
||||||
}
|
}
|
||||||
duration: Anims.durShort
|
duration: Anims.durShort
|
||||||
easing.type: Easing.BezierSpline
|
easing.type: Easing.BezierSpline
|
||||||
@@ -640,10 +760,9 @@ PanelWindow {
|
|||||||
|
|
||||||
function onPopupChanged() {
|
function onPopupChanged() {
|
||||||
if (!win.notificationData || win._isDestroying)
|
if (!win.notificationData || win._isDestroying)
|
||||||
return
|
return;
|
||||||
|
|
||||||
if (!win.notificationData.popup && !win.exiting)
|
if (!win.notificationData.popup && !win.exiting)
|
||||||
startExit()
|
startExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
target: win.notificationData || null
|
target: win.notificationData || null
|
||||||
@@ -656,7 +775,7 @@ PanelWindow {
|
|||||||
|
|
||||||
function onDropped() {
|
function onDropped() {
|
||||||
if (!win._isDestroying && !win.exiting)
|
if (!win._isDestroying && !win.exiting)
|
||||||
forceExit()
|
forceExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
target: (win.notificationData && win.notificationData.notification && win.notificationData.notification.Retainable) || null
|
target: (win.notificationData && win.notificationData.notification && win.notificationData.notification.Retainable) || null
|
||||||
@@ -671,7 +790,7 @@ PanelWindow {
|
|||||||
repeat: false
|
repeat: false
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (notificationData && notificationData.timer && !exiting && !_isDestroying)
|
if (notificationData && notificationData.timer && !exiting && !_isDestroying)
|
||||||
notificationData.timer.start()
|
notificationData.timer.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user