Make the slider work

Still WIP though: need to make vector work with the 'contains display name' rule being an override
This commit is contained in:
David Baker 2016-08-16 15:54:28 +01:00
parent a17df609f3
commit cd0ed879e3
3 changed files with 105 additions and 30 deletions

View File

@ -32,78 +32,86 @@ module.exports = React.createClass({
onFinished: React.PropTypes.func, onFinished: React.PropTypes.func,
}, },
_save: function( areNotifsMuted ) { getInitialState() {
var self = this; return {
vectorRoomNotifState: RoomNotifs.getVectorRoomNotifsState(this.props.room.roomId),
}
},
_save: function(newState) {
const oldState = this.state.vectorRoomNotifState;
const roomId = this.props.room.roomId; const roomId = this.props.room.roomId;
var cli = MatrixClientPeg.get(); var cli = MatrixClientPeg.get();
if (!cli.isGuest()) { if (!cli.isGuest()) {
// Wrapping this in a q promise, as setRoomMutePushRule can return // Wrapping this in a q promise, as setRoomMutePushRule can return
// a promise or a value // a promise or a value
q(cli.setRoomMutePushRule("global", roomId, areNotifsMuted)) this.setState({
.then(function() { vectorRoomNotifState: newState,
self.setState({areNotifsMuted: areNotifsMuted}); });
RoomNotifs.setVectorRoomNotifsState(this.props.room.roomId, newState).done(() => {
// delay slightly so that the user can see their state change // delay slightly so that the user can see their state change
// before closing the menu // before closing the menu
return q.delay(500).then(function() { return q.delay(500).then(() => {
// tell everyone that wants to know of the change in // tell everyone that wants to know of the change in
// notification state // notification state
dis.dispatch({ dis.dispatch({
action: 'notification_change', action: 'notification_change',
roomId: self.props.room.roomId, roomId: this.props.room.roomId,
areNotifsMuted: areNotifsMuted, //areNotifsMuted: areNotifsMuted,
}); });
// Close the context menu // Close the context menu
if (self.props.onFinished) { if (this.props.onFinished) {
self.props.onFinished(); this.props.onFinished();
}; };
}); });
}).fail(function(error) { }, (error) => {
// TODO: some form of error notification to the user // TODO: some form of error notification to the user
// to inform them that their state change failed. // to inform them that their state change failed.
// For now we at least set the state back
this.setState({
vectorRoomNotifState: oldState,
});
}); });
} }
}, },
_onClickAlertMe: function() { _onClickAlertMe: function() {
// Placeholder this._save('all_messages_loud');
}, },
_onClickAllNotifs: function() { _onClickAllNotifs: function() {
this._save(false); this._save('all_messages');
}, },
_onClickMentions: function() { _onClickMentions: function() {
this._save(true); this._save('mentions_only');
}, },
_onClickMute: function() { _onClickMute: function() {
// Placeholder this._save('mute');
}, },
render: function() { render: function() {
const vectorRoomNotifState = RoomNotifs.getVectorRoomNotifsState(this.props.room.roomId);
var alertMeClasses = classNames({ var alertMeClasses = classNames({
'mx_NotificationStateContextMenu_field': true, 'mx_NotificationStateContextMenu_field': true,
'mx_NotificationStateContextMenu_fieldSet': vectorRoomNotifState == 'all_messages_loud', 'mx_NotificationStateContextMenu_fieldSet': this.state.vectorRoomNotifState == 'all_messages_loud',
}); });
var allNotifsClasses = classNames({ var allNotifsClasses = classNames({
'mx_NotificationStateContextMenu_field': true, 'mx_NotificationStateContextMenu_field': true,
'mx_NotificationStateContextMenu_fieldSet': vectorRoomNotifState == 'all_messages', 'mx_NotificationStateContextMenu_fieldSet': this.state.vectorRoomNotifState == 'all_messages',
}); });
var mentionsClasses = classNames({ var mentionsClasses = classNames({
'mx_NotificationStateContextMenu_field': true, 'mx_NotificationStateContextMenu_field': true,
'mx_NotificationStateContextMenu_fieldSet': vectorRoomNotifState == 'mentions_only', 'mx_NotificationStateContextMenu_fieldSet': this.state.vectorRoomNotifState == 'mentions_only',
}); });
var muteNotifsClasses = classNames({ var muteNotifsClasses = classNames({
'mx_NotificationStateContextMenu_field': true, 'mx_NotificationStateContextMenu_field': true,
'mx_NotificationStateContextMenu_fieldDisabled': vectorRoomNotifState == 'mute', 'mx_NotificationStateContextMenu_fieldSet': this.state.vectorRoomNotifState == 'mute',
}); });
return ( return (

View File

@ -16,16 +16,14 @@ limitations under the License.
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
import PushProcessor from 'matrix-js-sdk/lib/pushprocessor'; import PushProcessor from 'matrix-js-sdk/lib/pushprocessor';
import q from 'q';
export function getVectorRoomNotifsState(roomId) { export function getVectorRoomNotifsState(roomId) {
// look through the override rules for a rule affecting this room: // look through the override rules for a rule affecting this room:
// if one exists, it will take precedence. // if one exists, it will take precedence.
for (const rule of MatrixClientPeg.get().pushRules['global'].override) { const muteRule = findOverrideMuteRule(roomId);
if (isRuleForRoom(roomId, rule)) { if (muteRule && muteRule.enabled) {
if (isMuteRule(rule)) { return 'mute';
return 'mute';
}
}
} }
// for everything else, look at the room rule. // for everything else, look at the room rule.
@ -34,7 +32,7 @@ export function getVectorRoomNotifsState(roomId) {
// XXX: We have to assume the default is to notify for all messages // 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 // (in particular this will be 'wrong' for one to one rooms because
// they will notify loudly for all messages) // they will notify loudly for all messages)
if (!roomRule) return 'all_messages'; if (!roomRule || !roomRule.enabled) return 'all_messages';
// a mute at the room level will still allow mentions // a mute at the room level will still allow mentions
// to notify // to notify
@ -46,6 +44,75 @@ export function getVectorRoomNotifsState(roomId) {
return null; return null;
} }
export function setVectorRoomNotifsState(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) { function isRuleForRoom(roomId, rule) {
if (rule.conditions.length !== 1) { if (rule.conditions.length !== 1) {
return false; return false;

View File

@ -65,7 +65,7 @@ module.exports = {
// Messages containing user's display name // Messages containing user's display name
// (skip contains_user_name which is too geeky) // (skip contains_user_name which is too geeky)
".m.rule.contains_display_name": new VectorPushRuleDefinition({ ".m.rule.contains_display_name": new VectorPushRuleDefinition({
kind: "underride", kind: "override",
description: "Messages containing my name", description: "Messages containing my name",
vectorStateToActions: { // The actions for each vector state, or null to disable the rule. vectorStateToActions: { // The actions for each vector state, or null to disable the rule.
on: StandardActions.ACTION_NOTIFY, on: StandardActions.ACTION_NOTIFY,