[MM-58693] Fix some issues with Windows notifications (#3060)

* Fix DND setting for Windows

* Add custom not_sent reason for handling windows permissions denied

* Wait to see if failed event happened first before calling success

* Add test

* Reverse priority
This commit is contained in:
Devin Binnie 2024-06-11 17:18:01 -04:00 committed by GitHub
parent d11752e195
commit 06c5fe9220
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 97 additions and 25 deletions

View file

@ -0,0 +1,62 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {getFocusAssist, isPriority} from 'windows-focus-assist';
import doNotDisturb from './dnd-windows';
jest.mock('windows-focus-assist', () => ({
getFocusAssist: jest.fn(),
isPriority: jest.fn(),
}));
describe('main/notifications/dnd-windows', () => {
it('should return false if unsupported, failed, or off', () => {
const originalPlatform = process.platform;
Object.defineProperty(process, 'platform', {
value: 'win32',
});
getFocusAssist.mockReturnValue({value: 0});
expect(doNotDisturb()).toBe(false);
getFocusAssist.mockReturnValue({value: -1});
expect(doNotDisturb()).toBe(false);
getFocusAssist.mockReturnValue({value: -2});
expect(doNotDisturb()).toBe(false);
Object.defineProperty(process, 'platform', {
value: originalPlatform,
});
});
it('should return true if alarms only', () => {
const originalPlatform = process.platform;
Object.defineProperty(process, 'platform', {
value: 'win32',
});
getFocusAssist.mockReturnValue({value: 2});
expect(doNotDisturb()).toBe(true);
Object.defineProperty(process, 'platform', {
value: originalPlatform,
});
});
it('should check if the app is priority if priority only', () => {
const originalPlatform = process.platform;
Object.defineProperty(process, 'platform', {
value: 'win32',
});
getFocusAssist.mockReturnValue({value: 1});
isPriority.mockReturnValue({value: 0});
expect(doNotDisturb()).toBe(true);
isPriority.mockReturnValue({value: 1});
expect(doNotDisturb()).toBe(false);
Object.defineProperty(process, 'platform', {
value: originalPlatform,
});
});
});

View file

@ -20,13 +20,9 @@ function getWindowsDoNotDisturb() {
case 2:
return true;
case 1:
return !isPriority('Mattermost.Desktop');
case 0:
case -1:
case -2:
return false;
return !(isPriority('Mattermost.Desktop').value);
default:
return focusAssistValue;
return false;
}
}

View file

@ -92,8 +92,12 @@ class NotificationManager {
log.debug('notification timeout', serverName, mention.uId);
resolve({status: 'error', reason: 'notification_timeout'});
}, 10000);
let failed = false;
mention.on('show', () => {
// Ensure the failed event isn't also called, if it is we should resolve using its method
setTimeout(() => {
if (!failed) {
log.debug('displayMention.show', serverName, mention.uId);
// On Windows, manually dismiss notifications from the same channel and only show the latest one
@ -113,13 +117,23 @@ class NotificationManager {
flashFrame(true);
clearTimeout(timeout);
resolve({status: 'success'});
}
}, 0);
});
mention.on('failed', (_, error) => {
failed = true;
this.allActiveNotifications.delete(mention.uId);
clearTimeout(timeout);
// Special case for Windows - means that notifications are disabled at the OS level
if (error.includes('HRESULT:-2143420143')) {
log.warn('notifications disabled in Windows settings');
resolve({status: 'not_sent', reason: 'windows_permissions_denied'});
} else {
log.error('notification failed to show', serverName, mention.uId, error);
resolve({status: 'error', reason: 'electron_notification_failed', data: error});
}
});
mention.show();
});