mirror of
https://github.com/finos/SymphonyElectron.git
synced 2024-12-28 09:51:06 -06:00
Merge pull request #1750 from sbenmoussati/bugfix/presence-update
SDA-4070 IDLE presence status bugfix
This commit is contained in:
commit
4537fb3173
@ -295,10 +295,8 @@ ipcMain.on(
|
||||
// Update App Menu
|
||||
const appMenu = windowHandler.appMenu;
|
||||
const mainWindow = windowHandler.getMainWindow();
|
||||
|
||||
if (mainWebContents) {
|
||||
const items = presenceStatus.createThumbarButtons(mainWebContents);
|
||||
|
||||
const items = presenceStatus.createThumbarButtons();
|
||||
mainWindow?.setThumbarButtons(items);
|
||||
logger.info('main-api-handler: Add actions preview menu');
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { app, Menu, nativeImage, WebContents } from 'electron';
|
||||
import { app, Menu, nativeImage } from 'electron';
|
||||
import {
|
||||
EPresenceStatus,
|
||||
EPresenceStatusCategory,
|
||||
EPresenceStatusGroup,
|
||||
IPresenceStatus,
|
||||
IThumbarButton,
|
||||
} from '../common/api-interface';
|
||||
@ -20,70 +21,89 @@ export interface IListItem {
|
||||
class PresenceStatus {
|
||||
private NAMESPACE = 'PresenceStatus';
|
||||
|
||||
public createThumbarButtons = (
|
||||
webContents: WebContents,
|
||||
): IThumbarButton[] => {
|
||||
public createThumbarButtons = (): IThumbarButton[] => {
|
||||
return [
|
||||
{
|
||||
click: () => {
|
||||
logger.info('presence-status-handler: Available Clicked');
|
||||
this.setPresenceStatus(webContents, EPresenceStatus.AVAILABLE);
|
||||
this.handlePresenceChange(
|
||||
EPresenceStatusCategory.AVAILABLE,
|
||||
EPresenceStatusGroup.ONLINE,
|
||||
);
|
||||
},
|
||||
icon: nativeImage.createFromPath(
|
||||
presenceStatusStore.generateImagePath(
|
||||
EPresenceStatus.AVAILABLE,
|
||||
EPresenceStatusGroup.ONLINE,
|
||||
'thumbnail',
|
||||
),
|
||||
),
|
||||
tooltip: i18n.t(EPresenceStatus.AVAILABLE, this.NAMESPACE)(),
|
||||
tooltip: i18n.t(EPresenceStatusCategory.AVAILABLE, this.NAMESPACE)(),
|
||||
},
|
||||
{
|
||||
click: () => {
|
||||
logger.info('presence-status-handler: Busy Clicked');
|
||||
this.setPresenceStatus(webContents, EPresenceStatus.BUSY);
|
||||
this.handlePresenceChange(
|
||||
EPresenceStatusCategory.BUSY,
|
||||
EPresenceStatusGroup.BUSY,
|
||||
);
|
||||
},
|
||||
icon: nativeImage.createFromPath(
|
||||
presenceStatusStore.generateImagePath(
|
||||
EPresenceStatus.BUSY,
|
||||
EPresenceStatusGroup.BUSY,
|
||||
'thumbnail',
|
||||
),
|
||||
),
|
||||
tooltip: i18n.t(EPresenceStatus.BUSY, this.NAMESPACE)(),
|
||||
tooltip: i18n.t(EPresenceStatusCategory.BUSY, this.NAMESPACE)(),
|
||||
},
|
||||
{
|
||||
click: () => {
|
||||
logger.info('presence-status-handler: Be Right Back Clicked');
|
||||
this.setPresenceStatus(webContents, EPresenceStatus.BE_RIGHT_BACK);
|
||||
this.handlePresenceChange(
|
||||
EPresenceStatusCategory.BE_RIGHT_BACK,
|
||||
EPresenceStatusGroup.IDLE,
|
||||
);
|
||||
},
|
||||
icon: nativeImage.createFromPath(
|
||||
presenceStatusStore.generateImagePath(
|
||||
EPresenceStatus.BE_RIGHT_BACK,
|
||||
EPresenceStatusGroup.IDLE,
|
||||
'thumbnail',
|
||||
),
|
||||
),
|
||||
tooltip: i18n.t(EPresenceStatus.BE_RIGHT_BACK, this.NAMESPACE)(),
|
||||
tooltip: i18n.t(
|
||||
EPresenceStatusCategory.BE_RIGHT_BACK,
|
||||
this.NAMESPACE,
|
||||
)(),
|
||||
},
|
||||
{
|
||||
click: () => {
|
||||
logger.info('presence-status-handler: Out of Office Clicked');
|
||||
this.setPresenceStatus(webContents, EPresenceStatus.OUT_OF_OFFICE);
|
||||
this.handlePresenceChange(
|
||||
EPresenceStatusCategory.OUT_OF_OFFICE,
|
||||
EPresenceStatusGroup.ABSENT,
|
||||
);
|
||||
},
|
||||
icon: nativeImage.createFromPath(
|
||||
presenceStatusStore.generateImagePath(
|
||||
EPresenceStatus.OUT_OF_OFFICE,
|
||||
EPresenceStatusGroup.ABSENT,
|
||||
'thumbnail',
|
||||
),
|
||||
),
|
||||
tooltip: i18n.t(EPresenceStatus.OUT_OF_OFFICE, this.NAMESPACE)(),
|
||||
tooltip: i18n.t(
|
||||
EPresenceStatusCategory.OUT_OF_OFFICE,
|
||||
this.NAMESPACE,
|
||||
)(),
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
public setMyPresence = (myPresence: IPresenceStatus) => {
|
||||
const currentPresenceStatus = presenceStatusStore.getStatus();
|
||||
const currentPresence = presenceStatusStore.getPresence();
|
||||
const count = presenceStatusStore.getNotificationCount();
|
||||
if (currentPresenceStatus !== myPresence.category) {
|
||||
presenceStatusStore.setStatus(myPresence.category);
|
||||
if (
|
||||
currentPresence.statusCategory !== myPresence.statusCategory ||
|
||||
currentPresence.statusGroup !== myPresence.statusGroup
|
||||
) {
|
||||
presenceStatusStore.setPresence(myPresence);
|
||||
this.updateSystemTrayPresence();
|
||||
}
|
||||
showBadgeCount(count);
|
||||
@ -95,10 +115,10 @@ class PresenceStatus {
|
||||
* @param count {number}
|
||||
*/
|
||||
public updateSystemTrayPresence = (): void => {
|
||||
const status = presenceStatusStore.getStatus();
|
||||
const presence = presenceStatusStore.getPresence();
|
||||
let tray = presenceStatusStore.getCurrentTray();
|
||||
const backgroundImage = presenceStatusStore.generateImagePath(
|
||||
status,
|
||||
presence.statusGroup,
|
||||
'tray',
|
||||
);
|
||||
if (!backgroundImage) {
|
||||
@ -111,7 +131,6 @@ class PresenceStatus {
|
||||
tray.setImage(backgroundImage);
|
||||
logger.info('presence-status-handler: new Symphony status updated');
|
||||
}
|
||||
const currentStatus = presenceStatusStore.getStatus();
|
||||
const presenceNamespace = 'PresenceStatus';
|
||||
const isMana = !!windowHandler.isMana;
|
||||
const contextMenu = Menu.buildFromTemplate([
|
||||
@ -121,39 +140,57 @@ class PresenceStatus {
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
label: i18n.t(EPresenceStatus.AVAILABLE, presenceNamespace)(),
|
||||
label: i18n.t(EPresenceStatusCategory.AVAILABLE, presenceNamespace)(),
|
||||
type: 'checkbox',
|
||||
visible: isMana,
|
||||
checked: currentStatus === EPresenceStatus.AVAILABLE,
|
||||
checked: presence.statusGroup === EPresenceStatusGroup.ONLINE,
|
||||
click: () => {
|
||||
this.handlePresenceChange(EPresenceStatus.AVAILABLE);
|
||||
this.handlePresenceChange(
|
||||
EPresenceStatusCategory.AVAILABLE,
|
||||
EPresenceStatusGroup.ONLINE,
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.t(EPresenceStatus.BUSY, presenceNamespace)(),
|
||||
label: i18n.t(EPresenceStatusCategory.BUSY, presenceNamespace)(),
|
||||
type: 'checkbox',
|
||||
visible: isMana,
|
||||
checked: currentStatus === EPresenceStatus.BUSY,
|
||||
checked: presence.statusGroup === EPresenceStatusGroup.BUSY,
|
||||
click: () => {
|
||||
this.handlePresenceChange(EPresenceStatus.BUSY);
|
||||
this.handlePresenceChange(
|
||||
EPresenceStatusCategory.BUSY,
|
||||
EPresenceStatusGroup.BUSY,
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.t(EPresenceStatus.BE_RIGHT_BACK, presenceNamespace)(),
|
||||
label: i18n.t(
|
||||
EPresenceStatusCategory.BE_RIGHT_BACK,
|
||||
presenceNamespace,
|
||||
)(),
|
||||
type: 'checkbox',
|
||||
visible: isMana,
|
||||
checked: currentStatus === EPresenceStatus.BE_RIGHT_BACK,
|
||||
checked: presence.statusGroup === EPresenceStatusGroup.IDLE,
|
||||
click: () => {
|
||||
this.handlePresenceChange(EPresenceStatus.BE_RIGHT_BACK);
|
||||
this.handlePresenceChange(
|
||||
EPresenceStatusCategory.BE_RIGHT_BACK,
|
||||
EPresenceStatusGroup.IDLE,
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.t(EPresenceStatus.OUT_OF_OFFICE, presenceNamespace)(),
|
||||
label: i18n.t(
|
||||
EPresenceStatusCategory.OUT_OF_OFFICE,
|
||||
presenceNamespace,
|
||||
)(),
|
||||
type: 'checkbox',
|
||||
visible: isMana,
|
||||
checked: currentStatus === EPresenceStatus.OUT_OF_OFFICE,
|
||||
checked: presence.statusGroup === EPresenceStatusGroup.OFFLINE,
|
||||
click: () => {
|
||||
this.handlePresenceChange(EPresenceStatus.OUT_OF_OFFICE);
|
||||
this.handlePresenceChange(
|
||||
EPresenceStatusCategory.OUT_OF_OFFICE,
|
||||
EPresenceStatusGroup.OFFLINE,
|
||||
);
|
||||
},
|
||||
},
|
||||
{ type: 'separator', visible: isMana },
|
||||
@ -165,27 +202,21 @@ class PresenceStatus {
|
||||
tray?.setContextMenu(contextMenu);
|
||||
};
|
||||
|
||||
private handlePresenceChange = (currentStatus: EPresenceStatus) => {
|
||||
const status = {
|
||||
category: currentStatus,
|
||||
statusGroup: '',
|
||||
private handlePresenceChange = (
|
||||
statusCategory: EPresenceStatusCategory,
|
||||
statusGroup: EPresenceStatusGroup,
|
||||
) => {
|
||||
const status: IPresenceStatus = {
|
||||
statusCategory,
|
||||
statusGroup,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
presenceStatus.setMyPresence(status);
|
||||
const mainWebContents = windowHandler.getMainWebContents();
|
||||
if (mainWebContents) {
|
||||
mainWebContents.send('send-presence-status-data', currentStatus);
|
||||
mainWebContents.send('send-presence-status-data', status.statusCategory);
|
||||
}
|
||||
};
|
||||
|
||||
private setPresenceStatus = (
|
||||
webContents: WebContents,
|
||||
status: EPresenceStatus,
|
||||
) => {
|
||||
webContents.send('send-presence-status-data', status);
|
||||
presenceStatusStore.setStatus(status);
|
||||
this.updateSystemTrayPresence();
|
||||
};
|
||||
}
|
||||
|
||||
const presenceStatus = new PresenceStatus();
|
||||
|
@ -1,7 +1,9 @@
|
||||
import { nativeTheme, Tray } from 'electron';
|
||||
import * as path from 'path';
|
||||
import {
|
||||
EPresenceStatus,
|
||||
EPresenceStatusCategory,
|
||||
EPresenceStatusGroup,
|
||||
IPresenceStatus,
|
||||
IStatusBadge,
|
||||
ITray,
|
||||
} from '../../common/api-interface';
|
||||
@ -11,23 +13,25 @@ import { isMac, isWindowsOS } from '../../common/env';
|
||||
|
||||
export class PresenceStatus {
|
||||
private presenceStatus: IStatusBadge = {
|
||||
status: EPresenceStatus.NO_PRESENCE,
|
||||
statusCategory: EPresenceStatusCategory.NO_PRESENCE,
|
||||
statusGroup: EPresenceStatusGroup.OFFLINE,
|
||||
count: 0,
|
||||
};
|
||||
private tray: ITray = {
|
||||
current: null,
|
||||
};
|
||||
|
||||
public setStatus = (status: EPresenceStatus) => {
|
||||
this.presenceStatus.status = status;
|
||||
public setPresence = (presence: IPresenceStatus) => {
|
||||
this.presenceStatus.statusCategory = presence.statusCategory;
|
||||
this.presenceStatus.statusGroup = presence.statusGroup;
|
||||
};
|
||||
|
||||
public setNotificationCount = (count: number) => {
|
||||
this.presenceStatus.count = count;
|
||||
};
|
||||
|
||||
public getStatus = () => {
|
||||
return this.presenceStatus.status;
|
||||
public getPresence = () => {
|
||||
return this.presenceStatus;
|
||||
};
|
||||
|
||||
public getNotificationCount = () => {
|
||||
@ -46,7 +50,10 @@ export class PresenceStatus {
|
||||
}
|
||||
};
|
||||
|
||||
public generateImagePath = (status: EPresenceStatus, place: string) => {
|
||||
public generateImagePath = (
|
||||
statusGroup: EPresenceStatusGroup,
|
||||
place: string,
|
||||
) => {
|
||||
let backgroundImage: string = '';
|
||||
const os = isWindowsOS ? 'windows' : isMac ? 'macOS' : 'linux';
|
||||
const theme = nativeTheme.shouldUseDarkColors ? 'light' : 'dark';
|
||||
@ -65,30 +72,30 @@ export class PresenceStatus {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (status) {
|
||||
case EPresenceStatus.AVAILABLE:
|
||||
switch (statusGroup) {
|
||||
case EPresenceStatusGroup.ONLINE:
|
||||
backgroundImage = `../../../${assetsPath}/${`available${iconPlace}.${fileExtension}`}`;
|
||||
break;
|
||||
|
||||
case EPresenceStatus.BUSY:
|
||||
case EPresenceStatusGroup.BUSY:
|
||||
backgroundImage = `../../../${assetsPath}/busy${iconPlace}.${fileExtension}`;
|
||||
break;
|
||||
|
||||
case EPresenceStatus.BE_RIGHT_BACK || EPresenceStatus.AWAY:
|
||||
case EPresenceStatusGroup.IDLE:
|
||||
backgroundImage = `../../../${assetsPath}/brb${iconPlace}.${fileExtension}`;
|
||||
break;
|
||||
|
||||
case EPresenceStatus.OFFLINE:
|
||||
case EPresenceStatusGroup.OFFLINE:
|
||||
backgroundImage = `../../../${assetsPath}/offline${iconPlace}.${fileExtension}`;
|
||||
break;
|
||||
|
||||
case EPresenceStatus.OUT_OF_OFFICE:
|
||||
case EPresenceStatusGroup.ABSENT:
|
||||
backgroundImage = `../../../${assetsPath}/out-of-office${iconPlace}.${fileExtension}`;
|
||||
break;
|
||||
case EPresenceStatus.IN_A_MEETING:
|
||||
case EPresenceStatusGroup.MEETING:
|
||||
backgroundImage = `../../../${assetsPath}/in-a-meeting${iconPlace}.${fileExtension}`;
|
||||
break;
|
||||
case EPresenceStatus.NO_PRESENCE:
|
||||
case EPresenceStatusGroup.HIDE_PRESENCE:
|
||||
backgroundImage = `../../../${assetsPath}/no-status${iconPlace}.${fileExtension}`;
|
||||
break;
|
||||
default:
|
||||
|
@ -20,7 +20,7 @@ import * as path from 'path';
|
||||
import { format, parse } from 'url';
|
||||
import {
|
||||
apiName,
|
||||
EPresenceStatus,
|
||||
EPresenceStatusGroup,
|
||||
// IStatusBadge,
|
||||
} from '../common/api-interface';
|
||||
|
||||
@ -288,14 +288,14 @@ export const showBadgeCount = (count: number): void => {
|
||||
mainWebContents.send('create-badge-data-url', { count });
|
||||
return;
|
||||
} else {
|
||||
const status = presenceStatusStore.getStatus();
|
||||
const status = presenceStatusStore.getPresence();
|
||||
const backgroundImage = presenceStatusStore.generateImagePath(
|
||||
status,
|
||||
status.statusGroup,
|
||||
'taskbar',
|
||||
);
|
||||
|
||||
if (backgroundImage) {
|
||||
setStatusBadge(backgroundImage, status);
|
||||
setStatusBadge(backgroundImage, status.statusGroup);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -336,13 +336,16 @@ export const initSysTray = () => {
|
||||
*/
|
||||
export const setStatusBadge = (
|
||||
path: string,
|
||||
status?: EPresenceStatus,
|
||||
statusGroup?: EPresenceStatusGroup,
|
||||
): void => {
|
||||
const mainWindow = windowHandler.getMainWindow();
|
||||
if (mainWindow && path && status) {
|
||||
if (mainWindow && path && statusGroup) {
|
||||
const img = nativeImage.createFromPath(path);
|
||||
// for accessibility screen readers
|
||||
const desc = `Your current status is ${i18n.t(status, 'PresenceStatus')()}`;
|
||||
const desc = `Your current status group is ${i18n.t(
|
||||
statusGroup,
|
||||
'PresenceStatus',
|
||||
)()}`;
|
||||
mainWindow.setOverlayIcon(img, desc);
|
||||
logger.info('window-utils: Taskbar Presence Updated');
|
||||
}
|
||||
|
@ -177,7 +177,8 @@ export interface IThumbarButton {
|
||||
}
|
||||
|
||||
export interface IStatusBadge extends IBadgeCount {
|
||||
status: EPresenceStatus;
|
||||
statusCategory: EPresenceStatusCategory;
|
||||
statusGroup: EPresenceStatusGroup;
|
||||
}
|
||||
|
||||
export interface ITray {
|
||||
@ -189,7 +190,7 @@ export interface IPresenceStore {
|
||||
presenceStatus: IPresenceStatus;
|
||||
}
|
||||
|
||||
export enum EPresenceStatus {
|
||||
export enum EPresenceStatusCategory {
|
||||
'ONLINE' = 'ONLINE',
|
||||
'OFFLINE' = 'OFFLINE',
|
||||
'AWAY' = 'AWAY',
|
||||
@ -204,9 +205,19 @@ export enum EPresenceStatus {
|
||||
'NO_PRESENCE' = 'NO_PRESENCE',
|
||||
}
|
||||
|
||||
export enum EPresenceStatusGroup {
|
||||
ONLINE = 'online',
|
||||
BUSY = 'busy',
|
||||
IDLE = 'idle',
|
||||
OFFLINE = 'offline',
|
||||
ABSENT = 'absent',
|
||||
MEETING = 'meeting',
|
||||
HIDE_PRESENCE = 'hide',
|
||||
}
|
||||
|
||||
export interface IPresenceStatus {
|
||||
category: EPresenceStatus;
|
||||
statusGroup: string;
|
||||
statusCategory: EPresenceStatusCategory;
|
||||
statusGroup: EPresenceStatusGroup;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
apiCmds,
|
||||
apiName,
|
||||
ConfigUpdateType,
|
||||
EPresenceStatus,
|
||||
EPresenceStatusCategory,
|
||||
IBoundsChange,
|
||||
ICloud9Pipe,
|
||||
ICPUUsage,
|
||||
@ -60,7 +60,7 @@ export interface ILocalObject {
|
||||
>;
|
||||
c9PipeEventCallback?: (event: string, arg?: any) => void;
|
||||
c9MessageCallback?: (status: IShellStatus) => void;
|
||||
updateMyPresenceCallback?: (presence: EPresenceStatus) => void;
|
||||
updateMyPresenceCallback?: (presence: EPresenceStatusCategory) => void;
|
||||
}
|
||||
|
||||
const local: ILocalObject = {
|
||||
@ -374,7 +374,9 @@ export class SSFApi {
|
||||
* It will only trigger if you hit any button at presence-status-handler
|
||||
*
|
||||
*/
|
||||
public updateMyPresence(callback: (category: EPresenceStatus) => void) {
|
||||
public updateMyPresence(
|
||||
callback: (category: EPresenceStatusCategory) => void,
|
||||
) {
|
||||
if (typeof callback === 'function') {
|
||||
local.updateMyPresenceCallback = callback;
|
||||
}
|
||||
@ -932,7 +934,7 @@ local.ipcRenderer.on(
|
||||
|
||||
local.ipcRenderer.on(
|
||||
'send-presence-status-data',
|
||||
(_event: Event, arg: EPresenceStatus) => {
|
||||
(_event: Event, arg: EPresenceStatusCategory) => {
|
||||
if (typeof local.updateMyPresenceCallback === 'function') {
|
||||
local.updateMyPresenceCallback(arg);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user