mirror of
https://github.com/element-hq/element-web
synced 2024-11-27 19:56:47 +03:00
Fix up notification setting listener in roomtile
The previous dispatch only did binary muted/non-muted but we now have 4 states. We now just listen for the push rules account data and update on that so it stays in sync if the pishrules are changed elsewhere. Also add util functions used here for getting the notif state and in vector for both getting and setting it.
This commit is contained in:
parent
5a83adc2b6
commit
87f94bde62
2 changed files with 162 additions and 27 deletions
137
src/RoomNotifs.js
Normal file
137
src/RoomNotifs.js
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
|
||||
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 MatrixClientPeg from './MatrixClientPeg';
|
||||
import PushProcessor from 'matrix-js-sdk/lib/pushprocessor';
|
||||
import q from 'q';
|
||||
|
||||
export function getRoomNotifsState(roomId) {
|
||||
// look through the override rules for a rule affecting this room:
|
||||
// if one exists, it will take precedence.
|
||||
const muteRule = findOverrideMuteRule(roomId);
|
||||
if (muteRule && muteRule.enabled) {
|
||||
return 'mute';
|
||||
}
|
||||
|
||||
// for everything else, look at the room rule.
|
||||
const roomRule = MatrixClientPeg.get().getRoomPushRule('global', roomId);
|
||||
|
||||
// XXX: We have to assume the default is to notify for all messages
|
||||
// (in particular this will be 'wrong' for one to one rooms because
|
||||
// they will notify loudly for all messages)
|
||||
if (!roomRule || !roomRule.enabled) return 'all_messages';
|
||||
|
||||
// a mute at the room level will still allow mentions
|
||||
// to notify
|
||||
if (isMuteRule(roomRule)) return 'mentions_only';
|
||||
|
||||
const actionsObject = PushProcessor.actionListToActionsObject(roomRule.actions);
|
||||
if (actionsObject.tweaks.sound) return 'all_messages_loud';
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function setRoomNotifsState(roomId, newState) {
|
||||
const cli = MatrixClientPeg.get();
|
||||
const promises = [];
|
||||
|
||||
if (newState == 'mute') {
|
||||
// delete the room rule
|
||||
const roomRule = MatrixClientPeg.get().getRoomPushRule('global', roomId);
|
||||
if (roomRule) {
|
||||
promises.push(cli.deletePushRule('global', 'room', roomRule.rule_id));
|
||||
}
|
||||
|
||||
// add an override rule to squelch everything in this room
|
||||
promises.push(cli.addPushRule('global', 'override', roomId, {
|
||||
conditions: [
|
||||
{
|
||||
kind: 'event_match',
|
||||
key: 'room_id',
|
||||
pattern: roomId,
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
'dont_notify',
|
||||
]
|
||||
}));
|
||||
} else {
|
||||
const overrideMuteRule = findOverrideMuteRule(roomId);
|
||||
if (overrideMuteRule) {
|
||||
promises.push(cli.deletePushRule('global', 'override', overrideMuteRule.rule_id));
|
||||
}
|
||||
|
||||
if (newState == 'all_messages') {
|
||||
promises.push(cli.deletePushRule('global', 'room', roomId));
|
||||
} else if (newState == 'mentions_only') {
|
||||
promises.push(cli.addPushRule('global', 'room', roomId, {
|
||||
actions: [
|
||||
'dont_notify',
|
||||
]
|
||||
}));
|
||||
// https://matrix.org/jira/browse/SPEC-400
|
||||
promises.push(cli.setPushRuleEnabled('global', 'room', roomId, true));
|
||||
} else if ('all_messages_loud') {
|
||||
promises.push(cli.addPushRule('global', 'room', roomId, {
|
||||
actions: [
|
||||
'notify',
|
||||
{
|
||||
set_tweak: 'sound',
|
||||
value: 'default',
|
||||
}
|
||||
]
|
||||
}));
|
||||
// https://matrix.org/jira/browse/SPEC-400
|
||||
promises.push(cli.setPushRuleEnabled('global', 'room', roomId, true));
|
||||
}
|
||||
}
|
||||
|
||||
return q.all(promises);
|
||||
}
|
||||
|
||||
function findOverrideMuteRule(roomId) {
|
||||
for (const rule of MatrixClientPeg.get().pushRules['global'].override) {
|
||||
if (isRuleForRoom(roomId, rule)) {
|
||||
if (isMuteRule(rule)) {
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function isRuleForRoom(roomId, rule) {
|
||||
if (rule.conditions.length !== 1) {
|
||||
return false;
|
||||
}
|
||||
const cond = rule.conditions[0];
|
||||
if (
|
||||
cond.kind == 'event_match' &&
|
||||
cond.key == 'room_id' &&
|
||||
cond.pattern == roomId
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isMuteRule(rule) {
|
||||
return (
|
||||
rule.actions.length == 1 &&
|
||||
rule.actions[0] == 'dont_notify'
|
||||
);
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@ var dis = require("../../../dispatcher");
|
|||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
var sdk = require('../../../index');
|
||||
var ContextualMenu = require('../../structures/ContextualMenu');
|
||||
var RoomNotifs = require('../../../RoomNotifs');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomTile',
|
||||
|
@ -43,43 +44,40 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
getInitialState: function() {
|
||||
var areNotifsMuted = false;
|
||||
var cli = MatrixClientPeg.get();
|
||||
if (!cli.isGuest()) {
|
||||
var roomPushRule = cli.getRoomPushRule("global", this.props.room.roomId);
|
||||
if (roomPushRule) {
|
||||
if (0 <= roomPushRule.actions.indexOf("dont_notify")) {
|
||||
areNotifsMuted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return({
|
||||
hover : false,
|
||||
badgeHover : false,
|
||||
notificationTagMenu: false,
|
||||
roomTagMenu: false,
|
||||
areNotifsMuted: areNotifsMuted,
|
||||
showBadge: this._shouldShowBadge(),
|
||||
});
|
||||
},
|
||||
|
||||
onAction: function(payload) {
|
||||
switch (payload.action) {
|
||||
case 'notification_change':
|
||||
// Is the notification about this room?
|
||||
if (payload.roomId === this.props.room.roomId) {
|
||||
this.setState( { areNotifsMuted : payload.areNotifsMuted });
|
||||
}
|
||||
break;
|
||||
_shouldShowBadge: function() {
|
||||
if (MatrixClientPeg.get().isGuest()) return true;
|
||||
|
||||
const showBadgeInStates = ['all_messages', 'all_messages_loud'];
|
||||
const currentState = RoomNotifs.getRoomNotifsState(this.props.room.roomId);
|
||||
return showBadgeInStates.indexOf(currentState) > -1;
|
||||
},
|
||||
|
||||
onAccountData: function(accountDataEvent) {
|
||||
if (accountDataEvent.getType() == 'm.push_rules') {
|
||||
this.setState({
|
||||
showBadge: this._shouldShowBadge(),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
componentWillMount: function() {
|
||||
MatrixClientPeg.get().on("accountData", this.onAccountData);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
var cli = MatrixClientPeg.get();
|
||||
if (cli) {
|
||||
MatrixClientPeg.get().removeListener("accountData", this.onAccountData);
|
||||
}
|
||||
},
|
||||
|
||||
onClick: function() {
|
||||
|
@ -183,11 +181,11 @@ module.exports = React.createClass({
|
|||
'mx_RoomTile': true,
|
||||
'mx_RoomTile_selected': this.props.selected,
|
||||
'mx_RoomTile_unread': this.props.unread,
|
||||
'mx_RoomTile_unreadNotify': notificationCount > 0 && !this.state.areNotifsMuted,
|
||||
'mx_RoomTile_unreadNotify': notificationCount > 0 && this.state.showBadge,
|
||||
'mx_RoomTile_highlight': this.props.highlight,
|
||||
'mx_RoomTile_invited': (me && me.membership == 'invite'),
|
||||
'mx_RoomTile_notificationTagMenu': this.state.notificationTagMenu,
|
||||
'mx_RoomTile_noBadges': !(this.props.highlight || (notificationCount > 0 && !this.state.areNotifsMuted))
|
||||
'mx_RoomTile_noBadges': !(this.props.highlight || (notificationCount > 0 && this.state.showBadge))
|
||||
});
|
||||
|
||||
var avatarClasses = classNames({
|
||||
|
@ -214,7 +212,7 @@ module.exports = React.createClass({
|
|||
|
||||
if (this.state.badgeHover || this.state.notificationTagMenu) {
|
||||
badgeContent = "\u00B7\u00B7\u00B7";
|
||||
} else if (this.props.highlight || (notificationCount > 0 && !this.state.areNotifsMuted)) {
|
||||
} else if (this.props.highlight || (notificationCount > 0 && this.state.showBadge)) {
|
||||
var limitedCount = (notificationCount > 99) ? '99+' : notificationCount;
|
||||
badgeContent = notificationCount ? limitedCount : '!';
|
||||
} else {
|
||||
|
@ -230,7 +228,7 @@ module.exports = React.createClass({
|
|||
var nameClasses = classNames({
|
||||
'mx_RoomTile_name': true,
|
||||
'mx_RoomTile_invite': this.props.isInvite,
|
||||
'mx_RoomTile_badgeShown': this.props.highlight || (notificationCount > 0 && !this.state.areNotifsMuted) || this.state.badgeHover || this.state.notificationTagMenu,
|
||||
'mx_RoomTile_badgeShown': this.props.highlight || (notificationCount > 0 && this.state.showBadge) || this.state.badgeHover || this.state.notificationTagMenu,
|
||||
});
|
||||
|
||||
if (this.props.selected) {
|
||||
|
|
Loading…
Reference in a new issue