mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-30 00:12:50 -05:00
notifications: fix redundant height animation
This commit is contained in:
@@ -9,6 +9,7 @@ DankListView {
|
|||||||
property var keyboardController: null
|
property var keyboardController: null
|
||||||
property bool keyboardActive: false
|
property bool keyboardActive: false
|
||||||
property bool autoScrollDisabled: false
|
property bool autoScrollDisabled: false
|
||||||
|
property bool isAnimatingExpansion: false
|
||||||
property alias count: listView.count
|
property alias count: listView.count
|
||||||
property alias listContentHeight: listView.contentHeight
|
property alias listContentHeight: listView.contentHeight
|
||||||
|
|
||||||
@@ -29,8 +30,19 @@ DankListView {
|
|||||||
Timer {
|
Timer {
|
||||||
id: positionPreservationTimer
|
id: positionPreservationTimer
|
||||||
interval: 200
|
interval: 200
|
||||||
running: keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled
|
running: keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled && !isAnimatingExpansion
|
||||||
repeat: true
|
repeat: true
|
||||||
|
onTriggered: {
|
||||||
|
if (keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled && !isAnimatingExpansion) {
|
||||||
|
keyboardController.ensureVisible();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: expansionEnsureVisibleTimer
|
||||||
|
interval: Theme.mediumDuration + 50
|
||||||
|
repeat: false
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled) {
|
if (keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled) {
|
||||||
keyboardController.ensureVisible();
|
keyboardController.ensureVisible();
|
||||||
@@ -68,14 +80,7 @@ DankListView {
|
|||||||
|
|
||||||
width: ListView.view.width
|
width: ListView.view.width
|
||||||
height: isDismissing ? 0 : notificationCard.height
|
height: isDismissing ? 0 : notificationCard.height
|
||||||
clip: true
|
clip: isDismissing
|
||||||
|
|
||||||
Behavior on height {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationCard {
|
NotificationCard {
|
||||||
id: notificationCard
|
id: notificationCard
|
||||||
@@ -84,6 +89,23 @@ DankListView {
|
|||||||
notificationGroup: modelData
|
notificationGroup: modelData
|
||||||
keyboardNavigationActive: listView.keyboardActive
|
keyboardNavigationActive: listView.keyboardActive
|
||||||
opacity: 1 - Math.abs(delegateRoot.swipeOffset) / (delegateRoot.width * 0.5)
|
opacity: 1 - Math.abs(delegateRoot.swipeOffset) / (delegateRoot.width * 0.5)
|
||||||
|
onIsAnimatingChanged: {
|
||||||
|
if (isAnimating) {
|
||||||
|
listView.isAnimatingExpansion = true;
|
||||||
|
} else {
|
||||||
|
Qt.callLater(() => {
|
||||||
|
let anyAnimating = false;
|
||||||
|
for (let i = 0; i < listView.count; i++) {
|
||||||
|
const item = listView.itemAtIndex(i);
|
||||||
|
if (item && item.children[0] && item.children[0].isAnimating) {
|
||||||
|
anyAnimating = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listView.isAnimatingExpansion = anyAnimating;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isGroupSelected: {
|
isGroupSelected: {
|
||||||
if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive)
|
if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive)
|
||||||
@@ -173,23 +195,15 @@ DankListView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onExpandedGroupsChanged() {
|
function onExpandedGroupsChanged() {
|
||||||
if (keyboardController && keyboardController.keyboardNavigationActive) {
|
if (!keyboardController || !keyboardController.keyboardNavigationActive)
|
||||||
Qt.callLater(() => {
|
return;
|
||||||
if (!autoScrollDisabled) {
|
expansionEnsureVisibleTimer.restart();
|
||||||
keyboardController.ensureVisible();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onExpandedMessagesChanged() {
|
function onExpandedMessagesChanged() {
|
||||||
if (keyboardController && keyboardController.keyboardNavigationActive) {
|
if (!keyboardController || !keyboardController.keyboardNavigationActive)
|
||||||
Qt.callLater(() => {
|
return;
|
||||||
if (!autoScrollDisabled) {
|
expansionEnsureVisibleTimer.restart();
|
||||||
keyboardController.ensureVisible();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Effects
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Widgets
|
|
||||||
import Quickshell.Services.Notifications
|
import Quickshell.Services.Notifications
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
@@ -13,9 +10,9 @@ Rectangle {
|
|||||||
|
|
||||||
property var notificationGroup
|
property var notificationGroup
|
||||||
property bool expanded: (NotificationService.expandedGroups[notificationGroup && notificationGroup.key] || false)
|
property bool expanded: (NotificationService.expandedGroups[notificationGroup && notificationGroup.key] || false)
|
||||||
property bool descriptionExpanded: (NotificationService.expandedMessages[(notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.notification
|
property bool descriptionExpanded: (NotificationService.expandedMessages[(notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.notification && notificationGroup.latestNotification.notification.id) ? (notificationGroup.latestNotification.notification.id + "_desc") : ""] || false)
|
||||||
&& notificationGroup.latestNotification.notification.id) ? (notificationGroup.latestNotification.notification.id + "_desc") : ""] || false)
|
|
||||||
property bool userInitiatedExpansion: false
|
property bool userInitiatedExpansion: false
|
||||||
|
property bool isAnimating: false
|
||||||
|
|
||||||
property bool isGroupSelected: false
|
property bool isGroupSelected: false
|
||||||
property int selectedNotificationIndex: -1
|
property int selectedNotificationIndex: -1
|
||||||
@@ -24,13 +21,13 @@ Rectangle {
|
|||||||
width: parent ? parent.width : 400
|
width: parent ? parent.width : 400
|
||||||
height: {
|
height: {
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
return expandedContent.height + 28
|
return expandedContent.height + 28;
|
||||||
}
|
}
|
||||||
const baseHeight = 116
|
const baseHeight = 116;
|
||||||
if (descriptionExpanded) {
|
if (descriptionExpanded) {
|
||||||
return baseHeight + descriptionText.contentHeight - (descriptionText.font.pixelSize * 1.2 * 2)
|
return baseHeight + descriptionText.contentHeight - (descriptionText.font.pixelSize * 1.2 * 2);
|
||||||
}
|
}
|
||||||
return baseHeight
|
return baseHeight;
|
||||||
}
|
}
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
|
|
||||||
@@ -43,36 +40,36 @@ Rectangle {
|
|||||||
|
|
||||||
color: {
|
color: {
|
||||||
if (isGroupSelected && keyboardNavigationActive) {
|
if (isGroupSelected && keyboardNavigationActive) {
|
||||||
return Theme.primaryPressed
|
return Theme.primaryPressed;
|
||||||
}
|
}
|
||||||
if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) {
|
if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) {
|
||||||
return Theme.primaryHoverLight
|
return Theme.primaryHoverLight;
|
||||||
}
|
}
|
||||||
return Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
|
return Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency);
|
||||||
}
|
}
|
||||||
border.color: {
|
border.color: {
|
||||||
if (isGroupSelected && keyboardNavigationActive) {
|
if (isGroupSelected && keyboardNavigationActive) {
|
||||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.5)
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.5);
|
||||||
}
|
}
|
||||||
if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) {
|
if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) {
|
||||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.2)
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.2);
|
||||||
}
|
}
|
||||||
if (notificationGroup?.latestNotification?.urgency === NotificationUrgency.Critical) {
|
if (notificationGroup?.latestNotification?.urgency === NotificationUrgency.Critical) {
|
||||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3)
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3);
|
||||||
}
|
}
|
||||||
return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.05)
|
return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.05);
|
||||||
}
|
}
|
||||||
border.width: {
|
border.width: {
|
||||||
if (isGroupSelected && keyboardNavigationActive) {
|
if (isGroupSelected && keyboardNavigationActive) {
|
||||||
return 1.5
|
return 1.5;
|
||||||
}
|
}
|
||||||
if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) {
|
if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) {
|
||||||
return 1
|
return 1;
|
||||||
}
|
}
|
||||||
if (notificationGroup?.latestNotification?.urgency === NotificationUrgency.Critical) {
|
if (notificationGroup?.latestNotification?.urgency === NotificationUrgency.Critical) {
|
||||||
return 2
|
return 2;
|
||||||
}
|
}
|
||||||
return 1
|
return 1;
|
||||||
}
|
}
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
@@ -121,21 +118,21 @@ Rectangle {
|
|||||||
|
|
||||||
imageSource: {
|
imageSource: {
|
||||||
if (hasNotificationImage)
|
if (hasNotificationImage)
|
||||||
return notificationGroup.latestNotification.cleanImage
|
return notificationGroup.latestNotification.cleanImage;
|
||||||
if (notificationGroup?.latestNotification?.appIcon) {
|
if (notificationGroup?.latestNotification?.appIcon) {
|
||||||
const appIcon = notificationGroup.latestNotification.appIcon
|
const appIcon = notificationGroup.latestNotification.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 = notificationGroup?.appName || "?"
|
const appName = notificationGroup?.appName || "?";
|
||||||
return appName.charAt(0).toUpperCase()
|
return appName.charAt(0).toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -195,9 +192,9 @@ Rectangle {
|
|||||||
StyledText {
|
StyledText {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: {
|
text: {
|
||||||
const timeStr = (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.timeStr) || ""
|
const timeStr = (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.timeStr) || "";
|
||||||
const appName = (notificationGroup && notificationGroup.appName) || ""
|
const appName = (notificationGroup && notificationGroup.appName) || "";
|
||||||
return timeStr.length > 0 ? `${appName} • ${timeStr}` : appName
|
return timeStr.length > 0 ? `${appName} • ${timeStr}` : appName;
|
||||||
}
|
}
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
@@ -238,24 +235,23 @@ Rectangle {
|
|||||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : (parent.hasMoreText || descriptionExpanded) ? Qt.PointingHandCursor : Qt.ArrowCursor
|
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : (parent.hasMoreText || descriptionExpanded) ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
|
|
||||||
onClicked: mouse => {
|
onClicked: mouse => {
|
||||||
if (!parent.hoveredLink && (parent.hasMoreText || descriptionExpanded)) {
|
if (!parent.hoveredLink && (parent.hasMoreText || descriptionExpanded)) {
|
||||||
const messageId = (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.notification
|
const messageId = (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.notification && notificationGroup.latestNotification.notification.id) ? (notificationGroup.latestNotification.notification.id + "_desc") : "";
|
||||||
&& notificationGroup.latestNotification.notification.id) ? (notificationGroup.latestNotification.notification.id + "_desc") : ""
|
NotificationService.toggleMessageExpansion(messageId);
|
||||||
NotificationService.toggleMessageExpansion(messageId)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
propagateComposedEvents: true
|
propagateComposedEvents: true
|
||||||
onPressed: mouse => {
|
onPressed: mouse => {
|
||||||
if (parent.hoveredLink) {
|
if (parent.hoveredLink) {
|
||||||
mouse.accepted = false
|
mouse.accepted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onReleased: mouse => {
|
onReleased: mouse => {
|
||||||
if (parent.hoveredLink) {
|
if (parent.hoveredLink) {
|
||||||
mouse.accepted = false
|
mouse.accepted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,15 +331,15 @@ Rectangle {
|
|||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: {
|
height: {
|
||||||
const baseHeight = 120
|
const baseHeight = 120;
|
||||||
if (messageExpanded) {
|
if (messageExpanded) {
|
||||||
const twoLineHeight = bodyText.font.pixelSize * 1.2 * 2
|
const twoLineHeight = bodyText.font.pixelSize * 1.2 * 2;
|
||||||
if (bodyText.implicitHeight > twoLineHeight + 2) {
|
if (bodyText.implicitHeight > twoLineHeight + 2) {
|
||||||
const extraHeight = bodyText.implicitHeight - twoLineHeight
|
const extraHeight = bodyText.implicitHeight - twoLineHeight;
|
||||||
return baseHeight + extraHeight
|
return baseHeight + extraHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return baseHeight
|
return baseHeight;
|
||||||
}
|
}
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: isSelected ? Theme.primaryPressed : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
|
color: isSelected ? Theme.primaryPressed : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
|
||||||
@@ -379,23 +375,23 @@ Rectangle {
|
|||||||
|
|
||||||
imageSource: {
|
imageSource: {
|
||||||
if (hasNotificationImage)
|
if (hasNotificationImage)
|
||||||
return modelData.cleanImage
|
return modelData.cleanImage;
|
||||||
|
|
||||||
if (modelData?.appIcon) {
|
if (modelData?.appIcon) {
|
||||||
const appIcon = modelData.appIcon
|
const appIcon = modelData.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 "";
|
||||||
}
|
}
|
||||||
|
|
||||||
fallbackIcon: ""
|
fallbackIcon: ""
|
||||||
|
|
||||||
fallbackText: {
|
fallbackText: {
|
||||||
const appName = modelData?.appName || "?"
|
const appName = modelData?.appName || "?";
|
||||||
return appName.charAt(0).toUpperCase()
|
return appName.charAt(0).toUpperCase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,22 +452,22 @@ Rectangle {
|
|||||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : (bodyText.hasMoreText || messageExpanded) ? Qt.PointingHandCursor : Qt.ArrowCursor
|
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : (bodyText.hasMoreText || messageExpanded) ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
|
|
||||||
onClicked: mouse => {
|
onClicked: mouse => {
|
||||||
if (!parent.hoveredLink && (bodyText.hasMoreText || messageExpanded)) {
|
if (!parent.hoveredLink && (bodyText.hasMoreText || messageExpanded)) {
|
||||||
NotificationService.toggleMessageExpansion(modelData?.notification?.id || "")
|
NotificationService.toggleMessageExpansion(modelData?.notification?.id || "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
propagateComposedEvents: true
|
propagateComposedEvents: true
|
||||||
onPressed: mouse => {
|
onPressed: mouse => {
|
||||||
if (parent.hoveredLink) {
|
if (parent.hoveredLink) {
|
||||||
mouse.accepted = false
|
mouse.accepted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onReleased: mouse => {
|
onReleased: mouse => {
|
||||||
if (parent.hoveredLink) {
|
if (parent.hoveredLink) {
|
||||||
mouse.accepted = false
|
mouse.accepted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -502,11 +498,11 @@ Rectangle {
|
|||||||
StyledText {
|
StyledText {
|
||||||
id: actionText
|
id: actionText
|
||||||
text: {
|
text: {
|
||||||
const baseText = modelData.text || "View"
|
const baseText = modelData.text || "View";
|
||||||
if (keyboardNavigationActive && (isGroupSelected || selectedNotificationIndex >= 0)) {
|
if (keyboardNavigationActive && (isGroupSelected || selectedNotificationIndex >= 0)) {
|
||||||
return `${baseText} (${index + 1})`
|
return `${baseText} (${index + 1})`;
|
||||||
}
|
}
|
||||||
return baseText
|
return baseText;
|
||||||
}
|
}
|
||||||
color: parent.isHovered ? Theme.primary : Theme.surfaceVariantText
|
color: parent.isHovered ? Theme.primary : Theme.surfaceVariantText
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
@@ -523,7 +519,7 @@ Rectangle {
|
|||||||
onExited: parent.isHovered = false
|
onExited: parent.isHovered = false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (modelData && modelData.invoke) {
|
if (modelData && modelData.invoke) {
|
||||||
modelData.invoke()
|
modelData.invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -587,11 +583,11 @@ Rectangle {
|
|||||||
StyledText {
|
StyledText {
|
||||||
id: actionText
|
id: actionText
|
||||||
text: {
|
text: {
|
||||||
const baseText = modelData.text || "View"
|
const baseText = modelData.text || "View";
|
||||||
if (keyboardNavigationActive && isGroupSelected) {
|
if (keyboardNavigationActive && isGroupSelected) {
|
||||||
return `${baseText} (${index + 1})`
|
return `${baseText} (${index + 1})`;
|
||||||
}
|
}
|
||||||
return baseText
|
return baseText;
|
||||||
}
|
}
|
||||||
color: parent.isHovered ? Theme.primary : Theme.surfaceVariantText
|
color: parent.isHovered ? Theme.primary : Theme.surfaceVariantText
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
@@ -608,7 +604,7 @@ Rectangle {
|
|||||||
onExited: parent.isHovered = false
|
onExited: parent.isHovered = false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (modelData && modelData.invoke) {
|
if (modelData && modelData.invoke) {
|
||||||
modelData.invoke()
|
modelData.invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -654,8 +650,8 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: !expanded && (notificationGroup?.count || 0) > 1 && !descriptionExpanded
|
visible: !expanded && (notificationGroup?.count || 0) > 1 && !descriptionExpanded
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.userInitiatedExpansion = true
|
root.userInitiatedExpansion = true;
|
||||||
NotificationService.toggleGroupExpansion(notificationGroup?.key || "")
|
NotificationService.toggleGroupExpansion(notificationGroup?.key || "");
|
||||||
}
|
}
|
||||||
z: -1
|
z: -1
|
||||||
}
|
}
|
||||||
@@ -677,8 +673,8 @@ Rectangle {
|
|||||||
iconSize: 18
|
iconSize: 18
|
||||||
buttonSize: 28
|
buttonSize: 28
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.userInitiatedExpansion = true
|
root.userInitiatedExpansion = true;
|
||||||
NotificationService.toggleGroupExpansion(notificationGroup?.key || "")
|
NotificationService.toggleGroupExpansion(notificationGroup?.key || "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -697,7 +693,14 @@ Rectangle {
|
|||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
onFinished: root.userInitiatedExpansion = false
|
onRunningChanged: {
|
||||||
|
if (running) {
|
||||||
|
root.isAnimating = true;
|
||||||
|
} else {
|
||||||
|
root.isAnimating = false;
|
||||||
|
root.userInitiatedExpansion = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Common
|
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
@@ -23,530 +22,518 @@ QtObject {
|
|||||||
property bool isRebuilding: false
|
property bool isRebuilding: false
|
||||||
|
|
||||||
function rebuildFlatNavigation() {
|
function rebuildFlatNavigation() {
|
||||||
isRebuilding = true
|
isRebuilding = true;
|
||||||
|
|
||||||
const nav = []
|
const nav = [];
|
||||||
const groups = NotificationService.groupedNotifications
|
const groups = NotificationService.groupedNotifications;
|
||||||
|
|
||||||
for (var i = 0; i < groups.length; i++) {
|
for (var i = 0; i < groups.length; i++) {
|
||||||
const group = groups[i]
|
const group = groups[i];
|
||||||
const isExpanded = NotificationService.expandedGroups[group.key] || false
|
const isExpanded = NotificationService.expandedGroups[group.key] || false;
|
||||||
|
|
||||||
nav.push({
|
nav.push({
|
||||||
"type": "group",
|
"type": "group",
|
||||||
"groupIndex": i,
|
"groupIndex": i,
|
||||||
"notificationIndex": -1,
|
"notificationIndex": -1,
|
||||||
"groupKey": group.key,
|
"groupKey": group.key,
|
||||||
"notificationId": ""
|
"notificationId": ""
|
||||||
})
|
});
|
||||||
|
|
||||||
if (isExpanded) {
|
if (isExpanded) {
|
||||||
const notifications = group.notifications || []
|
const notifications = group.notifications || [];
|
||||||
const maxNotifications = Math.min(notifications.length, 10)
|
const maxNotifications = Math.min(notifications.length, 10);
|
||||||
for (var j = 0; j < maxNotifications; j++) {
|
for (var j = 0; j < maxNotifications; j++) {
|
||||||
const notifId = String(notifications[j] && notifications[j].notification && notifications[j].notification.id ? notifications[j].notification.id : "")
|
const notifId = String(notifications[j] && notifications[j].notification && notifications[j].notification.id ? notifications[j].notification.id : "");
|
||||||
nav.push({
|
nav.push({
|
||||||
"type": "notification",
|
"type": "notification",
|
||||||
"groupIndex": i,
|
"groupIndex": i,
|
||||||
"notificationIndex": j,
|
"notificationIndex": j,
|
||||||
"groupKey": group.key,
|
"groupKey": group.key,
|
||||||
"notificationId": notifId
|
"notificationId": notifId
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flatNavigation = nav
|
flatNavigation = nav;
|
||||||
updateSelectedIndexFromId()
|
updateSelectedIndexFromId();
|
||||||
isRebuilding = false
|
isRebuilding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSelectedIndexFromId() {
|
function updateSelectedIndexFromId() {
|
||||||
if (!keyboardNavigationActive) {
|
if (!keyboardNavigationActive) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < flatNavigation.length; i++) {
|
for (var i = 0; i < flatNavigation.length; i++) {
|
||||||
const item = flatNavigation[i]
|
const item = flatNavigation[i];
|
||||||
|
|
||||||
if (selectedItemType === "group" && item.type === "group" && item.groupKey === selectedGroupKey) {
|
if (selectedItemType === "group" && item.type === "group" && item.groupKey === selectedGroupKey) {
|
||||||
selectedFlatIndex = i
|
selectedFlatIndex = i;
|
||||||
selectionVersion++ // Trigger UI update
|
selectionVersion++; // Trigger UI update
|
||||||
return
|
return;
|
||||||
} else if (selectedItemType === "notification" && item.type === "notification" && String(item.notificationId) === String(selectedNotificationId)) {
|
} else if (selectedItemType === "notification" && item.type === "notification" && String(item.notificationId) === String(selectedNotificationId)) {
|
||||||
selectedFlatIndex = i
|
selectedFlatIndex = i;
|
||||||
selectionVersion++ // Trigger UI update
|
selectionVersion++; // Trigger UI update
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not found, try to find the same group but select the group header instead
|
// If not found, try to find the same group but select the group header instead
|
||||||
if (selectedItemType === "notification") {
|
if (selectedItemType === "notification") {
|
||||||
for (var j = 0; j < flatNavigation.length; j++) {
|
for (var j = 0; j < flatNavigation.length; j++) {
|
||||||
const groupItem = flatNavigation[j]
|
const groupItem = flatNavigation[j];
|
||||||
if (groupItem.type === "group" && groupItem.groupKey === selectedGroupKey) {
|
if (groupItem.type === "group" && groupItem.groupKey === selectedGroupKey) {
|
||||||
selectedFlatIndex = j
|
selectedFlatIndex = j;
|
||||||
selectedItemType = "group"
|
selectedItemType = "group";
|
||||||
selectedNotificationId = ""
|
selectedNotificationId = "";
|
||||||
selectionVersion++ // Trigger UI update
|
selectionVersion++; // Trigger UI update
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If still not found, clamp to valid range and update
|
// If still not found, clamp to valid range and update
|
||||||
if (flatNavigation.length > 0) {
|
if (flatNavigation.length > 0) {
|
||||||
selectedFlatIndex = Math.min(selectedFlatIndex, flatNavigation.length - 1)
|
selectedFlatIndex = Math.min(selectedFlatIndex, flatNavigation.length - 1);
|
||||||
selectedFlatIndex = Math.max(selectedFlatIndex, 0)
|
selectedFlatIndex = Math.max(selectedFlatIndex, 0);
|
||||||
updateSelectedIdFromIndex()
|
updateSelectedIdFromIndex();
|
||||||
selectionVersion++ // Trigger UI update
|
selectionVersion++; // Trigger UI update
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSelectedIdFromIndex() {
|
function updateSelectedIdFromIndex() {
|
||||||
if (selectedFlatIndex >= 0 && selectedFlatIndex < flatNavigation.length) {
|
if (selectedFlatIndex >= 0 && selectedFlatIndex < flatNavigation.length) {
|
||||||
const item = flatNavigation[selectedFlatIndex]
|
const item = flatNavigation[selectedFlatIndex];
|
||||||
selectedItemType = item.type
|
selectedItemType = item.type;
|
||||||
selectedGroupKey = item.groupKey
|
selectedGroupKey = item.groupKey;
|
||||||
selectedNotificationId = item.notificationId
|
selectedNotificationId = item.notificationId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
selectedFlatIndex = 0
|
selectedFlatIndex = 0;
|
||||||
keyboardNavigationActive = false
|
keyboardNavigationActive = false;
|
||||||
showKeyboardHints = false
|
showKeyboardHints = false;
|
||||||
// Reset keyboardActive when modal is reset
|
// Reset keyboardActive when modal is reset
|
||||||
if (listView) {
|
if (listView) {
|
||||||
listView.keyboardActive = false
|
listView.keyboardActive = false;
|
||||||
}
|
}
|
||||||
rebuildFlatNavigation()
|
rebuildFlatNavigation();
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectNext() {
|
function selectNext() {
|
||||||
keyboardNavigationActive = true
|
keyboardNavigationActive = true;
|
||||||
if (flatNavigation.length === 0)
|
if (flatNavigation.length === 0)
|
||||||
return
|
return;
|
||||||
|
|
||||||
// Re-enable auto-scrolling when arrow keys are used
|
// Re-enable auto-scrolling when arrow keys are used
|
||||||
if (listView && listView.enableAutoScroll) {
|
if (listView && listView.enableAutoScroll) {
|
||||||
listView.enableAutoScroll()
|
listView.enableAutoScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedFlatIndex = Math.min(selectedFlatIndex + 1, flatNavigation.length - 1)
|
selectedFlatIndex = Math.min(selectedFlatIndex + 1, flatNavigation.length - 1);
|
||||||
updateSelectedIdFromIndex()
|
updateSelectedIdFromIndex();
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
ensureVisible()
|
ensureVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectNextWrapping() {
|
function selectNextWrapping() {
|
||||||
keyboardNavigationActive = true
|
keyboardNavigationActive = true;
|
||||||
if (flatNavigation.length === 0)
|
if (flatNavigation.length === 0)
|
||||||
return
|
return;
|
||||||
|
|
||||||
// Re-enable auto-scrolling when arrow keys are used
|
// Re-enable auto-scrolling when arrow keys are used
|
||||||
if (listView && listView.enableAutoScroll) {
|
if (listView && listView.enableAutoScroll) {
|
||||||
listView.enableAutoScroll()
|
listView.enableAutoScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedFlatIndex = (selectedFlatIndex + 1) % flatNavigation.length
|
selectedFlatIndex = (selectedFlatIndex + 1) % flatNavigation.length;
|
||||||
updateSelectedIdFromIndex()
|
updateSelectedIdFromIndex();
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
ensureVisible()
|
ensureVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectPrevious() {
|
function selectPrevious() {
|
||||||
keyboardNavigationActive = true
|
keyboardNavigationActive = true;
|
||||||
if (flatNavigation.length === 0)
|
if (flatNavigation.length === 0)
|
||||||
return
|
return;
|
||||||
|
|
||||||
// Re-enable auto-scrolling when arrow keys are used
|
// Re-enable auto-scrolling when arrow keys are used
|
||||||
if (listView && listView.enableAutoScroll) {
|
if (listView && listView.enableAutoScroll) {
|
||||||
listView.enableAutoScroll()
|
listView.enableAutoScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedFlatIndex = Math.max(selectedFlatIndex - 1, 0)
|
selectedFlatIndex = Math.max(selectedFlatIndex - 1, 0);
|
||||||
updateSelectedIdFromIndex()
|
updateSelectedIdFromIndex();
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
ensureVisible()
|
ensureVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleGroupExpanded() {
|
function toggleGroupExpanded() {
|
||||||
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
|
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
|
||||||
return
|
return;
|
||||||
|
const currentItem = flatNavigation[selectedFlatIndex];
|
||||||
const currentItem = flatNavigation[selectedFlatIndex]
|
const groups = NotificationService.groupedNotifications;
|
||||||
const groups = NotificationService.groupedNotifications
|
const group = groups[currentItem.groupIndex];
|
||||||
const group = groups[currentItem.groupIndex]
|
|
||||||
if (!group)
|
if (!group)
|
||||||
return
|
return;
|
||||||
|
|
||||||
// Prevent expanding groups with < 2 notifications
|
// Prevent expanding groups with < 2 notifications
|
||||||
const notificationCount = group.notifications ? group.notifications.length : 0
|
const notificationCount = group.notifications ? group.notifications.length : 0;
|
||||||
if (notificationCount < 2)
|
if (notificationCount < 2)
|
||||||
return
|
return;
|
||||||
|
const wasExpanded = NotificationService.expandedGroups[group.key] || false;
|
||||||
|
const groupIndex = currentItem.groupIndex;
|
||||||
|
|
||||||
const wasExpanded = NotificationService.expandedGroups[group.key] || false
|
isTogglingGroup = true;
|
||||||
const groupIndex = currentItem.groupIndex
|
NotificationService.toggleGroupExpansion(group.key);
|
||||||
|
rebuildFlatNavigation();
|
||||||
isTogglingGroup = true
|
|
||||||
NotificationService.toggleGroupExpansion(group.key)
|
|
||||||
rebuildFlatNavigation()
|
|
||||||
|
|
||||||
// Smart selection after toggle
|
// Smart selection after toggle
|
||||||
if (!wasExpanded) {
|
if (!wasExpanded) {
|
||||||
// Just expanded - move to first notification in the group
|
// Just expanded - move to first notification in the group
|
||||||
for (var i = 0; i < flatNavigation.length; i++) {
|
for (var i = 0; i < flatNavigation.length; i++) {
|
||||||
if (flatNavigation[i].type === "notification" && flatNavigation[i].groupIndex === groupIndex) {
|
if (flatNavigation[i].type === "notification" && flatNavigation[i].groupIndex === groupIndex) {
|
||||||
selectedFlatIndex = i
|
selectedFlatIndex = i;
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Just collapsed - stay on the group header
|
// Just collapsed - stay on the group header
|
||||||
for (var i = 0; i < flatNavigation.length; i++) {
|
for (var i = 0; i < flatNavigation.length; i++) {
|
||||||
if (flatNavigation[i].type === "group" && flatNavigation[i].groupIndex === groupIndex) {
|
if (flatNavigation[i].type === "group" && flatNavigation[i].groupIndex === groupIndex) {
|
||||||
selectedFlatIndex = i
|
selectedFlatIndex = i;
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isTogglingGroup = false
|
isTogglingGroup = false;
|
||||||
ensureVisible()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEnterKey() {
|
function handleEnterKey() {
|
||||||
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
|
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
|
||||||
return
|
return;
|
||||||
|
const currentItem = flatNavigation[selectedFlatIndex];
|
||||||
const currentItem = flatNavigation[selectedFlatIndex]
|
const groups = NotificationService.groupedNotifications;
|
||||||
const groups = NotificationService.groupedNotifications
|
const group = groups[currentItem.groupIndex];
|
||||||
const group = groups[currentItem.groupIndex]
|
|
||||||
if (!group)
|
if (!group)
|
||||||
return
|
return;
|
||||||
|
|
||||||
if (currentItem.type === "group") {
|
if (currentItem.type === "group") {
|
||||||
const notificationCount = group.notifications ? group.notifications.length : 0
|
const notificationCount = group.notifications ? group.notifications.length : 0;
|
||||||
if (notificationCount >= 2) {
|
if (notificationCount >= 2) {
|
||||||
toggleGroupExpanded()
|
toggleGroupExpanded();
|
||||||
} else {
|
} else {
|
||||||
executeAction(0)
|
executeAction(0);
|
||||||
}
|
}
|
||||||
} else if (currentItem.type === "notification") {
|
} else if (currentItem.type === "notification") {
|
||||||
executeAction(0)
|
executeAction(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleTextExpanded() {
|
function toggleTextExpanded() {
|
||||||
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
|
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
|
||||||
return
|
return;
|
||||||
|
const currentItem = flatNavigation[selectedFlatIndex];
|
||||||
const currentItem = flatNavigation[selectedFlatIndex]
|
const groups = NotificationService.groupedNotifications;
|
||||||
const groups = NotificationService.groupedNotifications
|
const group = groups[currentItem.groupIndex];
|
||||||
const group = groups[currentItem.groupIndex]
|
|
||||||
if (!group)
|
if (!group)
|
||||||
return
|
return;
|
||||||
|
let messageId = "";
|
||||||
let messageId = ""
|
|
||||||
|
|
||||||
if (currentItem.type === "group") {
|
if (currentItem.type === "group") {
|
||||||
messageId = group.latestNotification?.notification?.id + "_desc"
|
messageId = group.latestNotification?.notification?.id + "_desc";
|
||||||
} else if (currentItem.type === "notification" && currentItem.notificationIndex >= 0 && currentItem.notificationIndex < group.notifications.length) {
|
} else if (currentItem.type === "notification" && currentItem.notificationIndex >= 0 && currentItem.notificationIndex < group.notifications.length) {
|
||||||
messageId = group.notifications[currentItem.notificationIndex]?.notification?.id + "_desc"
|
messageId = group.notifications[currentItem.notificationIndex]?.notification?.id + "_desc";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messageId) {
|
if (messageId) {
|
||||||
NotificationService.toggleMessageExpansion(messageId)
|
NotificationService.toggleMessageExpansion(messageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function executeAction(actionIndex) {
|
function executeAction(actionIndex) {
|
||||||
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
|
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
|
||||||
return
|
return;
|
||||||
|
const currentItem = flatNavigation[selectedFlatIndex];
|
||||||
const currentItem = flatNavigation[selectedFlatIndex]
|
const groups = NotificationService.groupedNotifications;
|
||||||
const groups = NotificationService.groupedNotifications
|
const group = groups[currentItem.groupIndex];
|
||||||
const group = groups[currentItem.groupIndex]
|
|
||||||
if (!group)
|
if (!group)
|
||||||
return
|
return;
|
||||||
|
let actions = [];
|
||||||
let actions = []
|
|
||||||
|
|
||||||
if (currentItem.type === "group") {
|
if (currentItem.type === "group") {
|
||||||
actions = group.latestNotification?.actions || []
|
actions = group.latestNotification?.actions || [];
|
||||||
} else if (currentItem.type === "notification" && currentItem.notificationIndex >= 0 && currentItem.notificationIndex < group.notifications.length) {
|
} else if (currentItem.type === "notification" && currentItem.notificationIndex >= 0 && currentItem.notificationIndex < group.notifications.length) {
|
||||||
actions = group.notifications[currentItem.notificationIndex]?.actions || []
|
actions = group.notifications[currentItem.notificationIndex]?.actions || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionIndex >= 0 && actionIndex < actions.length) {
|
if (actionIndex >= 0 && actionIndex < actions.length) {
|
||||||
const action = actions[actionIndex]
|
const action = actions[actionIndex];
|
||||||
if (action.invoke) {
|
if (action.invoke) {
|
||||||
action.invoke()
|
action.invoke();
|
||||||
if (onClose)
|
if (onClose)
|
||||||
onClose()
|
onClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearSelected() {
|
function clearSelected() {
|
||||||
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
|
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
|
||||||
return
|
return;
|
||||||
|
const currentItem = flatNavigation[selectedFlatIndex];
|
||||||
const currentItem = flatNavigation[selectedFlatIndex]
|
const groups = NotificationService.groupedNotifications;
|
||||||
const groups = NotificationService.groupedNotifications
|
const group = groups[currentItem.groupIndex];
|
||||||
const group = groups[currentItem.groupIndex]
|
|
||||||
if (!group)
|
if (!group)
|
||||||
return
|
return;
|
||||||
|
|
||||||
if (currentItem.type === "group") {
|
if (currentItem.type === "group") {
|
||||||
NotificationService.dismissGroup(group.key)
|
NotificationService.dismissGroup(group.key);
|
||||||
} else if (currentItem.type === "notification") {
|
} else if (currentItem.type === "notification") {
|
||||||
const notification = group.notifications[currentItem.notificationIndex]
|
const notification = group.notifications[currentItem.notificationIndex];
|
||||||
NotificationService.dismissNotification(notification)
|
NotificationService.dismissNotification(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuildFlatNavigation()
|
rebuildFlatNavigation();
|
||||||
|
|
||||||
if (flatNavigation.length === 0) {
|
if (flatNavigation.length === 0) {
|
||||||
keyboardNavigationActive = false
|
keyboardNavigationActive = false;
|
||||||
if (listView) {
|
if (listView) {
|
||||||
listView.keyboardActive = false
|
listView.keyboardActive = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selectedFlatIndex = Math.min(selectedFlatIndex, flatNavigation.length - 1)
|
selectedFlatIndex = Math.min(selectedFlatIndex, flatNavigation.length - 1);
|
||||||
updateSelectedIdFromIndex()
|
updateSelectedIdFromIndex();
|
||||||
ensureVisible()
|
ensureVisible();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function findRepeater(parent) {
|
function findRepeater(parent) {
|
||||||
if (!parent || !parent.children) {
|
if (!parent || !parent.children) {
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
for (var i = 0; i < parent.children.length; i++) {
|
for (var i = 0; i < parent.children.length; i++) {
|
||||||
const child = parent.children[i]
|
const child = parent.children[i];
|
||||||
if (child.objectName === "notificationRepeater") {
|
if (child.objectName === "notificationRepeater") {
|
||||||
return child
|
return child;
|
||||||
}
|
}
|
||||||
const found = findRepeater(child)
|
const found = findRepeater(child);
|
||||||
if (found) {
|
if (found) {
|
||||||
return found
|
return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureVisible() {
|
function ensureVisible() {
|
||||||
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length || !listView)
|
if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length || !listView)
|
||||||
return
|
return;
|
||||||
|
const currentItem = flatNavigation[selectedFlatIndex];
|
||||||
const currentItem = flatNavigation[selectedFlatIndex]
|
|
||||||
|
|
||||||
if (keyboardNavigationActive && currentItem && currentItem.groupIndex >= 0) {
|
if (keyboardNavigationActive && currentItem && currentItem.groupIndex >= 0) {
|
||||||
if (currentItem.type === "notification") {
|
if (currentItem.type === "notification") {
|
||||||
const groupDelegate = listView.itemAtIndex(currentItem.groupIndex)
|
const groupDelegate = listView.itemAtIndex(currentItem.groupIndex);
|
||||||
if (groupDelegate && groupDelegate.children && groupDelegate.children.length > 0) {
|
if (groupDelegate && groupDelegate.children && groupDelegate.children.length > 0) {
|
||||||
const notificationCard = groupDelegate.children[0]
|
const notificationCard = groupDelegate.children[0];
|
||||||
const repeater = findRepeater(notificationCard)
|
const repeater = findRepeater(notificationCard);
|
||||||
|
|
||||||
if (repeater && currentItem.notificationIndex < repeater.count) {
|
if (repeater && currentItem.notificationIndex < repeater.count) {
|
||||||
const notificationItem = repeater.itemAt(currentItem.notificationIndex)
|
const notificationItem = repeater.itemAt(currentItem.notificationIndex);
|
||||||
if (notificationItem) {
|
if (notificationItem) {
|
||||||
const itemPos = notificationItem.mapToItem(listView.contentItem, 0, 0)
|
const itemPos = notificationItem.mapToItem(listView.contentItem, 0, 0);
|
||||||
const itemY = itemPos.y
|
const itemY = itemPos.y;
|
||||||
const itemHeight = notificationItem.height
|
const itemHeight = notificationItem.height;
|
||||||
|
|
||||||
const viewportTop = listView.contentY
|
const viewportTop = listView.contentY;
|
||||||
const viewportBottom = listView.contentY + listView.height
|
const viewportBottom = listView.contentY + listView.height;
|
||||||
|
|
||||||
if (itemY < viewportTop) {
|
if (itemY < viewportTop) {
|
||||||
listView.contentY = itemY - 20
|
listView.contentY = itemY - 20;
|
||||||
} else if (itemY + itemHeight > viewportBottom) {
|
} else if (itemY + itemHeight > viewportBottom) {
|
||||||
listView.contentY = itemY + itemHeight - listView.height + 20
|
listView.contentY = itemY + itemHeight - listView.height + 20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
listView.positionViewAtIndex(currentItem.groupIndex, ListView.Contain)
|
listView.positionViewAtIndex(currentItem.groupIndex, ListView.Contain);
|
||||||
}
|
}
|
||||||
|
|
||||||
listView.forceLayout()
|
listView.forceLayout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKey(event) {
|
function handleKey(event) {
|
||||||
if ((event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace) && (event.modifiers & Qt.ShiftModifier)) {
|
if ((event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace) && (event.modifiers & Qt.ShiftModifier)) {
|
||||||
NotificationService.clearAllNotifications()
|
NotificationService.clearAllNotifications();
|
||||||
rebuildFlatNavigation()
|
rebuildFlatNavigation();
|
||||||
if (flatNavigation.length === 0) {
|
if (flatNavigation.length === 0) {
|
||||||
keyboardNavigationActive = false
|
keyboardNavigationActive = false;
|
||||||
if (listView) {
|
if (listView) {
|
||||||
listView.keyboardActive = false
|
listView.keyboardActive = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selectedFlatIndex = 0
|
selectedFlatIndex = 0;
|
||||||
updateSelectedIdFromIndex()
|
updateSelectedIdFromIndex();
|
||||||
}
|
}
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.key === Qt.Key_Escape) {
|
if (event.key === Qt.Key_Escape) {
|
||||||
if (keyboardNavigationActive) {
|
if (keyboardNavigationActive) {
|
||||||
keyboardNavigationActive = false
|
keyboardNavigationActive = false;
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else {
|
} else {
|
||||||
if (onClose)
|
if (onClose)
|
||||||
onClose()
|
onClose();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
} else if (event.key === Qt.Key_Down || event.key === 16777237) {
|
} else if (event.key === Qt.Key_Down || event.key === 16777237) {
|
||||||
if (!keyboardNavigationActive) {
|
if (!keyboardNavigationActive) {
|
||||||
keyboardNavigationActive = true
|
keyboardNavigationActive = true;
|
||||||
rebuildFlatNavigation() // Ensure we have fresh navigation data
|
rebuildFlatNavigation(); // Ensure we have fresh navigation data
|
||||||
selectedFlatIndex = 0
|
selectedFlatIndex = 0;
|
||||||
updateSelectedIdFromIndex()
|
updateSelectedIdFromIndex();
|
||||||
// Set keyboardActive on listView to show highlight
|
// Set keyboardActive on listView to show highlight
|
||||||
if (listView) {
|
if (listView) {
|
||||||
listView.keyboardActive = true
|
listView.keyboardActive = true;
|
||||||
}
|
}
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
ensureVisible()
|
ensureVisible();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else {
|
} else {
|
||||||
selectNext()
|
selectNext();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
} else if (event.key === Qt.Key_Up || event.key === 16777235) {
|
} else if (event.key === Qt.Key_Up || event.key === 16777235) {
|
||||||
if (!keyboardNavigationActive) {
|
if (!keyboardNavigationActive) {
|
||||||
keyboardNavigationActive = true
|
keyboardNavigationActive = true;
|
||||||
rebuildFlatNavigation() // Ensure we have fresh navigation data
|
rebuildFlatNavigation(); // Ensure we have fresh navigation data
|
||||||
selectedFlatIndex = 0
|
selectedFlatIndex = 0;
|
||||||
updateSelectedIdFromIndex()
|
updateSelectedIdFromIndex();
|
||||||
// Set keyboardActive on listView to show highlight
|
// Set keyboardActive on listView to show highlight
|
||||||
if (listView) {
|
if (listView) {
|
||||||
listView.keyboardActive = true
|
listView.keyboardActive = true;
|
||||||
}
|
}
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
ensureVisible()
|
ensureVisible();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (selectedFlatIndex === 0) {
|
} else if (selectedFlatIndex === 0) {
|
||||||
keyboardNavigationActive = false
|
keyboardNavigationActive = false;
|
||||||
// Reset keyboardActive when navigation is disabled
|
// Reset keyboardActive when navigation is disabled
|
||||||
if (listView) {
|
if (listView) {
|
||||||
listView.keyboardActive = false
|
listView.keyboardActive = false;
|
||||||
}
|
}
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
return
|
return;
|
||||||
} else {
|
} else {
|
||||||
selectPrevious()
|
selectPrevious();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
} else if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
|
} else if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
|
||||||
if (!keyboardNavigationActive) {
|
if (!keyboardNavigationActive) {
|
||||||
keyboardNavigationActive = true
|
keyboardNavigationActive = true;
|
||||||
rebuildFlatNavigation()
|
rebuildFlatNavigation();
|
||||||
selectedFlatIndex = 0
|
selectedFlatIndex = 0;
|
||||||
updateSelectedIdFromIndex()
|
updateSelectedIdFromIndex();
|
||||||
if (listView) {
|
if (listView) {
|
||||||
listView.keyboardActive = true
|
listView.keyboardActive = true;
|
||||||
}
|
}
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
ensureVisible()
|
ensureVisible();
|
||||||
} else {
|
} else {
|
||||||
selectNext()
|
selectNext();
|
||||||
}
|
}
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) {
|
} else if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) {
|
||||||
if (!keyboardNavigationActive) {
|
if (!keyboardNavigationActive) {
|
||||||
keyboardNavigationActive = true
|
keyboardNavigationActive = true;
|
||||||
rebuildFlatNavigation()
|
rebuildFlatNavigation();
|
||||||
selectedFlatIndex = 0
|
selectedFlatIndex = 0;
|
||||||
updateSelectedIdFromIndex()
|
updateSelectedIdFromIndex();
|
||||||
if (listView) {
|
if (listView) {
|
||||||
listView.keyboardActive = true
|
listView.keyboardActive = true;
|
||||||
}
|
}
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
ensureVisible()
|
ensureVisible();
|
||||||
} else if (selectedFlatIndex === 0) {
|
} else if (selectedFlatIndex === 0) {
|
||||||
keyboardNavigationActive = false
|
keyboardNavigationActive = false;
|
||||||
if (listView) {
|
if (listView) {
|
||||||
listView.keyboardActive = false
|
listView.keyboardActive = false;
|
||||||
}
|
}
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
} else {
|
} else {
|
||||||
selectPrevious()
|
selectPrevious();
|
||||||
}
|
}
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) {
|
} else if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) {
|
||||||
if (!keyboardNavigationActive) {
|
if (!keyboardNavigationActive) {
|
||||||
keyboardNavigationActive = true
|
keyboardNavigationActive = true;
|
||||||
rebuildFlatNavigation()
|
rebuildFlatNavigation();
|
||||||
selectedFlatIndex = 0
|
selectedFlatIndex = 0;
|
||||||
updateSelectedIdFromIndex()
|
updateSelectedIdFromIndex();
|
||||||
if (listView) {
|
if (listView) {
|
||||||
listView.keyboardActive = true
|
listView.keyboardActive = true;
|
||||||
}
|
}
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
ensureVisible()
|
ensureVisible();
|
||||||
} else {
|
} else {
|
||||||
selectNext()
|
selectNext();
|
||||||
}
|
}
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) {
|
} else if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) {
|
||||||
if (!keyboardNavigationActive) {
|
if (!keyboardNavigationActive) {
|
||||||
keyboardNavigationActive = true
|
keyboardNavigationActive = true;
|
||||||
rebuildFlatNavigation()
|
rebuildFlatNavigation();
|
||||||
selectedFlatIndex = 0
|
selectedFlatIndex = 0;
|
||||||
updateSelectedIdFromIndex()
|
updateSelectedIdFromIndex();
|
||||||
if (listView) {
|
if (listView) {
|
||||||
listView.keyboardActive = true
|
listView.keyboardActive = true;
|
||||||
}
|
}
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
ensureVisible()
|
ensureVisible();
|
||||||
} else if (selectedFlatIndex === 0) {
|
} else if (selectedFlatIndex === 0) {
|
||||||
keyboardNavigationActive = false
|
keyboardNavigationActive = false;
|
||||||
if (listView) {
|
if (listView) {
|
||||||
listView.keyboardActive = false
|
listView.keyboardActive = false;
|
||||||
}
|
}
|
||||||
selectionVersion++
|
selectionVersion++;
|
||||||
} else {
|
} else {
|
||||||
selectPrevious()
|
selectPrevious();
|
||||||
}
|
}
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (keyboardNavigationActive) {
|
} else if (keyboardNavigationActive) {
|
||||||
if (event.key === Qt.Key_Space) {
|
if (event.key === Qt.Key_Space) {
|
||||||
toggleGroupExpanded()
|
toggleGroupExpanded();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
||||||
handleEnterKey()
|
handleEnterKey();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_E) {
|
} else if (event.key === Qt.Key_E) {
|
||||||
toggleTextExpanded()
|
toggleTextExpanded();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace) {
|
} else if (event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace) {
|
||||||
clearSelected()
|
clearSelected();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_Tab) {
|
} else if (event.key === Qt.Key_Tab) {
|
||||||
selectNext()
|
selectNext();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_Backtab) {
|
} else if (event.key === Qt.Key_Backtab) {
|
||||||
selectPrevious()
|
selectPrevious();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (event.key >= Qt.Key_1 && event.key <= Qt.Key_9) {
|
} else if (event.key >= Qt.Key_1 && event.key <= Qt.Key_9) {
|
||||||
const actionIndex = event.key - Qt.Key_1
|
const actionIndex = event.key - Qt.Key_1;
|
||||||
executeAction(actionIndex)
|
executeAction(actionIndex);
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.key === Qt.Key_F10) {
|
if (event.key === Qt.Key_F10) {
|
||||||
showKeyboardHints = !showKeyboardHints
|
showKeyboardHints = !showKeyboardHints;
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,13 +544,13 @@ QtObject {
|
|||||||
"type": "",
|
"type": "",
|
||||||
"groupIndex": -1,
|
"groupIndex": -1,
|
||||||
"notificationIndex": -1
|
"notificationIndex": -1
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
const result = flatNavigation[selectedFlatIndex] || {
|
const result = flatNavigation[selectedFlatIndex] || {
|
||||||
"type": "",
|
"type": "",
|
||||||
"groupIndex": -1,
|
"groupIndex": -1,
|
||||||
"notificationIndex": -1
|
"notificationIndex": -1
|
||||||
}
|
};
|
||||||
return result
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user