mirror of
https://github.com/finos/SymphonyElectron.git
synced 2024-12-28 09:51:06 -06:00
fix: SDA-2806, SDA-2822 & SDA-2831 (Reposition notifications when on input) (#1168)
* fix: SDA-2806 - Reposition notifications when on input * fix: SDA-2822 - Fix rendering issue on SFE
This commit is contained in:
parent
3a16b7ef19
commit
da6ed20bc6
@ -275,7 +275,7 @@ export default class NotificationComp extends React.Component<{}, IState> {
|
||||
let replyText = this.getInputValue();
|
||||
if (replyText) {
|
||||
// need to replace 👍 with :thumbsup: to make sure client displays the correct emoji
|
||||
replyText = replyText.replace(/👍/g, replyText.length <= 2 ? ':thumbsup: ' : ':thumbsup:');
|
||||
replyText = replyText.replace(/👍/g, ':thumbsup: ');
|
||||
ipcRenderer.send('notification-on-reply', id, replyText);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ interface ISettings {
|
||||
maxVisibleNotifications: number;
|
||||
animationSteps: number;
|
||||
animationStepMs: number;
|
||||
spacing: number;
|
||||
differentialHeight: number;
|
||||
}
|
||||
|
||||
interface ICorner {
|
||||
@ -114,18 +116,25 @@ export default class NotificationHandler {
|
||||
/**
|
||||
* Find next possible insert position (on top)
|
||||
*/
|
||||
public calcNextInsertPos(activeNotificationLength) {
|
||||
if (activeNotificationLength < this.settings.maxVisibleNotifications) {
|
||||
public calcNextInsertPos(activeNotifications) {
|
||||
let nextNotificationY: number = 0;
|
||||
activeNotifications.forEach((notification) => {
|
||||
if (notification && windowExists(notification)) {
|
||||
const [, height] = notification.getSize();
|
||||
nextNotificationY += height > this.settings.height ? 112 : 72;
|
||||
}
|
||||
});
|
||||
if (activeNotifications.length < this.settings.maxVisibleNotifications) {
|
||||
switch (this.settings.startCorner) {
|
||||
case 'upper-right':
|
||||
case 'upper-left':
|
||||
this.nextInsertPos.y = this.settings.corner.y + (this.settings.totalHeight * activeNotificationLength);
|
||||
this.nextInsertPos.y = this.settings.corner.y + nextNotificationY;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'lower-right':
|
||||
case 'lower-left':
|
||||
this.nextInsertPos.y = this.settings.corner.y - (this.settings.totalHeight * (activeNotificationLength + 1));
|
||||
this.nextInsertPos.y = this.settings.corner.y - (nextNotificationY + 72);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -136,8 +145,10 @@ export default class NotificationHandler {
|
||||
*
|
||||
* @param startPos {number}
|
||||
* @param activeNotifications {ICustomBrowserWindow[]}
|
||||
* @param height {number} height of the closed notification
|
||||
* @param isReset {boolean} whether to reset all notification position
|
||||
*/
|
||||
public moveNotificationDown(startPos, activeNotifications) {
|
||||
public moveNotificationDown(startPos, activeNotifications, height: number = 0, isReset: boolean = false) {
|
||||
if (startPos >= activeNotifications || startPos === -1) {
|
||||
return;
|
||||
}
|
||||
@ -149,44 +160,102 @@ export default class NotificationHandler {
|
||||
asyncMap(notificationPosArray, (i, done) => {
|
||||
// Get notification to move
|
||||
const notificationWindow = activeNotifications[i];
|
||||
if (!windowExists(notificationWindow)) {
|
||||
return;
|
||||
}
|
||||
const [, y] = notificationWindow.getPosition();
|
||||
|
||||
// Calc new y position
|
||||
let newY;
|
||||
switch (this.settings.startCorner) {
|
||||
case 'upper-right':
|
||||
case 'upper-left':
|
||||
newY = this.settings.corner.y + (this.settings.totalHeight * i);
|
||||
newY = isReset
|
||||
? this.settings.corner.y + (this.settings.totalHeight * i)
|
||||
: (y - height - this.settings.spacing);
|
||||
break;
|
||||
default:
|
||||
case 'lower-right':
|
||||
case 'lower-left':
|
||||
newY = this.settings.corner.y - (this.settings.totalHeight * (i + 1));
|
||||
newY = isReset
|
||||
? this.settings.corner.y - (this.settings.totalHeight * (i + 1))
|
||||
: (y + height + this.settings.spacing);
|
||||
break;
|
||||
}
|
||||
|
||||
this.animateNotificationPosition(notificationWindow, newY, done);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the notification by one step
|
||||
*
|
||||
* @param startPos {number}
|
||||
* @param activeNotifications {ICustomBrowserWindow[]}
|
||||
*/
|
||||
public moveNotificationUp(startPos, activeNotifications) {
|
||||
if (startPos >= activeNotifications || startPos === -1) {
|
||||
return;
|
||||
}
|
||||
if (this.settings.startCorner === 'lower-right' || this.settings.startCorner === 'lower-left') {
|
||||
startPos -= 1;
|
||||
}
|
||||
// Build array with index of affected notifications
|
||||
const notificationPosArray: number[] = [];
|
||||
for (let i = startPos; i < activeNotifications.length; i++) {
|
||||
notificationPosArray.push(i);
|
||||
}
|
||||
asyncMap(notificationPosArray, (i, done) => {
|
||||
// Get notification to move
|
||||
const notificationWindow = activeNotifications[i];
|
||||
if (!windowExists(notificationWindow)) {
|
||||
return;
|
||||
}
|
||||
const [, y] = notificationWindow.getPosition();
|
||||
|
||||
// Get startPos, calc step size and start animationInterval
|
||||
const startY = notificationWindow.getPosition()[1];
|
||||
const step = (newY - startY) / this.settings.animationSteps;
|
||||
let curStep = 1;
|
||||
const animationInterval = setInterval(() => {
|
||||
// Abort condition
|
||||
if (curStep === this.settings.animationSteps) {
|
||||
this.setWindowPosition(notificationWindow, this.settings.firstPos.x, newY);
|
||||
clearInterval(animationInterval);
|
||||
done(null, 'done');
|
||||
return;
|
||||
}
|
||||
// Move one step down
|
||||
this.setWindowPosition(notificationWindow, this.settings.firstPos.x, startY + curStep * step);
|
||||
curStep++;
|
||||
}, this.settings.animationStepMs);
|
||||
// Calc new y position
|
||||
let newY;
|
||||
switch (this.settings.startCorner) {
|
||||
case 'upper-right':
|
||||
case 'upper-left':
|
||||
newY = y + this.settings.differentialHeight;
|
||||
break;
|
||||
default:
|
||||
case 'lower-right':
|
||||
case 'lower-left':
|
||||
newY = y - this.settings.differentialHeight;
|
||||
break;
|
||||
}
|
||||
|
||||
this.animateNotificationPosition(notificationWindow, newY, done);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get startPos, calc step size and start animationInterval
|
||||
* @param notificationWindow
|
||||
* @param newY
|
||||
* @param done
|
||||
* @private
|
||||
*/
|
||||
private animateNotificationPosition(notificationWindow, newY, done) {
|
||||
const startY = notificationWindow.getPosition()[1];
|
||||
const step = (newY - startY) / this.settings.animationSteps;
|
||||
let curStep = 1;
|
||||
const animationInterval = setInterval(() => {
|
||||
// Abort condition
|
||||
if (curStep === this.settings.animationSteps) {
|
||||
this.setWindowPosition(notificationWindow, this.settings.firstPos.x, newY);
|
||||
clearInterval(animationInterval);
|
||||
done(null, 'done');
|
||||
return;
|
||||
}
|
||||
// Move one step down
|
||||
this.setWindowPosition(notificationWindow, this.settings.firstPos.x, startY + curStep * step);
|
||||
curStep++;
|
||||
}, this.settings.animationStepMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the first and next notification insert position
|
||||
*/
|
||||
|
@ -44,6 +44,8 @@ const notificationSettings = {
|
||||
animationSteps: 5,
|
||||
animationStepMs: 5,
|
||||
logging: true,
|
||||
spacing: 8,
|
||||
differentialHeight: 40,
|
||||
};
|
||||
|
||||
class Notification extends NotificationHandler {
|
||||
@ -193,8 +195,6 @@ class Notification extends NotificationHandler {
|
||||
notificationWindow.setSize(notificationSettings.width, notificationSettings.height, true);
|
||||
// Move notification to top
|
||||
notificationWindow.moveTop();
|
||||
// Reset alwaysOnTop level to normal
|
||||
notificationWindow.setAlwaysOnTop(true, 'normal');
|
||||
|
||||
if (!data.sticky) {
|
||||
timeoutId = setTimeout(async () => {
|
||||
@ -241,6 +241,7 @@ class Notification extends NotificationHandler {
|
||||
public async hideNotification(clientId: number): Promise<void> {
|
||||
const browserWindow = this.getNotificationWindow(clientId);
|
||||
if (browserWindow && windowExists(browserWindow)) {
|
||||
const [, height] = browserWindow.getSize();
|
||||
// send empty to reset the state
|
||||
const pos = this.activeNotifications.indexOf(browserWindow);
|
||||
this.activeNotifications.splice(pos, 1);
|
||||
@ -252,7 +253,7 @@ class Notification extends NotificationHandler {
|
||||
browserWindow.close();
|
||||
}
|
||||
|
||||
this.moveNotificationDown(pos, this.activeNotifications);
|
||||
this.moveNotificationDown(pos, this.activeNotifications, height);
|
||||
|
||||
if (this.notificationQueue.length > 0 && this.activeNotifications.length < this.settings.maxVisibleNotifications) {
|
||||
const notificationData = this.notificationQueue[0];
|
||||
@ -345,7 +346,7 @@ class Notification extends NotificationHandler {
|
||||
|
||||
// recalculate notification position
|
||||
this.setupNotificationPosition();
|
||||
this.moveNotificationDown(0, this.activeNotifications);
|
||||
this.moveNotificationDown(0, this.activeNotifications, 0, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -415,20 +416,6 @@ class Notification extends NotificationHandler {
|
||||
if (windowExists(window)) {
|
||||
this.renderNotification(window, data);
|
||||
}
|
||||
// This is a workaround to make sure the notification
|
||||
// with visible input always stays on top of normal notifications
|
||||
if (isWindowsOS) {
|
||||
this.activeNotifications.forEach((activeNotification) => {
|
||||
if (!activeNotification || !windowExists(activeNotification)) {
|
||||
return;
|
||||
}
|
||||
const [, height] = activeNotification.getSize();
|
||||
// Height of notification window with input will be 104
|
||||
if (height > notificationSettings.height) {
|
||||
activeNotification.moveTop();
|
||||
}
|
||||
});
|
||||
}
|
||||
return resolve(window);
|
||||
});
|
||||
});
|
||||
@ -441,7 +428,7 @@ class Notification extends NotificationHandler {
|
||||
* @param data {INotificationData}
|
||||
*/
|
||||
private renderNotification(notificationWindow, data): void {
|
||||
this.calcNextInsertPos(this.activeNotifications.length);
|
||||
this.calcNextInsertPos(this.activeNotifications);
|
||||
this.setWindowPosition(notificationWindow, this.nextInsertPos.x, this.nextInsertPos.y);
|
||||
this.setNotificationContent(notificationWindow, { ...data, windowId: notificationWindow.id });
|
||||
this.activeNotifications.push(notificationWindow);
|
||||
@ -518,8 +505,9 @@ class Notification extends NotificationHandler {
|
||||
return;
|
||||
}
|
||||
clearTimeout(notificationWindow.displayTimer);
|
||||
notificationWindow.setAlwaysOnTop(true, 'pop-up-menu');
|
||||
notificationWindow.setSize(344, CONTAINER_HEIGHT_WITH_INPUT, true);
|
||||
const pos = this.activeNotifications.indexOf(notificationWindow) + 1;
|
||||
this.moveNotificationUp(pos, this.activeNotifications);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user