mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
SDA-4300 (Fix issues related to call toast notification) (#1961)
* SDA-4300 - Fix issues related to call toast notification * SDA-4300 - Fix timer GitHub action issue
This commit is contained in:
parent
881df90d46
commit
80df59784d
@ -1,5 +1,5 @@
|
|||||||
import { app, powerMonitor, WebContents } from 'electron';
|
import { app, powerMonitor, WebContents } from 'electron';
|
||||||
import Timer = NodeJS.Timer;
|
import Timeout = NodeJS.Timeout;
|
||||||
|
|
||||||
import { logger } from '../common/logger';
|
import { logger } from '../common/logger';
|
||||||
import { windowHandler } from './window-handler';
|
import { windowHandler } from './window-handler';
|
||||||
@ -7,8 +7,8 @@ import { windowHandler } from './window-handler';
|
|||||||
class ActivityDetection {
|
class ActivityDetection {
|
||||||
private idleThreshold: number;
|
private idleThreshold: number;
|
||||||
private window: WebContents | null;
|
private window: WebContents | null;
|
||||||
private timer: Timer | undefined;
|
private timer: Timeout | undefined;
|
||||||
private queryInterval: NodeJS.Timer | undefined;
|
private queryInterval: Timeout | undefined;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.idleThreshold = 60 * 60 * 1000;
|
this.idleThreshold = 60 * 60 * 1000;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// regex match the semver (semantic version) this checks for the pattern X.Y.Z
|
// regex match the semver (semantic version) this checks for the pattern X.Y.Z
|
||||||
// ex-valid v1.2.0, 1.2.0, 2.3.4-r51
|
// ex-valid v1.2.0, 1.2.0, 2.3.4-r51
|
||||||
const semver = /^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?)?)?$/i;
|
const semver =
|
||||||
|
/^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?)?)?$/i;
|
||||||
const patch = /-([0-9A-Za-z-.]+)/;
|
const patch = /-([0-9A-Za-z-.]+)/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -205,7 +206,7 @@ export const throttle = (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let timer: NodeJS.Timer;
|
let timer: NodeJS.Timeout;
|
||||||
let lastRan = 0;
|
let lastRan = 0;
|
||||||
|
|
||||||
return (...args) => {
|
return (...args) => {
|
||||||
@ -213,7 +214,9 @@ export const throttle = (
|
|||||||
func.apply(null, args);
|
func.apply(null, args);
|
||||||
lastRan = Date.now();
|
lastRan = Date.now();
|
||||||
} else {
|
} else {
|
||||||
|
if (timer) {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
|
}
|
||||||
timer = setTimeout(() => {
|
timer = setTimeout(() => {
|
||||||
if (Date.now() - lastRan >= wait) {
|
if (Date.now() - lastRan >= wait) {
|
||||||
func.apply(null, args);
|
func.apply(null, args);
|
||||||
|
@ -48,10 +48,11 @@ export default class CallNotification extends React.Component<
|
|||||||
onAccept: (data) => (event: mouseEventButton) => this.accept(event, data),
|
onAccept: (data) => (event: mouseEventButton) => this.accept(event, data),
|
||||||
onReject: (data) => (event: mouseEventButton) => this.reject(event, data),
|
onReject: (data) => (event: mouseEventButton) => this.reject(event, data),
|
||||||
};
|
};
|
||||||
|
private readonly defaultState: ICallNotificationState;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.defaultState = {
|
||||||
title: 'Incoming call',
|
title: 'Incoming call',
|
||||||
primaryText: 'unknown',
|
primaryText: 'unknown',
|
||||||
secondaryText: '',
|
secondaryText: '',
|
||||||
@ -68,6 +69,7 @@ export default class CallNotification extends React.Component<
|
|||||||
isExternal: false,
|
isExternal: false,
|
||||||
theme: '',
|
theme: '',
|
||||||
};
|
};
|
||||||
|
this.state = { ...this.defaultState };
|
||||||
this.updateState = this.updateState.bind(this);
|
this.updateState = this.updateState.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,11 +136,7 @@ export default class CallNotification extends React.Component<
|
|||||||
: callType === 'IM' || callType === 'ROOM'
|
: callType === 'IM' || callType === 'ROOM'
|
||||||
? 'join'
|
? 'join'
|
||||||
: 'answer';
|
: 'answer';
|
||||||
const rejectText = rejectButtonText
|
const rejectText = rejectButtonText ? rejectButtonText : 'decline';
|
||||||
? rejectButtonText
|
|
||||||
: callType === 'IM' || callType === 'ROOM'
|
|
||||||
? 'ignore'
|
|
||||||
: 'decline';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -165,17 +163,25 @@ export default class CallNotification extends React.Component<
|
|||||||
<div className='caller-name-container'>
|
<div className='caller-name-container'>
|
||||||
<div
|
<div
|
||||||
data-testid='CALL_NOTIFICATION_NAME'
|
data-testid='CALL_NOTIFICATION_NAME'
|
||||||
className={`caller-name ${themeClassName}`}
|
className={`caller-name ${themeClassName} tooltip-trigger`}
|
||||||
>
|
>
|
||||||
{primaryText}
|
{primaryText}
|
||||||
</div>
|
</div>
|
||||||
|
<div className='tooltip-content tooltip-primary'>
|
||||||
|
{primaryText}
|
||||||
|
</div>
|
||||||
{this.renderExtBadge(isExternal)}
|
{this.renderExtBadge(isExternal)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{secondaryText ? (
|
{secondaryText ? (
|
||||||
<div className='secondary-text-container'>
|
<div className='secondary-text-container'>
|
||||||
<div className='caller-details'>
|
<div className='caller-details'>
|
||||||
<div className={`caller-role ${themeClassName}`}>
|
<div
|
||||||
|
className={`caller-role ${themeClassName} tooltip-trigger`}
|
||||||
|
>
|
||||||
|
{secondaryText}
|
||||||
|
</div>
|
||||||
|
<div className='tooltip-content tooltip-secondary'>
|
||||||
{secondaryText}
|
{secondaryText}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -264,6 +270,7 @@ export default class CallNotification extends React.Component<
|
|||||||
* @param data {Object}
|
* @param data {Object}
|
||||||
*/
|
*/
|
||||||
private updateState(_event, data): void {
|
private updateState(_event, data): void {
|
||||||
|
this.setState({ ...this.defaultState });
|
||||||
const { color } = data;
|
const { color } = data;
|
||||||
// FYI: 1.5 sends hex color but without '#', reason why we check and add prefix if necessary.
|
// FYI: 1.5 sends hex color but without '#', reason why we check and add prefix if necessary.
|
||||||
// Goal is to keep backward compatibility with 1.5 colors (SDA v. 9.2.0)
|
// Goal is to keep backward compatibility with 1.5 colors (SDA v. 9.2.0)
|
||||||
@ -305,7 +312,7 @@ export default class CallNotification extends React.Component<
|
|||||||
alt = 'Profile picture';
|
alt = 'Profile picture';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!imageUrl) {
|
if (!imageUrl || isDefaultUrl) {
|
||||||
const profilePlaceHolderClassName =
|
const profilePlaceHolderClassName =
|
||||||
callType === 'IM'
|
callType === 'IM'
|
||||||
? 'profilePlaceHolderContainer'
|
? 'profilePlaceHolderContainer'
|
||||||
|
@ -31,7 +31,7 @@ const CONTAINER_WIDTH = 363;
|
|||||||
interface ICustomBrowserWindow extends Electron.BrowserWindow {
|
interface ICustomBrowserWindow extends Electron.BrowserWindow {
|
||||||
winName: string;
|
winName: string;
|
||||||
notificationData: INotificationData;
|
notificationData: INotificationData;
|
||||||
displayTimer: NodeJS.Timer;
|
displayTimer: NodeJS.Timeout;
|
||||||
clientId: number;
|
clientId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ class Notification extends NotificationHandler {
|
|||||||
};
|
};
|
||||||
private activeNotifications: ICustomBrowserWindow[] = [];
|
private activeNotifications: ICustomBrowserWindow[] = [];
|
||||||
private inactiveWindows: ICustomBrowserWindow[] = [];
|
private inactiveWindows: ICustomBrowserWindow[] = [];
|
||||||
private cleanUpTimer: NodeJS.Timer;
|
private cleanUpTimer: NodeJS.Timeout;
|
||||||
private notificationQueue: INotificationData[] = [];
|
private notificationQueue: INotificationData[] = [];
|
||||||
|
|
||||||
private readonly notificationCallbacks: any[] = [];
|
private readonly notificationCallbacks: any[] = [];
|
||||||
|
@ -140,6 +140,7 @@ body {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
position: relative;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,6 +267,10 @@ text {
|
|||||||
|
|
||||||
.decline {
|
.decline {
|
||||||
background-color: @red-50;
|
background-color: @red-50;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: @red-40;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-icon {
|
.action-icon {
|
||||||
@ -274,6 +279,45 @@ text {
|
|||||||
|
|
||||||
.accept {
|
.accept {
|
||||||
background-color: @green-50;
|
background-color: @green-50;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: @green-40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-content {
|
||||||
|
visibility: hidden;
|
||||||
|
background-color: #333;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
left: 50%;
|
||||||
|
width: auto;
|
||||||
|
max-width: 200px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
height: auto;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s, visibility 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-primary {
|
||||||
|
bottom: 50%;
|
||||||
|
}
|
||||||
|
.tooltip-secondary {
|
||||||
|
bottom: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-trigger {
|
||||||
|
&:hover {
|
||||||
|
& + .tooltip-content {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.light-flashing {
|
.light-flashing {
|
||||||
|
@ -30,4 +30,6 @@
|
|||||||
|
|
||||||
@red-05: #fbeeed;
|
@red-05: #fbeeed;
|
||||||
@red-50: #dd342e;
|
@red-50: #dd342e;
|
||||||
|
@red-40: #ff5d50;
|
||||||
@green-50: #378535;
|
@green-50: #378535;
|
||||||
|
@green-40: #2eaa35;
|
||||||
|
13
src/renderer/styles/tool-tip.less
Normal file
13
src/renderer/styles/tool-tip.less
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.tooltip {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100px;
|
||||||
|
height: 50px;
|
||||||
|
background-color: red;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 999999;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user