Inhibit local notifications when local notifications are silenced (#9328)
parent
951cad98d3
commit
a49603b9b8
|
@ -46,6 +46,7 @@ import { mediaFromMxc } from "./customisations/Media";
|
|||
import ErrorDialog from "./components/views/dialogs/ErrorDialog";
|
||||
import LegacyCallHandler from "./LegacyCallHandler";
|
||||
import VoipUserMapper from "./VoipUserMapper";
|
||||
import { localNotificationsAreSilenced } from "./utils/notifications";
|
||||
|
||||
/*
|
||||
* Dispatches:
|
||||
|
@ -90,8 +91,9 @@ export const Notifier = {
|
|||
return TextForEvent.textForEvent(ev);
|
||||
},
|
||||
|
||||
_displayPopupNotification: function(ev: MatrixEvent, room: Room) {
|
||||
_displayPopupNotification: function(ev: MatrixEvent, room: Room): void {
|
||||
const plaf = PlatformPeg.get();
|
||||
const cli = MatrixClientPeg.get();
|
||||
if (!plaf) {
|
||||
return;
|
||||
}
|
||||
|
@ -99,6 +101,10 @@ export const Notifier = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (localNotificationsAreSilenced(cli)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let msg = this.notificationMessageForEvent(ev);
|
||||
if (!msg) return;
|
||||
|
||||
|
@ -170,7 +176,12 @@ export const Notifier = {
|
|||
};
|
||||
},
|
||||
|
||||
_playAudioNotification: async function(ev: MatrixEvent, room: Room) {
|
||||
_playAudioNotification: async function(ev: MatrixEvent, room: Room): Promise<void> {
|
||||
const cli = MatrixClientPeg.get();
|
||||
if (localNotificationsAreSilenced(cli)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const sound = this.getSoundForRoom(room.roomId);
|
||||
logger.log(`Got sound ${sound && sound.name || "default"} for ${room.roomId}`);
|
||||
|
||||
|
@ -325,7 +336,7 @@ export const Notifier = {
|
|||
}
|
||||
const isGuest = client.isGuest();
|
||||
return !isGuest && this.supportsDesktopNotifications() && !isPushNotifyDisabled() &&
|
||||
!this.isEnabled() && !this._isPromptHidden();
|
||||
!localNotificationsAreSilenced(client) && !this.isEnabled() && !this._isPromptHidden();
|
||||
},
|
||||
|
||||
_isPromptHidden: function() {
|
||||
|
|
|
@ -15,6 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { LOCAL_NOTIFICATION_SETTINGS_PREFIX } from "matrix-js-sdk/src/@types/event";
|
||||
import { LocalNotificationSettings } from "matrix-js-sdk/src/@types/local_notifications";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
|
||||
import SettingsStore from "../settings/SettingsStore";
|
||||
|
@ -32,7 +33,6 @@ export function getLocalNotificationAccountDataEventType(deviceId: string): stri
|
|||
export async function createLocalNotificationSettingsIfNeeded(cli: MatrixClient): Promise<void> {
|
||||
const eventType = getLocalNotificationAccountDataEventType(cli.deviceId);
|
||||
const event = cli.getAccountData(eventType);
|
||||
|
||||
// New sessions will create an account data event to signify they support
|
||||
// remote toggling of push notifications on this device. Default `is_silenced=true`
|
||||
// For backwards compat purposes, older sessions will need to check settings value
|
||||
|
@ -47,3 +47,9 @@ export async function createLocalNotificationSettingsIfNeeded(cli: MatrixClient)
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function localNotificationsAreSilenced(cli: MatrixClient): boolean {
|
||||
const eventType = getLocalNotificationAccountDataEventType(cli.deviceId);
|
||||
const event = cli.getAccountData(eventType);
|
||||
return event?.getContent<LocalNotificationSettings>()?.is_silenced ?? true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
|
||||
import Notifier from "../src/Notifier";
|
||||
import { getLocalNotificationAccountDataEventType } from "../src/utils/notifications";
|
||||
import { getMockClientWithEventEmitter, mkEvent, mkRoom, mockPlatformPeg } from "./test-utils";
|
||||
|
||||
describe("Notifier", () => {
|
||||
let MockPlatform;
|
||||
let accountDataStore = {};
|
||||
|
||||
const mockClient = getMockClientWithEventEmitter({
|
||||
getUserId: jest.fn().mockReturnValue("@bob:example.org"),
|
||||
isGuest: jest.fn().mockReturnValue(false),
|
||||
getAccountData: jest.fn().mockImplementation(eventType => accountDataStore[eventType]),
|
||||
setAccountData: jest.fn().mockImplementation((eventType, content) => {
|
||||
accountDataStore[eventType] = new MatrixEvent({
|
||||
type: eventType,
|
||||
content,
|
||||
});
|
||||
}),
|
||||
});
|
||||
const accountDataEventKey = getLocalNotificationAccountDataEventType(mockClient.deviceId);
|
||||
const roomId = "!room1:server";
|
||||
const testEvent = mkEvent({
|
||||
event: true,
|
||||
type: "m.room.message",
|
||||
user: "@user1:server",
|
||||
room: roomId,
|
||||
content: {},
|
||||
});
|
||||
const testRoom = mkRoom(mockClient, roomId);
|
||||
|
||||
beforeEach(() => {
|
||||
accountDataStore = {};
|
||||
MockPlatform = mockPlatformPeg({
|
||||
supportsNotifications: jest.fn().mockReturnValue(true),
|
||||
maySendNotifications: jest.fn().mockReturnValue(true),
|
||||
displayNotification: jest.fn(),
|
||||
});
|
||||
|
||||
Notifier.isBodyEnabled = jest.fn().mockReturnValue(true);
|
||||
});
|
||||
|
||||
describe("_displayPopupNotification", () => {
|
||||
it.each([
|
||||
{ silenced: true, count: 0 },
|
||||
{ silenced: false, count: 1 },
|
||||
])("does not dispatch when notifications are silenced", ({ silenced, count }) => {
|
||||
mockClient.setAccountData(accountDataEventKey, { is_silenced: silenced });
|
||||
Notifier._displayPopupNotification(testEvent, testRoom);
|
||||
expect(MockPlatform.displayNotification).toHaveBeenCalledTimes(count);
|
||||
});
|
||||
});
|
||||
|
||||
describe("_playAudioNotification", () => {
|
||||
it.each([
|
||||
{ silenced: true, count: 0 },
|
||||
{ silenced: false, count: 1 },
|
||||
])("does not dispatch when notifications are silenced", ({ silenced, count }) => {
|
||||
// It's not ideal to only look at whether this function has been called
|
||||
// but avoids starting to look into DOM stuff
|
||||
Notifier.getSoundForRoom = jest.fn();
|
||||
|
||||
mockClient.setAccountData(accountDataEventKey, { is_silenced: silenced });
|
||||
Notifier._playAudioNotification(testEvent, testRoom);
|
||||
expect(Notifier.getSoundForRoom).toHaveBeenCalledTimes(count);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -18,6 +18,7 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
|||
import { mocked } from "jest-mock";
|
||||
|
||||
import {
|
||||
localNotificationsAreSilenced,
|
||||
createLocalNotificationSettingsIfNeeded,
|
||||
getLocalNotificationAccountDataEventType,
|
||||
} from "../../src/utils/notifications";
|
||||
|
@ -27,7 +28,7 @@ import { getMockClientWithEventEmitter } from "../test-utils/client";
|
|||
jest.mock("../../src/settings/SettingsStore");
|
||||
|
||||
describe('notifications', () => {
|
||||
const accountDataStore = {};
|
||||
let accountDataStore = {};
|
||||
const mockClient = getMockClientWithEventEmitter({
|
||||
isGuest: jest.fn().mockReturnValue(false),
|
||||
getAccountData: jest.fn().mockImplementation(eventType => accountDataStore[eventType]),
|
||||
|
@ -42,6 +43,7 @@ describe('notifications', () => {
|
|||
const accountDataEventKey = getLocalNotificationAccountDataEventType(mockClient.deviceId);
|
||||
|
||||
beforeEach(() => {
|
||||
accountDataStore = {};
|
||||
mocked(SettingsStore).getValue.mockReturnValue(false);
|
||||
});
|
||||
|
||||
|
@ -76,4 +78,17 @@ describe('notifications', () => {
|
|||
expect(event?.getContent().is_silenced).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('localNotificationsAreSilenced', () => {
|
||||
it('defaults to true when no setting exists', () => {
|
||||
expect(localNotificationsAreSilenced(mockClient)).toBeTruthy();
|
||||
});
|
||||
it('checks the persisted value', () => {
|
||||
mockClient.setAccountData(accountDataEventKey, { is_silenced: true });
|
||||
expect(localNotificationsAreSilenced(mockClient)).toBeTruthy();
|
||||
|
||||
mockClient.setAccountData(accountDataEventKey, { is_silenced: false });
|
||||
expect(localNotificationsAreSilenced(mockClient)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue