mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-07 14:05:38 -05:00
notifications: reverse order top to bottom, fix warnings
This commit is contained in:
@@ -6,166 +6,100 @@ import qs.Services
|
||||
QtObject {
|
||||
id: manager
|
||||
|
||||
property var popupLoaders: []
|
||||
property int maxTargetNotifications: 3
|
||||
property int baseNotificationHeight: 132
|
||||
property bool dismissalInProgress: false
|
||||
property int topMargin: 0
|
||||
property var popupWindows: []
|
||||
|
||||
property Timer dismissalTimer: Timer {
|
||||
interval: 200
|
||||
repeat: false
|
||||
onTriggered: dismissNextOldest()
|
||||
}
|
||||
|
||||
property Component popupLoaderComponent: Component {
|
||||
Loader {
|
||||
id: popupLoader
|
||||
|
||||
property var notifWrapper
|
||||
|
||||
active: false
|
||||
asynchronous: true
|
||||
|
||||
sourceComponent: NotificationPopup {
|
||||
id: popup
|
||||
|
||||
notificationData: popupLoader.notifWrapper
|
||||
notificationId: popupLoader.notifWrapper ? popupLoader.notifWrapper.notification.id : ""
|
||||
onEntered: manager._onPopupEntered(popupLoader)
|
||||
onSlideOutChanged: {
|
||||
if (slideOut) {
|
||||
manager._onPopupExitStarted(popupLoader);
|
||||
}
|
||||
}
|
||||
onExitFinished: manager._onPopupExitFinished(popupLoader)
|
||||
}
|
||||
property Component popupComponent: Component {
|
||||
NotificationPopup {
|
||||
property var wrapper
|
||||
notificationData: wrapper
|
||||
notificationId: wrapper.notification.id
|
||||
rowHeight: manager.baseNotificationHeight
|
||||
onEntered: manager._onPopupEntered(this)
|
||||
onExitFinished: manager._onPopupExitFinished(this)
|
||||
}
|
||||
}
|
||||
|
||||
property Connections notificationConnections: Connections {
|
||||
function onVisibleNotificationsChanged() {
|
||||
syncPopupsWithQueue(NotificationService.visibleNotifications);
|
||||
}
|
||||
|
||||
target: NotificationService
|
||||
}
|
||||
|
||||
function _createPopupLoader(notifWrapper) {
|
||||
const L = popupLoaderComponent.createObject(manager, {
|
||||
"notifWrapper": notifWrapper
|
||||
});
|
||||
popupLoaders.push(L);
|
||||
return L;
|
||||
}
|
||||
|
||||
function _destroyPopupLoader(L) {
|
||||
const i = popupLoaders.indexOf(L);
|
||||
if (i !== -1) {
|
||||
popupLoaders.splice(i, 1);
|
||||
popupLoaders = popupLoaders.slice();
|
||||
}
|
||||
L.active = false;
|
||||
L.sourceComponent = null;
|
||||
}
|
||||
|
||||
function _activeItems() {
|
||||
return popupLoaders.filter((L) => {
|
||||
return L.item && L.item.notificationData && L.item.notificationData.popup;
|
||||
});
|
||||
}
|
||||
|
||||
function _stableItems() {
|
||||
return _activeItems().filter((L) => {
|
||||
return !L.item.entering;
|
||||
});
|
||||
}
|
||||
|
||||
function repositionAll() {
|
||||
const stable = _stableItems();
|
||||
for (let i = 0; i < stable.length; ++i) {
|
||||
const it = stable[i].item;
|
||||
if (it)
|
||||
it.verticalOffset = i * baseNotificationHeight;
|
||||
|
||||
function onVisibleNotificationsChanged() {
|
||||
manager._sync(NotificationService.visibleNotifications);
|
||||
}
|
||||
}
|
||||
|
||||
function syncPopupsWithQueue(newWrappers) {
|
||||
function _hasWindowFor(w) { return popupWindows.some(p => p && p.notificationData === w); }
|
||||
|
||||
function _sync(newWrappers) {
|
||||
for (let w of newWrappers) {
|
||||
if (!popupLoaders.some((L) => {
|
||||
return L.notifWrapper === w;
|
||||
})) {
|
||||
const L = _createPopupLoader(w);
|
||||
const actives = _activeItems().length;
|
||||
w.initialOffset = actives * baseNotificationHeight;
|
||||
L.active = true;
|
||||
if (!_hasWindowFor(w)) _insertNewestAtTop(w);
|
||||
}
|
||||
for (let p of popupWindows.slice()) {
|
||||
if (newWrappers.indexOf(p.notificationData) === -1 && p && !p.exiting) {
|
||||
p.notificationData.removedByLimit = true;
|
||||
p.notificationData.popup = false;
|
||||
}
|
||||
}
|
||||
for (let L of popupLoaders.slice()) {
|
||||
if (newWrappers.indexOf(L.notifWrapper) === -1)
|
||||
_destroyPopupLoader(L);
|
||||
|
||||
}
|
||||
repositionAll();
|
||||
}
|
||||
|
||||
function _onPopupEntered(L) {
|
||||
repositionAll();
|
||||
maybeStartOverflow();
|
||||
}
|
||||
|
||||
function _onPopupExitStarted(L) {
|
||||
const it = L.item;
|
||||
if (!it)
|
||||
return ;
|
||||
|
||||
if (it.shadowLayers) {
|
||||
for (let layer of it.shadowLayers) {
|
||||
if (layer)
|
||||
layer.visible = false;
|
||||
|
||||
function _insertNewestAtTop(wrapper) {
|
||||
for (let p of popupWindows) {
|
||||
if (p && p.notificationData && p.notificationData.popup && !p.exiting) {
|
||||
p.screenY = p.screenY + baseNotificationHeight;
|
||||
}
|
||||
}
|
||||
if (it.iconContainer && it.iconContainer.iconImage) {
|
||||
it.iconContainer.iconImage.source = "";
|
||||
|
||||
const win = popupComponent.createObject(null, { wrapper: wrapper, screenY: topMargin });
|
||||
if (!win) {
|
||||
console.warn("Popup create failed");
|
||||
return;
|
||||
}
|
||||
popupWindows.push(win);
|
||||
_maybeStartOverflow();
|
||||
}
|
||||
|
||||
function _active() {
|
||||
return popupWindows.filter(p => p && p.notificationData && p.notificationData.popup);
|
||||
}
|
||||
|
||||
function _bottom() {
|
||||
let b = null, max = -1;
|
||||
for (let p of _active()) {
|
||||
if (!p.exiting && p.screenY > max) {
|
||||
max = p.screenY;
|
||||
b = p;
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
function _maybeStartOverflow() {
|
||||
if (_active().length <= maxTargetNotifications + 1) return;
|
||||
const b = _bottom();
|
||||
if (b && !b.exiting) {
|
||||
b.notificationData.removedByLimit = true;
|
||||
b.notificationData.popup = false;
|
||||
}
|
||||
}
|
||||
|
||||
function _onPopupExitFinished(L) {
|
||||
NotificationService.releaseWrapper(L.notifWrapper);
|
||||
_destroyPopupLoader(L);
|
||||
repositionAll();
|
||||
maybeStartOverflow();
|
||||
function _onPopupEntered(p) {
|
||||
// Entry completed
|
||||
}
|
||||
|
||||
function maybeStartOverflow() {
|
||||
const active = _activeItems();
|
||||
if (dismissalInProgress)
|
||||
return ;
|
||||
|
||||
if (active.length > maxTargetNotifications)
|
||||
startSequentialDismissal();
|
||||
|
||||
}
|
||||
|
||||
function startSequentialDismissal() {
|
||||
dismissalInProgress = true;
|
||||
dismissNextOldest();
|
||||
}
|
||||
|
||||
function dismissNextOldest() {
|
||||
const active = _activeItems();
|
||||
if (active.length <= maxTargetNotifications) {
|
||||
dismissalInProgress = false;
|
||||
return ;
|
||||
}
|
||||
const oldest = active[0].item;
|
||||
if (oldest) {
|
||||
oldest.notificationData.removedByLimit = true;
|
||||
oldest.notificationData.popup = false;
|
||||
dismissalTimer.restart();
|
||||
function _onPopupExitFinished(p) {
|
||||
const i = popupWindows.indexOf(p);
|
||||
if (i !== -1) {
|
||||
popupWindows.splice(i, 1);
|
||||
popupWindows = popupWindows.slice();
|
||||
}
|
||||
if (NotificationService.releaseWrapper) NotificationService.releaseWrapper(p.notificationData);
|
||||
p.destroy();
|
||||
|
||||
const survivors = _active().filter(s => !s.exiting).sort((a,b) => a.screenY - b.screenY);
|
||||
for (let k = 0; k < survivors.length; ++k)
|
||||
survivors[k].screenY = topMargin + k * baseNotificationHeight;
|
||||
|
||||
_maybeStartOverflow();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user