summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/dms/Modules/Notifications/Center/NotificationCenterPopout.qml
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-hyprland-theme/theme-data/dms/Modules/Notifications/Center/NotificationCenterPopout.qml')
-rw-r--r--raveos-hyprland-theme/theme-data/dms/Modules/Notifications/Center/NotificationCenterPopout.qml321
1 files changed, 321 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/dms/Modules/Notifications/Center/NotificationCenterPopout.qml b/raveos-hyprland-theme/theme-data/dms/Modules/Notifications/Center/NotificationCenterPopout.qml
new file mode 100644
index 0000000..b7b616b
--- /dev/null
+++ b/raveos-hyprland-theme/theme-data/dms/Modules/Notifications/Center/NotificationCenterPopout.qml
@@ -0,0 +1,321 @@
+import QtQuick
+import qs.Common
+import qs.Services
+import qs.Widgets
+
+DankPopout {
+ id: root
+
+ layerNamespace: "dms:notification-center-popout"
+ fullHeightSurface: true
+
+ property bool notificationHistoryVisible: false
+ property var triggerScreen: null
+ property real stablePopupHeight: 400
+ property real _lastAlignedContentHeight: -1
+ property bool _pendingSizedOpen: false
+
+ function updateStablePopupHeight() {
+ const item = contentLoader.item;
+ if (item && !root.shouldBeVisible) {
+ const notificationList = findChild(item, "notificationList");
+ if (notificationList && typeof notificationList.forceLayout === "function") {
+ notificationList.forceLayout();
+ }
+ }
+ const target = item ? Theme.px(item.implicitHeight, dpr) : 400;
+ if (Math.abs(target - _lastAlignedContentHeight) < 0.5)
+ return;
+ _lastAlignedContentHeight = target;
+ stablePopupHeight = target;
+ }
+
+ NotificationKeyboardController {
+ id: keyboardController
+ listView: null
+ isOpen: root.shouldBeVisible
+ onClose: () => {
+ notificationHistoryVisible = false;
+ }
+ }
+
+ popupWidth: triggerScreen ? Math.min(500, Math.max(380, triggerScreen.width - 48)) : 400
+ popupHeight: stablePopupHeight
+ positioning: ""
+ animationScaleCollapsed: 0.94
+ animationOffset: 0
+ suspendShadowWhileResizing: false
+
+ screen: triggerScreen
+
+ function toggle() {
+ notificationHistoryVisible = !notificationHistoryVisible;
+ }
+
+ function openSized() {
+ if (!notificationHistoryVisible)
+ return;
+
+ primeContent();
+ if (contentLoader.item) {
+ updateStablePopupHeight();
+ _pendingSizedOpen = false;
+ Qt.callLater(() => {
+ if (!notificationHistoryVisible)
+ return;
+ updateStablePopupHeight();
+ open();
+ clearPrimedContent();
+ });
+ return;
+ }
+
+ _pendingSizedOpen = true;
+ }
+
+ onBackgroundClicked: {
+ notificationHistoryVisible = false;
+ }
+
+ onNotificationHistoryVisibleChanged: {
+ if (notificationHistoryVisible) {
+ openSized();
+ } else {
+ _pendingSizedOpen = false;
+ clearPrimedContent();
+ close();
+ }
+ }
+
+ function setupKeyboardNavigation() {
+ if (!contentLoader.item)
+ return;
+ contentLoader.item.externalKeyboardController = keyboardController;
+
+ const notificationList = findChild(contentLoader.item, "notificationList");
+ const notificationHeader = findChild(contentLoader.item, "notificationHeader");
+
+ if (notificationList) {
+ keyboardController.listView = notificationList;
+ notificationList.keyboardController = keyboardController;
+ }
+ if (notificationHeader) {
+ notificationHeader.keyboardController = keyboardController;
+ }
+
+ keyboardController.reset();
+ keyboardController.rebuildFlatNavigation();
+ }
+
+ Connections {
+ target: contentLoader
+ function onLoaded() {
+ root.updateStablePopupHeight();
+ if (root._pendingSizedOpen && root.notificationHistoryVisible) {
+ Qt.callLater(() => {
+ if (!root._pendingSizedOpen || !root.notificationHistoryVisible)
+ return;
+ root.updateStablePopupHeight();
+ root._pendingSizedOpen = false;
+ root.open();
+ root.clearPrimedContent();
+ });
+ return;
+ }
+ if (root.shouldBeVisible)
+ Qt.callLater(root.setupKeyboardNavigation);
+ }
+ }
+
+ Connections {
+ target: contentLoader.item
+ function onImplicitHeightChanged() {
+ root.updateStablePopupHeight();
+ }
+ }
+
+ onDprChanged: updateStablePopupHeight()
+
+ onShouldBeVisibleChanged: {
+ if (shouldBeVisible) {
+ NotificationService.onOverlayOpen();
+ updateStablePopupHeight();
+ if (contentLoader.item)
+ Qt.callLater(setupKeyboardNavigation);
+ } else {
+ NotificationService.onOverlayClose();
+ keyboardController.keyboardNavigationActive = false;
+ NotificationService.expandedGroups = {};
+ NotificationService.expandedMessages = {};
+ }
+ }
+
+ function findChild(parent, objectName) {
+ if (parent.objectName === objectName) {
+ return parent;
+ }
+ for (let i = 0; i < parent.children.length; i++) {
+ const child = parent.children[i];
+ const result = findChild(child, objectName);
+ if (result) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ content: Component {
+ Rectangle {
+ id: notificationContent
+
+ LayoutMirroring.enabled: I18n.isRtl
+ LayoutMirroring.childrenInherit: true
+
+ property var externalKeyboardController: null
+ property real cachedHeaderHeight: 32
+ readonly property real settingsMaxHeight: {
+ const screenH = root.screen ? root.screen.height : 1080;
+ const maxPopupH = screenH * 0.8;
+ const overhead = cachedHeaderHeight + Theme.spacingL * 2 + Theme.spacingM * 2;
+ return Math.max(200, maxPopupH - overhead - 150);
+ }
+ implicitHeight: {
+ let baseHeight = Theme.spacingL * 2;
+ baseHeight += cachedHeaderHeight;
+ baseHeight += Theme.spacingM * 2;
+
+ const settingsHeight = notificationSettings.expanded ? Math.min(notificationSettings.naturalContentHeight, settingsMaxHeight) : 0;
+ const currentListHeight = root.shouldBeVisible ? notificationList.stableContentHeight : notificationList.listContentHeight;
+ let listHeight = notificationHeader.currentTab === 0 ? currentListHeight : Math.max(200, NotificationService.historyList.length * 80);
+ if (notificationHeader.currentTab === 0 && NotificationService.groupedNotifications.length === 0) {
+ listHeight = 200;
+ }
+ if (notificationHeader.currentTab === 1 && NotificationService.historyList.length === 0) {
+ listHeight = 200;
+ }
+
+ const maxContentArea = 600;
+ const availableListSpace = Math.max(200, maxContentArea - settingsHeight);
+
+ baseHeight += settingsHeight;
+ baseHeight += Math.min(listHeight, availableListSpace);
+
+ const maxHeight = root.screen ? root.screen.height * 0.8 : Screen.height * 0.8;
+ return Math.max(300, Math.min(baseHeight, maxHeight));
+ }
+
+ color: "transparent"
+ focus: true
+
+ Component.onCompleted: {
+ if (root.shouldBeVisible) {
+ forceActiveFocus();
+ }
+ }
+
+ Keys.onPressed: event => {
+ if (event.key === Qt.Key_Escape) {
+ notificationHistoryVisible = false;
+ event.accepted = true;
+ return;
+ }
+
+ if (event.key === Qt.Key_Left) {
+ if (notificationHeader.currentTab > 0) {
+ notificationHeader.currentTab = 0;
+ event.accepted = true;
+ }
+ return;
+ }
+
+ if (event.key === Qt.Key_Right) {
+ if (notificationHeader.currentTab === 0 && SettingsData.notificationHistoryEnabled) {
+ notificationHeader.currentTab = 1;
+ event.accepted = true;
+ }
+ return;
+ }
+ if (notificationHeader.currentTab === 1) {
+ historyList.handleKey(event);
+ return;
+ }
+ if (externalKeyboardController) {
+ externalKeyboardController.handleKey(event);
+ }
+ }
+
+ Connections {
+ function onShouldBeVisibleChanged() {
+ if (root.shouldBeVisible) {
+ Qt.callLater(() => {
+ notificationContent.forceActiveFocus();
+ });
+ } else {
+ notificationContent.focus = false;
+ }
+ }
+ target: root
+ }
+
+ FocusScope {
+ id: contentColumn
+
+ anchors.fill: parent
+ anchors.margins: Theme.spacingL
+ focus: true
+
+ Column {
+ id: contentColumnInner
+ anchors.fill: parent
+ spacing: Theme.spacingM
+
+ NotificationHeader {
+ id: notificationHeader
+ objectName: "notificationHeader"
+ onHeightChanged: notificationContent.cachedHeaderHeight = height
+ }
+
+ NotificationSettings {
+ id: notificationSettings
+ expanded: notificationHeader.showSettings
+ maxAllowedHeight: notificationContent.settingsMaxHeight
+ }
+
+ Item {
+ visible: notificationHeader.currentTab === 0
+ width: parent.width
+ height: parent.height - notificationContent.cachedHeaderHeight - notificationSettings.height - contentColumnInner.spacing * 2
+
+ KeyboardNavigatedNotificationList {
+ id: notificationList
+ objectName: "notificationList"
+ anchors.fill: parent
+ anchors.leftMargin: -shadowHorizontalGutter
+ anchors.rightMargin: -shadowHorizontalGutter
+ anchors.topMargin: -(shadowVerticalGutter + delegateShadowGutter / 2)
+ anchors.bottomMargin: -(shadowVerticalGutter + delegateShadowGutter / 2)
+ cardAnimateExpansion: true
+ }
+ }
+
+ HistoryNotificationList {
+ id: historyList
+ visible: notificationHeader.currentTab === 1
+ width: parent.width
+ height: parent.height - notificationContent.cachedHeaderHeight - notificationSettings.height - contentColumnInner.spacing * 2
+ }
+ }
+ }
+
+ NotificationKeyboardHints {
+ id: keyboardHints
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.margins: Theme.spacingL
+ showHints: notificationHeader.currentTab === 0 ? (externalKeyboardController && externalKeyboardController.showKeyboardHints) || false : historyList.showKeyboardHints
+ z: 200
+ }
+ }
+ }
+}