Fix notifications not working (#2865)
* Fix notifications not working * Transform into a manager * Remove test accessor
This commit is contained in:

committed by
GitHub

parent
02261c9de3
commit
9aec7db821
@@ -96,7 +96,8 @@
|
|||||||
"src/main/**/*.ts"
|
"src/main/**/*.ts"
|
||||||
],
|
],
|
||||||
"testMatch": [
|
"testMatch": [
|
||||||
"**/src/**/*.test.js"
|
"**/src/**/*.test.js",
|
||||||
|
"**/src/**/*.test.ts"
|
||||||
],
|
],
|
||||||
"testPathIgnorePatterns": [
|
"testPathIgnorePatterns": [
|
||||||
"/node_modules/",
|
"/node_modules/",
|
||||||
|
@@ -12,7 +12,7 @@ import {Logger} from 'common/log';
|
|||||||
import ServerManager from 'common/servers/serverManager';
|
import ServerManager from 'common/servers/serverManager';
|
||||||
import {ping} from 'common/utils/requests';
|
import {ping} from 'common/utils/requests';
|
||||||
|
|
||||||
import {displayMention} from 'main/notifications';
|
import NotificationManager from 'main/notifications';
|
||||||
import {getLocalPreload, getLocalURLString} from 'main/utils';
|
import {getLocalPreload, getLocalURLString} from 'main/utils';
|
||||||
import ModalManager from 'main/views/modalManager';
|
import ModalManager from 'main/views/modalManager';
|
||||||
import MainWindow from 'main/windows/mainWindow';
|
import MainWindow from 'main/windows/mainWindow';
|
||||||
@@ -116,7 +116,7 @@ export function handleWelcomeScreenModal() {
|
|||||||
|
|
||||||
export function handleMentionNotification(event: IpcMainEvent, title: string, body: string, channel: {id: string}, teamId: string, url: string, silent: boolean, data: MentionData) {
|
export function handleMentionNotification(event: IpcMainEvent, title: string, body: string, channel: {id: string}, teamId: string, url: string, silent: boolean, data: MentionData) {
|
||||||
log.debug('handleMentionNotification', {title, body, channel, teamId, url, silent, data});
|
log.debug('handleMentionNotification', {title, body, channel, teamId, url, silent, data});
|
||||||
displayMention(title, body, channel, teamId, url, silent, event.sender, data);
|
NotificationManager.displayMention(title, body, channel, teamId, url, silent, event.sender, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function handleOpenAppMenu() {
|
export function handleOpenAppMenu() {
|
||||||
|
@@ -1,13 +1,17 @@
|
|||||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import {ipcMain} from 'electron';
|
import {ipcMain as notMockedIpcMain} from 'electron';
|
||||||
import {autoUpdater} from 'electron-updater';
|
import {autoUpdater as notMockedAutoUpdater} from 'electron-updater';
|
||||||
|
|
||||||
import {CHECK_FOR_UPDATES} from 'common/communication';
|
import {CHECK_FOR_UPDATES} from 'common/communication';
|
||||||
|
|
||||||
|
import NotificationManager from 'main/notifications';
|
||||||
|
|
||||||
import {UpdateManager} from './autoUpdater';
|
import {UpdateManager} from './autoUpdater';
|
||||||
import {displayRestartToUpgrade, displayUpgrade} from './notifications';
|
|
||||||
|
const autoUpdater = jest.mocked(notMockedAutoUpdater);
|
||||||
|
const ipcMain = jest.mocked(notMockedIpcMain);
|
||||||
|
|
||||||
jest.mock('electron', () => ({
|
jest.mock('electron', () => ({
|
||||||
app: {
|
app: {
|
||||||
@@ -44,6 +48,7 @@ jest.mock('main/notifications', () => ({
|
|||||||
displayUpgrade: jest.fn(),
|
displayUpgrade: jest.fn(),
|
||||||
displayRestartToUpgrade: jest.fn(),
|
displayRestartToUpgrade: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('main/windows/mainWindow', () => ({
|
jest.mock('main/windows/mainWindow', () => ({
|
||||||
sendToRenderer: jest.fn(),
|
sendToRenderer: jest.fn(),
|
||||||
}));
|
}));
|
||||||
@@ -55,6 +60,7 @@ jest.mock('main/i18nManager', () => ({
|
|||||||
jest.mock('main/downloadsManager', () => ({
|
jest.mock('main/downloadsManager', () => ({
|
||||||
removeUpdateBeforeRestart: jest.fn(),
|
removeUpdateBeforeRestart: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('main/autoUpdater', () => {
|
describe('main/autoUpdater', () => {
|
||||||
describe('constructor', () => {
|
describe('constructor', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -62,11 +68,12 @@ describe('main/autoUpdater', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should notify user on update-available', () => {
|
it('should notify user on update-available', () => {
|
||||||
let cb;
|
let cb: any;
|
||||||
autoUpdater.on.mockImplementation((event, callback) => {
|
autoUpdater.on.mockImplementation((event, callback) => {
|
||||||
if (event === 'update-available') {
|
if (event === 'update-available') {
|
||||||
cb = callback;
|
cb = callback;
|
||||||
}
|
}
|
||||||
|
return autoUpdater;
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateManager = new UpdateManager();
|
const updateManager = new UpdateManager();
|
||||||
@@ -78,11 +85,12 @@ describe('main/autoUpdater', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should notify user on update-downloaded', () => {
|
it('should notify user on update-downloaded', () => {
|
||||||
let cb;
|
let cb: any;
|
||||||
autoUpdater.on.mockImplementation((event, callback) => {
|
autoUpdater.on.mockImplementation((event, callback) => {
|
||||||
if (event === 'update-downloaded') {
|
if (event === 'update-downloaded') {
|
||||||
cb = callback;
|
cb = callback;
|
||||||
}
|
}
|
||||||
|
return autoUpdater;
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateManager = new UpdateManager();
|
const updateManager = new UpdateManager();
|
||||||
@@ -94,11 +102,12 @@ describe('main/autoUpdater', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should check for updates when emitted', () => {
|
it('should check for updates when emitted', () => {
|
||||||
let cb;
|
let cb: any;
|
||||||
ipcMain.on.mockImplementation((event, callback) => {
|
ipcMain.on.mockImplementation((event, callback) => {
|
||||||
if (event === CHECK_FOR_UPDATES) {
|
if (event === CHECK_FOR_UPDATES) {
|
||||||
cb = callback;
|
cb = callback;
|
||||||
}
|
}
|
||||||
|
return ipcMain;
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateManager = new UpdateManager();
|
const updateManager = new UpdateManager();
|
||||||
@@ -133,7 +142,7 @@ describe('main/autoUpdater', () => {
|
|||||||
updateManager.versionAvailable = '5.1.0';
|
updateManager.versionAvailable = '5.1.0';
|
||||||
updateManager.notify();
|
updateManager.notify();
|
||||||
updateManager.notify = jest.fn();
|
updateManager.notify = jest.fn();
|
||||||
expect(displayUpgrade).toHaveBeenCalledWith('5.1.0', expect.any(Function));
|
expect(NotificationManager.displayUpgrade).toHaveBeenCalledWith('5.1.0', expect.any(Function));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display downloaded upgrade notification', () => {
|
it('should display downloaded upgrade notification', () => {
|
||||||
@@ -141,13 +150,13 @@ describe('main/autoUpdater', () => {
|
|||||||
updateManager.versionDownloaded = '5.1.0';
|
updateManager.versionDownloaded = '5.1.0';
|
||||||
updateManager.notify();
|
updateManager.notify();
|
||||||
updateManager.notify = jest.fn();
|
updateManager.notify = jest.fn();
|
||||||
expect(displayRestartToUpgrade).toHaveBeenCalledWith('5.1.0', expect.any(Function));
|
expect(NotificationManager.displayRestartToUpgrade).toHaveBeenCalledWith('5.1.0', expect.any(Function));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('checkForUpdates', () => {
|
describe('checkForUpdates', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
autoUpdater.checkForUpdates.mockReturnValue(Promise.resolve());
|
autoUpdater.checkForUpdates.mockReturnValue(Promise.resolve(null));
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -164,8 +173,9 @@ describe('main/autoUpdater', () => {
|
|||||||
it('should show dialog if update is not available', () => {
|
it('should show dialog if update is not available', () => {
|
||||||
autoUpdater.once.mockImplementation((event, callback) => {
|
autoUpdater.once.mockImplementation((event, callback) => {
|
||||||
if (event === 'update-not-available') {
|
if (event === 'update-not-available') {
|
||||||
callback();
|
(callback as any)();
|
||||||
}
|
}
|
||||||
|
return autoUpdater;
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateManager = new UpdateManager();
|
const updateManager = new UpdateManager();
|
||||||
@@ -177,7 +187,7 @@ describe('main/autoUpdater', () => {
|
|||||||
|
|
||||||
it('should check again at the next interval', () => {
|
it('should check again at the next interval', () => {
|
||||||
const updateManager = new UpdateManager();
|
const updateManager = new UpdateManager();
|
||||||
updateManager.checkForUpdates();
|
updateManager.checkForUpdates(false);
|
||||||
updateManager.checkForUpdates = jest.fn();
|
updateManager.checkForUpdates = jest.fn();
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
expect(updateManager.checkForUpdates).toBeCalled();
|
expect(updateManager.checkForUpdates).toBeCalled();
|
@@ -10,7 +10,7 @@ import {Logger} from 'common/log';
|
|||||||
|
|
||||||
import downloadsManager from 'main/downloadsManager';
|
import downloadsManager from 'main/downloadsManager';
|
||||||
import {localizeMessage} from 'main/i18nManager';
|
import {localizeMessage} from 'main/i18nManager';
|
||||||
import {displayUpgrade, displayRestartToUpgrade} from 'main/notifications';
|
import NotificationManager from 'main/notifications';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CANCEL_UPGRADE,
|
CANCEL_UPGRADE,
|
||||||
@@ -113,12 +113,12 @@ export class UpdateManager {
|
|||||||
|
|
||||||
notifyUpgrade = (): void => {
|
notifyUpgrade = (): void => {
|
||||||
ipcMain.emit(UPDATE_AVAILABLE, null, this.versionAvailable);
|
ipcMain.emit(UPDATE_AVAILABLE, null, this.versionAvailable);
|
||||||
displayUpgrade(this.versionAvailable || 'unknown', this.handleDownload);
|
NotificationManager.displayUpgrade(this.versionAvailable || 'unknown', this.handleDownload);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyDownloaded = (): void => {
|
notifyDownloaded = (): void => {
|
||||||
ipcMain.emit(UPDATE_DOWNLOADED, null, this.downloadedInfo);
|
ipcMain.emit(UPDATE_DOWNLOADED, null, this.downloadedInfo);
|
||||||
displayRestartToUpgrade(this.versionDownloaded || 'unknown', this.handleUpdate);
|
NotificationManager.displayRestartToUpgrade(this.versionDownloaded || 'unknown', this.handleUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDownload = (): void => {
|
handleDownload = (): void => {
|
||||||
|
@@ -31,7 +31,7 @@ import {APP_UPDATE_KEY, UPDATE_DOWNLOAD_ITEM} from 'common/constants';
|
|||||||
import {DOWNLOADS_DROPDOWN_AUTOCLOSE_TIMEOUT, DOWNLOADS_DROPDOWN_MAX_ITEMS} from 'common/utils/constants';
|
import {DOWNLOADS_DROPDOWN_AUTOCLOSE_TIMEOUT, DOWNLOADS_DROPDOWN_MAX_ITEMS} from 'common/utils/constants';
|
||||||
import * as Validator from 'common/Validator';
|
import * as Validator from 'common/Validator';
|
||||||
import {localizeMessage} from 'main/i18nManager';
|
import {localizeMessage} from 'main/i18nManager';
|
||||||
import {displayDownloadCompleted} from 'main/notifications';
|
import NotificationManager from 'main/notifications';
|
||||||
import ViewManager from 'main/views/viewManager';
|
import ViewManager from 'main/views/viewManager';
|
||||||
import MainWindow from 'main/windows/mainWindow';
|
import MainWindow from 'main/windows/mainWindow';
|
||||||
import {doubleSecToMs, getPercentage, isStringWithLength, readFilenameFromContentDispositionHeader, shouldIncrementFilename} from 'main/utils';
|
import {doubleSecToMs, getPercentage, isStringWithLength, readFilenameFromContentDispositionHeader, shouldIncrementFilename} from 'main/utils';
|
||||||
@@ -559,7 +559,7 @@ export class DownloadsManager extends JsonFileManager<DownloadedItems> {
|
|||||||
log.debug('doneEventController', {state});
|
log.debug('doneEventController', {state});
|
||||||
|
|
||||||
if (state === 'completed' && !this.open) {
|
if (state === 'completed' && !this.open) {
|
||||||
displayDownloadCompleted(path.basename(item.savePath), item.savePath, ViewManager.getViewByWebContentsId(webContents.id)?.view.server.name ?? '');
|
NotificationManager.displayDownloadCompleted(path.basename(item.savePath), item.savePath, ViewManager.getViewByWebContentsId(webContents.id)?.view.server.name ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
const bookmark = this.bookmarks.get(this.getFileId(item));
|
const bookmark = this.bookmarks.get(this.getFileId(item));
|
||||||
|
@@ -4,6 +4,8 @@
|
|||||||
import os from 'os';
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
|
import {v4 as uuid} from 'uuid';
|
||||||
|
|
||||||
import {app, Notification} from 'electron';
|
import {app, Notification} from 'electron';
|
||||||
|
|
||||||
import Utils from 'common/utils/util';
|
import Utils from 'common/utils/util';
|
||||||
@@ -22,6 +24,8 @@ const defaultOptions = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class DownloadNotification extends Notification {
|
export class DownloadNotification extends Notification {
|
||||||
|
uId: string;
|
||||||
|
|
||||||
constructor(fileName: string, serverName: string) {
|
constructor(fileName: string, serverName: string) {
|
||||||
const options = {...defaultOptions};
|
const options = {...defaultOptions};
|
||||||
if (process.platform === 'darwin' || (process.platform === 'win32' && Utils.isVersionGreaterThanOrEqualTo(os.release(), '10.0'))) {
|
if (process.platform === 'darwin' || (process.platform === 'win32' && Utils.isVersionGreaterThanOrEqualTo(os.release(), '10.0'))) {
|
||||||
@@ -33,5 +37,7 @@ export class DownloadNotification extends Notification {
|
|||||||
options.body = process.platform === 'win32' ? localizeMessage('main.notifications.download.complete.body', 'Download Complete \n {fileName}', {fileName}) : fileName;
|
options.body = process.platform === 'win32' ? localizeMessage('main.notifications.download.complete.body', 'Download Complete \n {fileName}', {fileName}) : fileName;
|
||||||
|
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
|
this.uId = uuid();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,8 @@
|
|||||||
import os from 'os';
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
|
import {v4 as uuid} from 'uuid';
|
||||||
|
|
||||||
import {app, Notification} from 'electron';
|
import {app, Notification} from 'electron';
|
||||||
|
|
||||||
import {MentionOptions} from 'types/notification';
|
import {MentionOptions} from 'types/notification';
|
||||||
@@ -27,6 +29,7 @@ export class Mention extends Notification {
|
|||||||
customSound: string;
|
customSound: string;
|
||||||
channel: {id: string}; // TODO: Channel from mattermost-redux
|
channel: {id: string}; // TODO: Channel from mattermost-redux
|
||||||
teamId: string;
|
teamId: string;
|
||||||
|
uId: string;
|
||||||
|
|
||||||
constructor(customOptions: MentionOptions, channel: {id: string}, teamId: string) {
|
constructor(customOptions: MentionOptions, channel: {id: string}, teamId: string) {
|
||||||
const options = {...defaultOptions, ...customOptions};
|
const options = {...defaultOptions, ...customOptions};
|
||||||
@@ -44,6 +47,7 @@ export class Mention extends Notification {
|
|||||||
this.customSound = customSound;
|
this.customSound = customSound;
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
this.teamId = teamId;
|
this.teamId = teamId;
|
||||||
|
this.uId = uuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
getNotificationSound = () => {
|
getNotificationSound = () => {
|
||||||
|
@@ -2,26 +2,35 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
import cp from 'child_process';
|
import notMockedCP from 'child_process';
|
||||||
|
|
||||||
import {Notification, shell, app} from 'electron';
|
import {Notification as NotMockedNotification, shell, app, BrowserWindow, WebContents} from 'electron';
|
||||||
|
|
||||||
import {getFocusAssist} from 'windows-focus-assist';
|
import {getFocusAssist as notMockedGetFocusAssist} from 'windows-focus-assist';
|
||||||
import {getDoNotDisturb as getDarwinDoNotDisturb} from 'macos-notification-state';
|
import {getDoNotDisturb as notMockedGetDarwinDoNotDisturb} from 'macos-notification-state';
|
||||||
|
|
||||||
import {PLAY_SOUND} from 'common/communication';
|
import {PLAY_SOUND} from 'common/communication';
|
||||||
import Config from 'common/config';
|
import notMockedConfig from 'common/config';
|
||||||
|
|
||||||
import {localizeMessage} from 'main/i18nManager';
|
import {localizeMessage as notMockedLocalizeMessage} from 'main/i18nManager';
|
||||||
import PermissionsManager from 'main/permissionsManager';
|
import notMockedPermissionsManager from 'main/permissionsManager';
|
||||||
import MainWindow from 'main/windows/mainWindow';
|
import notMockedMainWindow from 'main/windows/mainWindow';
|
||||||
import ViewManager from 'main/views/viewManager';
|
import ViewManager from 'main/views/viewManager';
|
||||||
|
|
||||||
import getLinuxDoNotDisturb from './dnd-linux';
|
import getLinuxDoNotDisturb from './dnd-linux';
|
||||||
|
|
||||||
import {displayMention, displayDownloadCompleted, currentNotifications} from './index';
|
import NotificationManager from './index';
|
||||||
|
|
||||||
const mentions = [];
|
const Notification = jest.mocked(NotMockedNotification);
|
||||||
|
const getFocusAssist = jest.mocked(notMockedGetFocusAssist);
|
||||||
|
const PermissionsManager = jest.mocked(notMockedPermissionsManager);
|
||||||
|
const getDarwinDoNotDisturb = jest.mocked(notMockedGetDarwinDoNotDisturb);
|
||||||
|
const Config = jest.mocked(notMockedConfig);
|
||||||
|
const MainWindow = jest.mocked(notMockedMainWindow);
|
||||||
|
const localizeMessage = jest.mocked(notMockedLocalizeMessage);
|
||||||
|
const cp = jest.mocked(notMockedCP);
|
||||||
|
|
||||||
|
const mentions: Array<{body: string; value: any}> = [];
|
||||||
|
|
||||||
jest.mock('child_process', () => ({
|
jest.mock('child_process', () => ({
|
||||||
execSync: jest.fn(),
|
execSync: jest.fn(),
|
||||||
@@ -29,25 +38,26 @@ jest.mock('child_process', () => ({
|
|||||||
|
|
||||||
jest.mock('electron', () => {
|
jest.mock('electron', () => {
|
||||||
class NotificationMock {
|
class NotificationMock {
|
||||||
|
callbackMap: Map<string, () => void>;
|
||||||
static isSupported = jest.fn();
|
static isSupported = jest.fn();
|
||||||
static didConstruct = jest.fn();
|
static didConstruct = jest.fn();
|
||||||
|
|
||||||
constructor(options) {
|
constructor(options: any) {
|
||||||
NotificationMock.didConstruct();
|
NotificationMock.didConstruct();
|
||||||
this.callbackMap = new Map();
|
this.callbackMap = new Map();
|
||||||
mentions.push({body: options.body, value: this});
|
mentions.push({body: options.body, value: this});
|
||||||
}
|
}
|
||||||
|
|
||||||
on = (event, callback) => {
|
on = (event: string, callback: () => void) => {
|
||||||
this.callbackMap.set(event, callback);
|
this.callbackMap.set(event, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
show = jest.fn().mockImplementation(() => {
|
show = jest.fn().mockImplementation(() => {
|
||||||
this.callbackMap.get('show')();
|
this.callbackMap.get('show')?.();
|
||||||
});
|
});
|
||||||
|
|
||||||
click = jest.fn().mockImplementation(() => {
|
click = jest.fn().mockImplementation(() => {
|
||||||
this.callbackMap.get('click')();
|
this.callbackMap.get('click')?.();
|
||||||
});
|
});
|
||||||
|
|
||||||
close = jest.fn();
|
close = jest.fn();
|
||||||
@@ -105,35 +115,43 @@ describe('main/notifications', () => {
|
|||||||
describe('displayMention', () => {
|
describe('displayMention', () => {
|
||||||
const mainWindow = {
|
const mainWindow = {
|
||||||
flashFrame: jest.fn(),
|
flashFrame: jest.fn(),
|
||||||
};
|
} as unknown as BrowserWindow;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
PermissionsManager.doPermissionRequest.mockReturnValue(Promise.resolve(true));
|
PermissionsManager.doPermissionRequest.mockReturnValue(Promise.resolve(true));
|
||||||
Notification.isSupported.mockImplementation(() => true);
|
Notification.isSupported.mockImplementation(() => true);
|
||||||
getFocusAssist.mockReturnValue({value: false});
|
getFocusAssist.mockReturnValue({value: 0, name: ''});
|
||||||
getDarwinDoNotDisturb.mockReturnValue(false);
|
getDarwinDoNotDisturb.mockReturnValue(false);
|
||||||
Config.notifications = {};
|
Config.notifications = {
|
||||||
|
flashWindow: 0,
|
||||||
|
bounceIcon: false,
|
||||||
|
bounceIconType: 'informational',
|
||||||
|
};
|
||||||
MainWindow.get.mockReturnValue(mainWindow);
|
MainWindow.get.mockReturnValue(mainWindow);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.resetAllMocks();
|
jest.resetAllMocks();
|
||||||
Config.notifications = {};
|
Config.notifications = {
|
||||||
|
flashWindow: 0,
|
||||||
|
bounceIcon: false,
|
||||||
|
bounceIconType: 'informational',
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should do nothing when Notification is not supported', async () => {
|
it('should do nothing when Notification is not supported', async () => {
|
||||||
Notification.isSupported.mockImplementation(() => false);
|
Notification.isSupported.mockImplementation(() => false);
|
||||||
await displayMention(
|
await NotificationManager.displayMention(
|
||||||
'test',
|
'test',
|
||||||
'test body',
|
'test body',
|
||||||
{id: 'channel_id'},
|
{id: 'channel_id'},
|
||||||
'team_id',
|
'team_id',
|
||||||
'http://server-1.com/team_id/channel_id',
|
'http://server-1.com/team_id/channel_id',
|
||||||
false,
|
false,
|
||||||
{id: 1},
|
{id: 1} as WebContents,
|
||||||
{},
|
{soundName: ''},
|
||||||
);
|
);
|
||||||
expect(Notification.didConstruct).not.toBeCalled();
|
expect(MainWindow.show).not.toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should do nothing when alarms only is enabled on windows', async () => {
|
it('should do nothing when alarms only is enabled on windows', async () => {
|
||||||
@@ -142,18 +160,18 @@ describe('main/notifications', () => {
|
|||||||
value: 'win32',
|
value: 'win32',
|
||||||
});
|
});
|
||||||
|
|
||||||
getFocusAssist.mockReturnValue({value: 2});
|
getFocusAssist.mockReturnValue({value: 2, name: ''});
|
||||||
await displayMention(
|
await NotificationManager.displayMention(
|
||||||
'test',
|
'test',
|
||||||
'test body',
|
'test body',
|
||||||
{id: 'channel_id'},
|
{id: 'channel_id'},
|
||||||
'team_id',
|
'team_id',
|
||||||
'http://server-1.com/team_id/channel_id',
|
'http://server-1.com/team_id/channel_id',
|
||||||
false,
|
false,
|
||||||
{id: 1},
|
{id: 1} as WebContents,
|
||||||
{},
|
{soundName: ''},
|
||||||
);
|
);
|
||||||
expect(Notification.didConstruct).not.toBeCalled();
|
expect(MainWindow.show).not.toBeCalled();
|
||||||
|
|
||||||
Object.defineProperty(process, 'platform', {
|
Object.defineProperty(process, 'platform', {
|
||||||
value: originalPlatform,
|
value: originalPlatform,
|
||||||
@@ -167,17 +185,17 @@ describe('main/notifications', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
getDarwinDoNotDisturb.mockReturnValue(true);
|
getDarwinDoNotDisturb.mockReturnValue(true);
|
||||||
await displayMention(
|
await NotificationManager.displayMention(
|
||||||
'test',
|
'test',
|
||||||
'test body',
|
'test body',
|
||||||
{id: 'channel_id'},
|
{id: 'channel_id'},
|
||||||
'team_id',
|
'team_id',
|
||||||
'http://server-1.com/team_id/channel_id',
|
'http://server-1.com/team_id/channel_id',
|
||||||
false,
|
false,
|
||||||
{id: 1},
|
{id: 1} as WebContents,
|
||||||
{},
|
{soundName: ''},
|
||||||
);
|
);
|
||||||
expect(Notification.didConstruct).not.toBeCalled();
|
expect(MainWindow.show).not.toBeCalled();
|
||||||
|
|
||||||
Object.defineProperty(process, 'platform', {
|
Object.defineProperty(process, 'platform', {
|
||||||
value: originalPlatform,
|
value: originalPlatform,
|
||||||
@@ -186,28 +204,28 @@ describe('main/notifications', () => {
|
|||||||
|
|
||||||
it('should do nothing when the permission check fails', async () => {
|
it('should do nothing when the permission check fails', async () => {
|
||||||
PermissionsManager.doPermissionRequest.mockReturnValue(Promise.resolve(false));
|
PermissionsManager.doPermissionRequest.mockReturnValue(Promise.resolve(false));
|
||||||
await displayMention(
|
await NotificationManager.displayMention(
|
||||||
'test',
|
'test',
|
||||||
'test body',
|
'test body',
|
||||||
{id: 'channel_id'},
|
{id: 'channel_id'},
|
||||||
'team_id',
|
'team_id',
|
||||||
'http://server-1.com/team_id/channel_id',
|
'http://server-1.com/team_id/channel_id',
|
||||||
false,
|
false,
|
||||||
{id: 1},
|
{id: 1} as WebContents,
|
||||||
{},
|
{soundName: ''},
|
||||||
);
|
);
|
||||||
expect(Notification.didConstruct).not.toBeCalled();
|
expect(MainWindow.show).not.toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should play notification sound when custom sound is provided', async () => {
|
it('should play notification sound when custom sound is provided', async () => {
|
||||||
await displayMention(
|
await NotificationManager.displayMention(
|
||||||
'test',
|
'test',
|
||||||
'test body',
|
'test body',
|
||||||
{id: 'channel_id'},
|
{id: 'channel_id'},
|
||||||
'team_id',
|
'team_id',
|
||||||
'http://server-1.com/team_id/channel_id',
|
'http://server-1.com/team_id/channel_id',
|
||||||
false,
|
false,
|
||||||
{id: 1},
|
{id: 1} as WebContents,
|
||||||
{soundName: 'test_sound'},
|
{soundName: 'test_sound'},
|
||||||
);
|
);
|
||||||
expect(MainWindow.sendToRenderer).toHaveBeenCalledWith(PLAY_SOUND, 'test_sound');
|
expect(MainWindow.sendToRenderer).toHaveBeenCalledWith(PLAY_SOUND, 'test_sound');
|
||||||
@@ -219,34 +237,36 @@ describe('main/notifications', () => {
|
|||||||
value: 'win32',
|
value: 'win32',
|
||||||
});
|
});
|
||||||
|
|
||||||
await displayMention(
|
await NotificationManager.displayMention(
|
||||||
'test',
|
'test',
|
||||||
'test body',
|
'test body',
|
||||||
{id: 'channel_id'},
|
{id: 'channel_id'},
|
||||||
'team_id',
|
'team_id',
|
||||||
'http://server-1.com/team_id/channel_id',
|
'http://server-1.com/team_id/channel_id',
|
||||||
false,
|
false,
|
||||||
{id: 1},
|
{id: 1} as WebContents,
|
||||||
{},
|
{soundName: ''},
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(currentNotifications.has('team_id:channel_id')).toBe(true);
|
// convert to any to access private field
|
||||||
|
const mentionsPerChannel = (NotificationManager as any).mentionsPerChannel;
|
||||||
|
expect(mentionsPerChannel.has('team_id:channel_id')).toBe(true);
|
||||||
|
|
||||||
const existingMention = currentNotifications.get('team_id:channel_id');
|
const existingMention = mentionsPerChannel.get('team_id:channel_id');
|
||||||
currentNotifications.delete = jest.fn();
|
mentionsPerChannel.delete = jest.fn();
|
||||||
await displayMention(
|
await NotificationManager.displayMention(
|
||||||
'test',
|
'test',
|
||||||
'test body 2',
|
'test body 2',
|
||||||
{id: 'channel_id'},
|
{id: 'channel_id'},
|
||||||
'team_id',
|
'team_id',
|
||||||
'http://server-1.com/team_id/channel_id',
|
'http://server-1.com/team_id/channel_id',
|
||||||
false,
|
false,
|
||||||
{id: 1},
|
{id: 1} as WebContents,
|
||||||
{},
|
{soundName: ''},
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(currentNotifications.delete).toHaveBeenCalled();
|
expect(mentionsPerChannel.delete).toHaveBeenCalled();
|
||||||
expect(existingMention.close).toHaveBeenCalled();
|
expect(existingMention?.close).toHaveBeenCalled();
|
||||||
|
|
||||||
Object.defineProperty(process, 'platform', {
|
Object.defineProperty(process, 'platform', {
|
||||||
value: originalPlatform,
|
value: originalPlatform,
|
||||||
@@ -254,18 +274,18 @@ describe('main/notifications', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should switch view when clicking on notification', async () => {
|
it('should switch view when clicking on notification', async () => {
|
||||||
await displayMention(
|
await NotificationManager.displayMention(
|
||||||
'click_test',
|
'click_test',
|
||||||
'mention_click_body',
|
'mention_click_body',
|
||||||
{id: 'channel_id'},
|
{id: 'channel_id'},
|
||||||
'team_id',
|
'team_id',
|
||||||
'http://server-1.com/team_id/channel_id',
|
'http://server-1.com/team_id/channel_id',
|
||||||
false,
|
false,
|
||||||
{id: 1, send: jest.fn()},
|
{id: 1, send: jest.fn()} as unknown as WebContents,
|
||||||
{},
|
{soundName: ''},
|
||||||
);
|
);
|
||||||
const mention = mentions.find((m) => m.body === 'mention_click_body');
|
const mention = mentions.find((m) => m.body === 'mention_click_body');
|
||||||
mention.value.click();
|
mention?.value.click();
|
||||||
expect(MainWindow.show).toHaveBeenCalled();
|
expect(MainWindow.show).toHaveBeenCalled();
|
||||||
expect(ViewManager.showById).toHaveBeenCalledWith('server_id');
|
expect(ViewManager.showById).toHaveBeenCalledWith('server_id');
|
||||||
});
|
});
|
||||||
@@ -275,15 +295,15 @@ describe('main/notifications', () => {
|
|||||||
Object.defineProperty(process, 'platform', {
|
Object.defineProperty(process, 'platform', {
|
||||||
value: 'linux',
|
value: 'linux',
|
||||||
});
|
});
|
||||||
await displayMention(
|
await NotificationManager.displayMention(
|
||||||
'click_test',
|
'click_test',
|
||||||
'mention_click_body',
|
'mention_click_body',
|
||||||
{id: 'channel_id'},
|
{id: 'channel_id'},
|
||||||
'team_id',
|
'team_id',
|
||||||
'http://server-1.com/team_id/channel_id',
|
'http://server-1.com/team_id/channel_id',
|
||||||
false,
|
false,
|
||||||
{id: 1, send: jest.fn()},
|
{id: 1, send: jest.fn()} as unknown as WebContents,
|
||||||
{},
|
{soundName: ''},
|
||||||
);
|
);
|
||||||
Object.defineProperty(process, 'platform', {
|
Object.defineProperty(process, 'platform', {
|
||||||
value: originalPlatform,
|
value: originalPlatform,
|
||||||
@@ -293,21 +313,23 @@ describe('main/notifications', () => {
|
|||||||
|
|
||||||
it('linux/windows - should flash frame when config item is set', async () => {
|
it('linux/windows - should flash frame when config item is set', async () => {
|
||||||
Config.notifications = {
|
Config.notifications = {
|
||||||
flashWindow: true,
|
flashWindow: 1,
|
||||||
|
bounceIcon: false,
|
||||||
|
bounceIconType: 'informational',
|
||||||
};
|
};
|
||||||
const originalPlatform = process.platform;
|
const originalPlatform = process.platform;
|
||||||
Object.defineProperty(process, 'platform', {
|
Object.defineProperty(process, 'platform', {
|
||||||
value: 'linux',
|
value: 'linux',
|
||||||
});
|
});
|
||||||
await displayMention(
|
await NotificationManager.displayMention(
|
||||||
'click_test',
|
'click_test',
|
||||||
'mention_click_body',
|
'mention_click_body',
|
||||||
{id: 'channel_id'},
|
{id: 'channel_id'},
|
||||||
'team_id',
|
'team_id',
|
||||||
'http://server-1.com/team_id/channel_id',
|
'http://server-1.com/team_id/channel_id',
|
||||||
false,
|
false,
|
||||||
{id: 1, send: jest.fn()},
|
{id: 1, send: jest.fn()} as unknown as WebContents,
|
||||||
{},
|
{soundName: ''},
|
||||||
);
|
);
|
||||||
Object.defineProperty(process, 'platform', {
|
Object.defineProperty(process, 'platform', {
|
||||||
value: originalPlatform,
|
value: originalPlatform,
|
||||||
@@ -320,15 +342,15 @@ describe('main/notifications', () => {
|
|||||||
Object.defineProperty(process, 'platform', {
|
Object.defineProperty(process, 'platform', {
|
||||||
value: 'darwin',
|
value: 'darwin',
|
||||||
});
|
});
|
||||||
await displayMention(
|
await NotificationManager.displayMention(
|
||||||
'click_test',
|
'click_test',
|
||||||
'mention_click_body',
|
'mention_click_body',
|
||||||
{id: 'channel_id'},
|
{id: 'channel_id'},
|
||||||
'team_id',
|
'team_id',
|
||||||
'http://server-1.com/team_id/channel_id',
|
'http://server-1.com/team_id/channel_id',
|
||||||
false,
|
false,
|
||||||
{id: 1, send: jest.fn()},
|
{id: 1, send: jest.fn()} as unknown as WebContents,
|
||||||
{},
|
{soundName: ''},
|
||||||
);
|
);
|
||||||
Object.defineProperty(process, 'platform', {
|
Object.defineProperty(process, 'platform', {
|
||||||
value: originalPlatform,
|
value: originalPlatform,
|
||||||
@@ -340,20 +362,21 @@ describe('main/notifications', () => {
|
|||||||
Config.notifications = {
|
Config.notifications = {
|
||||||
bounceIcon: true,
|
bounceIcon: true,
|
||||||
bounceIconType: 'critical',
|
bounceIconType: 'critical',
|
||||||
|
flashWindow: 0,
|
||||||
};
|
};
|
||||||
const originalPlatform = process.platform;
|
const originalPlatform = process.platform;
|
||||||
Object.defineProperty(process, 'platform', {
|
Object.defineProperty(process, 'platform', {
|
||||||
value: 'darwin',
|
value: 'darwin',
|
||||||
});
|
});
|
||||||
await displayMention(
|
await NotificationManager.displayMention(
|
||||||
'click_test',
|
'click_test',
|
||||||
'mention_click_body',
|
'mention_click_body',
|
||||||
{id: 'channel_id'},
|
{id: 'channel_id'},
|
||||||
'team_id',
|
'team_id',
|
||||||
'http://server-1.com/team_id/channel_id',
|
'http://server-1.com/team_id/channel_id',
|
||||||
false,
|
false,
|
||||||
{id: 1, send: jest.fn()},
|
{id: 1, send: jest.fn()} as unknown as WebContents,
|
||||||
{},
|
{soundName: ''},
|
||||||
);
|
);
|
||||||
Object.defineProperty(process, 'platform', {
|
Object.defineProperty(process, 'platform', {
|
||||||
value: originalPlatform,
|
value: originalPlatform,
|
||||||
@@ -365,26 +388,26 @@ describe('main/notifications', () => {
|
|||||||
describe('displayDownloadCompleted', () => {
|
describe('displayDownloadCompleted', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
Notification.isSupported.mockImplementation(() => true);
|
Notification.isSupported.mockImplementation(() => true);
|
||||||
getFocusAssist.mockReturnValue({value: false});
|
getFocusAssist.mockReturnValue({value: 0, name: ''});
|
||||||
getDarwinDoNotDisturb.mockReturnValue(false);
|
getDarwinDoNotDisturb.mockReturnValue(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should open file when clicked', () => {
|
it('should open file when clicked', () => {
|
||||||
getDarwinDoNotDisturb.mockReturnValue(false);
|
getDarwinDoNotDisturb.mockReturnValue(false);
|
||||||
localizeMessage.mockReturnValue('test_filename');
|
localizeMessage.mockReturnValue('test_filename');
|
||||||
displayDownloadCompleted(
|
NotificationManager.displayDownloadCompleted(
|
||||||
'test_filename',
|
'test_filename',
|
||||||
'/path/to/file',
|
'/path/to/file',
|
||||||
'server_name',
|
'server_name',
|
||||||
);
|
);
|
||||||
const mention = mentions.find((m) => m.body.includes('test_filename'));
|
const mention = mentions.find((m) => m.body.includes('test_filename'));
|
||||||
mention.value.click();
|
mention?.value.click();
|
||||||
expect(shell.showItemInFolder).toHaveBeenCalledWith('/path/to/file');
|
expect(shell.showItemInFolder).toHaveBeenCalledWith('/path/to/file');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getLinuxDoNotDisturb', () => {
|
describe('getLinuxDoNotDisturb', () => {
|
||||||
let originalPlatform;
|
let originalPlatform: NodeJS.Platform;
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
originalPlatform = process.platform;
|
originalPlatform = process.platform;
|
||||||
Object.defineProperty(process, 'platform', {
|
Object.defineProperty(process, 'platform', {
|
||||||
@@ -399,7 +422,7 @@ describe('main/notifications', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return false', () => {
|
it('should return false', () => {
|
||||||
cp.execSync.mockReturnValue('true');
|
cp.execSync.mockReturnValue(Buffer.from('true'));
|
||||||
expect(getLinuxDoNotDisturb()).toBe(false);
|
expect(getLinuxDoNotDisturb()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -411,7 +434,7 @@ describe('main/notifications', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return true', () => {
|
it('should return true', () => {
|
||||||
cp.execSync.mockReturnValue('false');
|
cp.execSync.mockReturnValue(Buffer.from('false'));
|
||||||
expect(getLinuxDoNotDisturb()).toBe(true);
|
expect(getLinuxDoNotDisturb()).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
@@ -21,134 +21,157 @@ import {NewVersionNotification, UpgradeNotification} from './Upgrade';
|
|||||||
import getLinuxDoNotDisturb from './dnd-linux';
|
import getLinuxDoNotDisturb from './dnd-linux';
|
||||||
import getWindowsDoNotDisturb from './dnd-windows';
|
import getWindowsDoNotDisturb from './dnd-windows';
|
||||||
|
|
||||||
export const currentNotifications = new Map();
|
|
||||||
|
|
||||||
const log = new Logger('Notifications');
|
const log = new Logger('Notifications');
|
||||||
|
|
||||||
export async function displayMention(title: string, body: string, channel: {id: string}, teamId: string, url: string, silent: boolean, webcontents: Electron.WebContents, data: MentionData) {
|
class NotificationManager {
|
||||||
log.debug('displayMention', {title, body, channel, teamId, url, silent, data});
|
private mentionsPerChannel: Map<string, Mention> = new Map();
|
||||||
|
private allActiveNotifications: Map<string, Notification> = new Map();
|
||||||
|
private upgradeNotification?: NewVersionNotification;
|
||||||
|
private restartToUpgradeNotification?: UpgradeNotification;
|
||||||
|
|
||||||
if (!Notification.isSupported()) {
|
public async displayMention(title: string, body: string, channel: {id: string}, teamId: string, url: string, silent: boolean, webcontents: Electron.WebContents, data: MentionData) {
|
||||||
log.error('notification not supported');
|
log.debug('displayMention', {title, body, channel, teamId, url, silent, data});
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getDoNotDisturb()) {
|
if (!Notification.isSupported()) {
|
||||||
return;
|
log.error('notification not supported');
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const view = ViewManager.getViewByWebContentsId(webcontents.id);
|
if (getDoNotDisturb()) {
|
||||||
if (!view) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
const serverName = view.view.server.name;
|
|
||||||
|
|
||||||
const options = {
|
const view = ViewManager.getViewByWebContentsId(webcontents.id);
|
||||||
title: `${serverName}: ${title}`,
|
if (!view) {
|
||||||
body,
|
return;
|
||||||
silent,
|
}
|
||||||
data,
|
const serverName = view.view.server.name;
|
||||||
};
|
|
||||||
|
|
||||||
if (!await PermissionsManager.doPermissionRequest(webcontents.id, 'notifications', view.view.server.url.toString())) {
|
const options = {
|
||||||
return;
|
title: `${serverName}: ${title}`,
|
||||||
}
|
body,
|
||||||
|
silent,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
|
||||||
const mention = new Mention(options, channel, teamId);
|
if (!await PermissionsManager.doPermissionRequest(webcontents.id, 'notifications', view.view.server.url.toString())) {
|
||||||
const mentionKey = `${mention.teamId}:${mention.channel.id}`;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mention.on('show', () => {
|
const mention = new Mention(options, channel, teamId);
|
||||||
log.debug('displayMention.show');
|
const mentionKey = `${mention.teamId}:${mention.channel.id}`;
|
||||||
|
this.allActiveNotifications.set(mention.uId, mention);
|
||||||
|
|
||||||
// On Windows, manually dismiss notifications from the same channel and only show the latest one
|
mention.on('show', () => {
|
||||||
if (process.platform === 'win32') {
|
log.debug('displayMention.show');
|
||||||
if (currentNotifications.has(mentionKey)) {
|
|
||||||
log.debug(`close ${mentionKey}`);
|
// On Windows, manually dismiss notifications from the same channel and only show the latest one
|
||||||
currentNotifications.get(mentionKey).close();
|
if (process.platform === 'win32') {
|
||||||
currentNotifications.delete(mentionKey);
|
if (this.mentionsPerChannel.has(mentionKey)) {
|
||||||
|
log.debug(`close ${mentionKey}`);
|
||||||
|
this.mentionsPerChannel.get(mentionKey)?.close();
|
||||||
|
this.mentionsPerChannel.delete(mentionKey);
|
||||||
|
}
|
||||||
|
this.mentionsPerChannel.set(mentionKey, mention);
|
||||||
}
|
}
|
||||||
currentNotifications.set(mentionKey, mention);
|
const notificationSound = mention.getNotificationSound();
|
||||||
|
if (notificationSound) {
|
||||||
|
MainWindow.sendToRenderer(PLAY_SOUND, notificationSound);
|
||||||
|
}
|
||||||
|
flashFrame(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
mention.on('click', () => {
|
||||||
|
log.debug('notification click', serverName, mention);
|
||||||
|
|
||||||
|
this.allActiveNotifications.delete(mention.uId);
|
||||||
|
MainWindow.show();
|
||||||
|
if (serverName) {
|
||||||
|
ViewManager.showById(view.id);
|
||||||
|
webcontents.send('notification-clicked', {channel, teamId, url});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mention.on('close', () => {
|
||||||
|
this.allActiveNotifications.delete(mention.uId);
|
||||||
|
});
|
||||||
|
|
||||||
|
mention.on('failed', () => {
|
||||||
|
this.allActiveNotifications.delete(mention.uId);
|
||||||
|
});
|
||||||
|
mention.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public displayDownloadCompleted(fileName: string, path: string, serverName: string) {
|
||||||
|
log.debug('displayDownloadCompleted', {fileName, path, serverName});
|
||||||
|
|
||||||
|
if (!Notification.isSupported()) {
|
||||||
|
log.error('notification not supported');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
const notificationSound = mention.getNotificationSound();
|
|
||||||
if (notificationSound) {
|
if (getDoNotDisturb()) {
|
||||||
MainWindow.sendToRenderer(PLAY_SOUND, notificationSound);
|
return;
|
||||||
}
|
}
|
||||||
flashFrame(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
mention.on('click', () => {
|
const download = new DownloadNotification(fileName, serverName);
|
||||||
log.debug('notification click', serverName, mention);
|
this.allActiveNotifications.set(download.uId, download);
|
||||||
MainWindow.show();
|
|
||||||
if (serverName) {
|
download.on('show', () => {
|
||||||
ViewManager.showById(view.id);
|
flashFrame(true);
|
||||||
webcontents.send('notification-clicked', {channel, teamId, url});
|
});
|
||||||
|
|
||||||
|
download.on('click', () => {
|
||||||
|
shell.showItemInFolder(path.normalize());
|
||||||
|
this.allActiveNotifications.delete(download.uId);
|
||||||
|
});
|
||||||
|
|
||||||
|
download.on('close', () => {
|
||||||
|
this.allActiveNotifications.delete(download.uId);
|
||||||
|
});
|
||||||
|
|
||||||
|
download.on('failed', () => {
|
||||||
|
this.allActiveNotifications.delete(download.uId);
|
||||||
|
});
|
||||||
|
download.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public displayUpgrade(version: string, handleUpgrade: () => void): void {
|
||||||
|
if (!Notification.isSupported()) {
|
||||||
|
log.error('notification not supported');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (getDoNotDisturb()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
mention.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function displayDownloadCompleted(fileName: string, path: string, serverName: string) {
|
if (this.upgradeNotification) {
|
||||||
log.debug('displayDownloadCompleted', {fileName, path, serverName});
|
this.upgradeNotification.close();
|
||||||
|
}
|
||||||
if (!Notification.isSupported()) {
|
this.upgradeNotification = new NewVersionNotification();
|
||||||
log.error('notification not supported');
|
this.upgradeNotification.on('click', () => {
|
||||||
return;
|
log.info(`User clicked to upgrade to ${version}`);
|
||||||
|
handleUpgrade();
|
||||||
|
});
|
||||||
|
this.upgradeNotification.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getDoNotDisturb()) {
|
public displayRestartToUpgrade(version: string, handleUpgrade: () => void): void {
|
||||||
return;
|
if (!Notification.isSupported()) {
|
||||||
|
log.error('notification not supported');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (getDoNotDisturb()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.restartToUpgradeNotification = new UpgradeNotification();
|
||||||
|
this.restartToUpgradeNotification.on('click', () => {
|
||||||
|
log.info(`User requested perform the upgrade now to ${version}`);
|
||||||
|
handleUpgrade();
|
||||||
|
});
|
||||||
|
this.restartToUpgradeNotification.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
const download = new DownloadNotification(fileName, serverName);
|
|
||||||
|
|
||||||
download.on('show', () => {
|
|
||||||
flashFrame(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
download.on('click', () => {
|
|
||||||
shell.showItemInFolder(path.normalize());
|
|
||||||
});
|
|
||||||
download.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
let upgrade: NewVersionNotification;
|
|
||||||
|
|
||||||
export function displayUpgrade(version: string, handleUpgrade: () => void): void {
|
|
||||||
if (!Notification.isSupported()) {
|
|
||||||
log.error('notification not supported');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (getDoNotDisturb()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (upgrade) {
|
|
||||||
upgrade.close();
|
|
||||||
}
|
|
||||||
upgrade = new NewVersionNotification();
|
|
||||||
upgrade.on('click', () => {
|
|
||||||
log.info(`User clicked to upgrade to ${version}`);
|
|
||||||
handleUpgrade();
|
|
||||||
});
|
|
||||||
upgrade.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
let restartToUpgrade;
|
|
||||||
export function displayRestartToUpgrade(version: string, handleUpgrade: () => void): void {
|
|
||||||
if (!Notification.isSupported()) {
|
|
||||||
log.error('notification not supported');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (getDoNotDisturb()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
restartToUpgrade = new UpgradeNotification();
|
|
||||||
restartToUpgrade.on('click', () => {
|
|
||||||
log.info(`User requested perform the upgrade now to ${version}`);
|
|
||||||
handleUpgrade();
|
|
||||||
});
|
|
||||||
restartToUpgrade.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDoNotDisturb() {
|
function getDoNotDisturb() {
|
||||||
@@ -177,3 +200,6 @@ function flashFrame(flash: boolean) {
|
|||||||
app.dock.bounce(Config.notifications.bounceIconType);
|
app.dock.bounce(Config.notifications.bounceIconType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const notificationManager = new NotificationManager();
|
||||||
|
export default notificationManager;
|
||||||
|
Reference in New Issue
Block a user