Merge pull request #1037 from vector-im/markjh/change_push_actions
Update the actions of default rules instead of overriding.
This commit is contained in:
commit
eb01cb9cba
1 changed files with 203 additions and 305 deletions
|
@ -37,240 +37,186 @@ var PushRuleVectorState = {
|
||||||
OFF: "off"
|
OFF: "off"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Encodes a dictionary of {
|
||||||
|
// "notify": true/false,
|
||||||
|
// "sound": string or undefined,
|
||||||
|
// "highlight: true/false,
|
||||||
|
// }
|
||||||
|
// to a list of push actions.
|
||||||
|
function encodeActions(action) {
|
||||||
|
var notify = action.notify;
|
||||||
|
var sound = action.sound;
|
||||||
|
var highlight = action.highlight;
|
||||||
|
if (notify) {
|
||||||
|
var actions = ["notify"];
|
||||||
|
if (sound) {
|
||||||
|
actions.push({"set_tweak": "sound", "value": sound});
|
||||||
|
}
|
||||||
|
if (highlight) {
|
||||||
|
actions.push({"set_tweak": "highlight"});
|
||||||
|
} else {
|
||||||
|
actions.push({"set_tweak": "highlight", "value": false});
|
||||||
|
}
|
||||||
|
return actions;
|
||||||
|
} else {
|
||||||
|
return ["dont_notify"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a list of actions to a dictionary of {
|
||||||
|
// "notify": true/false,
|
||||||
|
// "sound": string or undefined,
|
||||||
|
// "highlight: true/false,
|
||||||
|
// }
|
||||||
|
// If the actions couldn't be decoded then returns null.
|
||||||
|
function decodeActions(actions) {
|
||||||
|
var notify = false;
|
||||||
|
var sound = null;
|
||||||
|
var highlight = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < actions.length; ++i) {
|
||||||
|
var action = actions[i];
|
||||||
|
if (action === "notify") {
|
||||||
|
notify = true;
|
||||||
|
} else if (action === "dont_notify") {
|
||||||
|
notify = false;
|
||||||
|
} else if (typeof action === 'object') {
|
||||||
|
if (action.set_tweak === "sound") {
|
||||||
|
sound = action.value
|
||||||
|
} else if (action.set_tweak === "highlight") {
|
||||||
|
highlight = action.value;
|
||||||
|
} else {
|
||||||
|
// We don't understand this kind of tweak, so give up.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We don't understand this kind of action, so give up.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (highlight === undefined) {
|
||||||
|
// If a highlight tweak is missing a value then it defaults to true.
|
||||||
|
highlight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = {notify: notify, highlight: highlight};
|
||||||
|
if (sound !== null) {
|
||||||
|
result.sound = sound;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ACTION_NOTIFY = encodeActions({notify: true});
|
||||||
|
var ACTION_NOTIFY_DEFAULT_SOUND = encodeActions({notify: true, sound: "default"});
|
||||||
|
var ACTION_NOTIFY_RING_SOUND = encodeActions({notify: true, sound: "ring"});
|
||||||
|
var ACTION_HIGHLIGHT_DEFAULT_SOUND = encodeActions({notify: true, sound: "default", highlight: true});
|
||||||
|
var ACTION_DONT_NOTIFY = encodeActions({notify: false});
|
||||||
|
var ACTION_DISABLED = null;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The descriptions of rules managed by the Vector UI.
|
* The descriptions of rules managed by the Vector UI.
|
||||||
* Each rule is described so that if the server does not have it in its default
|
|
||||||
* rules or if the user wants to use actions ('PushRuleVectorState') that are
|
|
||||||
* different from the hs one, the code will create a new rule that will override
|
|
||||||
* the hs one.
|
|
||||||
*/
|
*/
|
||||||
var VectorPushRulesDefinitions = {
|
var VectorPushRulesDefinitions = {
|
||||||
|
|
||||||
// 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)
|
||||||
"im.vector.rule.contains_display_name": {
|
".m.rule.contains_display_name": {
|
||||||
kind: "underride",
|
kind: "underride",
|
||||||
hsDefaultRuleId: ".m.rule.contains_display_name",
|
|
||||||
description: "Messages containing my name",
|
description: "Messages containing my name",
|
||||||
conditions: [{
|
vectorStateToActions: { // The actions for each vector state, or null to disable the rule.
|
||||||
"kind": "contains_display_name"
|
on: ACTION_NOTIFY,
|
||||||
}],
|
loud: ACTION_HIGHLIGHT_DEFAULT_SOUND,
|
||||||
vectorStateToActions: { // The actions for each vector state
|
off: ACTION_DISABLED
|
||||||
on: [
|
}
|
||||||
"notify"
|
|
||||||
],
|
|
||||||
loud: [
|
|
||||||
"notify",
|
|
||||||
{
|
|
||||||
"set_tweak": "sound",
|
|
||||||
"value": "default"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"set_tweak":"highlight"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
vectorStateToHsDefaultRuleEnabled: { // If it exists, the hs default push rule enabled expected value for each vector state
|
|
||||||
on: undefined, // ON (and its actions) does not corresponds to the default hs push rule, so NA
|
|
||||||
loud: true, // LOUD corresponds to the default rule when its enabled value is true
|
|
||||||
off: false // OFF corresponds to the default rule when its enabled value is false
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Messages just sent to the user in a 1:1 room
|
// Messages just sent to the user in a 1:1 room
|
||||||
"im.vector.rule.room_one_to_one": {
|
".m.rule.room_one_to_one": {
|
||||||
kind: "underride",
|
kind: "underride",
|
||||||
hsDefaultRuleId: ".m.rule.room_one_to_one",
|
|
||||||
description: "Messages in one-to-one chats",
|
description: "Messages in one-to-one chats",
|
||||||
conditions: [{
|
|
||||||
"is": "2",
|
|
||||||
"kind": "room_member_count"
|
|
||||||
}],
|
|
||||||
vectorStateToActions: {
|
vectorStateToActions: {
|
||||||
on: [
|
on: ACTION_NOTIFY,
|
||||||
"notify"
|
loud: ACTION_NOTIFY_DEFAULT_SOUND,
|
||||||
],
|
off: ACTION_DONT_NOTIFY
|
||||||
loud: [
|
|
||||||
"notify",
|
|
||||||
{
|
|
||||||
"set_tweak": "sound",
|
|
||||||
"value": "default"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
off: [
|
|
||||||
"dont_notify"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
vectorStateToHsDefaultRuleEnabled: {
|
|
||||||
on: undefined,
|
|
||||||
loud: true,
|
|
||||||
off: undefined
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Messages just sent to a group chat room
|
// Messages just sent to a group chat room
|
||||||
// 1:1 room messages are catched by the .m.rule.room_one_to_one rule if any defined
|
// 1:1 room messages are catched by the .m.rule.room_one_to_one rule if any defined
|
||||||
// By opposition, all other room messages are from group chat rooms.
|
// By opposition, all other room messages are from group chat rooms.
|
||||||
"im.vector.rule.room_message": {
|
".m.rule.message": {
|
||||||
kind: "underride",
|
kind: "underride",
|
||||||
description: "Messages in group chats",
|
description: "Messages in group chats",
|
||||||
conditions: [{
|
|
||||||
"pattern": "m.room.message",
|
|
||||||
"kind": "event_match",
|
|
||||||
"key": "type"
|
|
||||||
}],
|
|
||||||
hsDefaultRuleId: ".m.rule.message",
|
|
||||||
vectorStateToActions: {
|
vectorStateToActions: {
|
||||||
on: [
|
on: ACTION_NOTIFY,
|
||||||
"notify"
|
loud: ACTION_NOTIFY_DEFAULT_SOUND,
|
||||||
],
|
off: ACTION_DONT_NOTIFY
|
||||||
loud: [
|
|
||||||
"notify",
|
|
||||||
{
|
|
||||||
"set_tweak": "sound",
|
|
||||||
"value": "default"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
off: [
|
|
||||||
"dont_notify"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
vectorStateToHsDefaultRuleEnabled: {
|
|
||||||
on: true,
|
|
||||||
loud: undefined,
|
|
||||||
off: undefined
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Invitation for the user
|
// Invitation for the user
|
||||||
"im.vector.rule.invite_for_me": {
|
".m.rule.invite_for_me": {
|
||||||
kind: "underride",
|
kind: "underride",
|
||||||
hsDefaultRuleId: ".m.rule.invite_for_me",
|
|
||||||
description: "When I'm invited to a room",
|
description: "When I'm invited to a room",
|
||||||
conditions: [
|
|
||||||
{
|
|
||||||
"key": "type",
|
|
||||||
"kind": "event_match",
|
|
||||||
"pattern": "m.room.member"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "content.membership",
|
|
||||||
"kind": "event_match",
|
|
||||||
"pattern": "invite"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "state_key",
|
|
||||||
"kind": "event_match",
|
|
||||||
"pattern": "" // It is updated at runtime the user id
|
|
||||||
}
|
|
||||||
],
|
|
||||||
vectorStateToActions: {
|
vectorStateToActions: {
|
||||||
on: [
|
on: ACTION_NOTIFY,
|
||||||
"notify"
|
loud: ACTION_NOTIFY_DEFAULT_SOUND,
|
||||||
],
|
off: ACTION_DISABLED
|
||||||
loud: [
|
|
||||||
"notify",
|
|
||||||
{
|
|
||||||
"set_tweak": "sound",
|
|
||||||
"value": "default"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
vectorStateToHsDefaultRuleEnabled: {
|
|
||||||
on: undefined,
|
|
||||||
loud: true,
|
|
||||||
off: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// When people join or leave a room
|
|
||||||
/*"im.vector.rule.member_event": {
|
|
||||||
hsDefaultRuleId: ".m.rule.member_event",
|
|
||||||
description: "When people join or leave a room",
|
|
||||||
conditions: [{
|
|
||||||
"pattern": "m.room.member",
|
|
||||||
"kind": "event_match",
|
|
||||||
"key": "type"
|
|
||||||
}],
|
|
||||||
vectorStateToActions: {
|
|
||||||
on: [
|
|
||||||
"notify"
|
|
||||||
],
|
|
||||||
loud: [
|
|
||||||
"notify",
|
|
||||||
{
|
|
||||||
"set_tweak": "sound",
|
|
||||||
"value": "default"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
vectorStateToHsDefaultRuleEnabled: {
|
|
||||||
on: true,
|
|
||||||
loud: undefined,
|
|
||||||
off: false
|
|
||||||
}
|
|
||||||
},*/
|
|
||||||
|
|
||||||
// Incoming call
|
// Incoming call
|
||||||
"im.vector.rule.call": {
|
".m.rule.call": {
|
||||||
kind: "underride",
|
kind: "underride",
|
||||||
hsDefaultRuleId: ".m.rule.call",
|
|
||||||
description: "Call invitation",
|
description: "Call invitation",
|
||||||
conditions: [{
|
|
||||||
"pattern": "m.room.member",
|
|
||||||
"kind": "event_match",
|
|
||||||
"key": "type"
|
|
||||||
}],
|
|
||||||
vectorStateToActions: {
|
vectorStateToActions: {
|
||||||
on: [
|
on: ACTION_NOTIFY,
|
||||||
"notify"
|
loud: ACTION_NOTIFY_RING_SOUND,
|
||||||
],
|
off: ACTION_DISABLED
|
||||||
loud: [
|
|
||||||
"notify",
|
|
||||||
{
|
|
||||||
"set_tweak": "sound",
|
|
||||||
"value": "ring"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
vectorStateToHsDefaultRuleEnabled: {
|
|
||||||
on: undefined,
|
|
||||||
loud: true,
|
|
||||||
off: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Notifications from bots
|
// Notifications from bots
|
||||||
"im.vector.rule.notices": {
|
".m.rule.suppress_notices": {
|
||||||
kind: "override",
|
kind: "override",
|
||||||
hsDefaultRuleId: ".m.rule.suppress_notices",
|
|
||||||
description: "Messages sent by bot",
|
description: "Messages sent by bot",
|
||||||
conditions: [{
|
|
||||||
"kind": "event_match",
|
|
||||||
"key": "content.msgtype",
|
|
||||||
"pattern": "m.notice"
|
|
||||||
}],
|
|
||||||
vectorStateToActions: {
|
vectorStateToActions: {
|
||||||
on: undefined, // ON for vector UI means that the .m.rule.suppress_notices rule is disabled.
|
// .m.rule.suppress_notices is a "negative" rule, we have to invert its enabled value for vector UI
|
||||||
loud: [
|
on: ACTION_DISABLED,
|
||||||
"notify",
|
loud: ACTION_NOTIFY_DEFAULT_SOUND,
|
||||||
{
|
off: ACTION_DONT_NOTIFY,
|
||||||
"set_tweak": "sound",
|
|
||||||
"value": "ring"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
off: [
|
|
||||||
"dont_notify"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
vectorStateToHsDefaultRuleEnabled: {
|
|
||||||
on: false, // .m.rule.suppress_notices is a "negative" rule, we have to invert its enabled value for vector UI
|
|
||||||
loud: undefined,
|
|
||||||
off: true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rules that Vector used to set in order to override the actions of default rules.
|
||||||
|
* These are used to port peoples existing overrides to match the current API.
|
||||||
|
* These can be removed and forgotten once everyone has moved to the new client.
|
||||||
|
*/
|
||||||
|
var LEGACY_RULES = {
|
||||||
|
"im.vector.rule.contains_display_name": ".m.rule.contains_display_name",
|
||||||
|
"im.vector.rule.room_one_to_one": ".m.rule.room_one_to_one",
|
||||||
|
"im.vector.rule.room_message": ".m.rule.message",
|
||||||
|
"im.vector.rule.invite_for_me": ".m.rule.invite_for_me",
|
||||||
|
"im.vector.rule.call": ".m.rule.call",
|
||||||
|
"im.vector.rule.notices": ".m.rule.suppress_notices"
|
||||||
|
};
|
||||||
|
|
||||||
|
function portLegacyActions(actions) {
|
||||||
|
var decoded = decodeActions(actions);
|
||||||
|
if (decoded !== null) {
|
||||||
|
return encodeActions(decoded);
|
||||||
|
} else {
|
||||||
|
// We don't recognise one of the actions here, so we don't try to
|
||||||
|
// canonicalise them.
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'Notififications',
|
displayName: 'Notififications',
|
||||||
|
|
||||||
|
@ -295,9 +241,6 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
// Finalise the vector definitions
|
|
||||||
VectorPushRulesDefinitions["im.vector.rule.invite_for_me"].conditions[2].pattern = MatrixClientPeg.get().credentials.userId;
|
|
||||||
|
|
||||||
this._refreshFromServer();
|
this._refreshFromServer();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -389,13 +332,10 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
_actionsFor: function(pushRuleVectorState) {
|
_actionsFor: function(pushRuleVectorState) {
|
||||||
if (pushRuleVectorState === PushRuleVectorState.ON) {
|
if (pushRuleVectorState === PushRuleVectorState.ON) {
|
||||||
return ['notify'];
|
return ACTION_NOTIFY;
|
||||||
}
|
}
|
||||||
else if (pushRuleVectorState === PushRuleVectorState.LOUD) {
|
else if (pushRuleVectorState === PushRuleVectorState.LOUD) {
|
||||||
return ['notify',
|
return ACTION_HIGHLIGHT_DEFAULT_SOUND;
|
||||||
{'set_tweak': 'sound', 'value': 'default'},
|
|
||||||
{'set_tweak': 'highlight', 'value': 'true'}
|
|
||||||
];;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -437,36 +377,18 @@ module.exports = React.createClass({
|
||||||
var ruleDefinition = VectorPushRulesDefinitions[rule.vectorRuleId];
|
var ruleDefinition = VectorPushRulesDefinitions[rule.vectorRuleId];
|
||||||
|
|
||||||
if (rule.rule) {
|
if (rule.rule) {
|
||||||
if (undefined !== ruleDefinition.vectorStateToHsDefaultRuleEnabled[newPushRuleVectorState] && rule.hsDefaultRule) {
|
var actions = ruleDefinition.vectorStateToActions[newPushRuleVectorState];
|
||||||
// The new state corresponds to the default hs rule
|
|
||||||
// Enable or disable it according to the rule definition
|
|
||||||
deferreds.push(cli.setPushRuleEnabled('global', rule.hsDefaultRule.kind, ruleDefinition.hsDefaultRuleId,
|
|
||||||
ruleDefinition.vectorStateToHsDefaultRuleEnabled[newPushRuleVectorState]));
|
|
||||||
|
|
||||||
// Remove the vector rule if any
|
if (actions === ACTION_DISABLED) {
|
||||||
if (!rule.isHSDefaultRule) {
|
// The new state corresponds to disabling the rule.
|
||||||
deferreds.push(cli.deletePushRule('global', rule.rule.kind, rule.rule.rule_id))
|
deferreds.push(cli.setPushRuleEnabled('global', rule.rule.kind, rule.rule.rule_id, false));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// The new state (and its implied actions) does not correspond to a default hs rule
|
// The new state corresponds to enabling the rule and setting specific actions
|
||||||
// or the HS does not expose this default rule.
|
deferreds.push(this._updatePushRuleActions(rule.rule, actions, true));
|
||||||
if (rule.isHSDefaultRule) {
|
|
||||||
// Create a new rule that will override the default one
|
|
||||||
deferreds.push(this._addOverridingVectorPushRule(rule.vectorRuleId, newPushRuleVectorState));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Change the actions of the existing overriding Vector rule
|
|
||||||
deferreds.push(this._updatePushRuleActions(rule.rule, ruleDefinition.vectorStateToActions[newPushRuleVectorState]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// This is a Vector rule which does not exist yet server side
|
|
||||||
// Create it
|
|
||||||
deferreds.push(this._addOverridingVectorPushRule(rule.vectorRuleId, newPushRuleVectorState));
|
|
||||||
}
|
|
||||||
|
|
||||||
q.all(deferreds).done(function() {
|
q.all(deferreds).done(function() {
|
||||||
self._refreshFromServer();
|
self._refreshFromServer();
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
|
@ -651,23 +573,45 @@ module.exports = React.createClass({
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Add a push rule server side according to the 'VectorPushRulesDefinitions' spec
|
// Check if any legacy im.vector rules need to be ported to the new API
|
||||||
_addOverridingVectorPushRule: function(vectorRuleId, vectorState) {
|
// for overriding the actions of default rules.
|
||||||
|
_portRulesToNewAPI: function(rulesets) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
var needsUpdate = [];
|
||||||
|
var cli = MatrixClientPeg.get();
|
||||||
|
|
||||||
// Create the rule as predefined
|
for (var kind in rulesets.global) {
|
||||||
var ruleDefinition = VectorPushRulesDefinitions[vectorRuleId];
|
var ruleset = rulesets.global[kind];
|
||||||
var body = {
|
for (var i = 0; i < ruleset.length; ++i) {
|
||||||
conditions: ruleDefinition.conditions,
|
var rule = ruleset[i];
|
||||||
actions: ruleDefinition.vectorStateToActions[vectorState]
|
if (rule.rule_id in LEGACY_RULES) {
|
||||||
|
console.log("Porting legacy rule", rule);
|
||||||
|
needsUpdate.push( function(kind, rule) {
|
||||||
|
return cli.setPushRuleActions(
|
||||||
|
'global', kind, LEGACY_RULES[rule.rule_id], portLegacyActions(rule.actions)
|
||||||
|
).then( function() {
|
||||||
|
return cli.deletePushRule('global', kind, rule.rule_id);
|
||||||
|
})
|
||||||
|
}(kind, rule));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsUpdate.length > 0) {
|
||||||
|
// If some of the rules need to be ported then wait for the porting
|
||||||
|
// to happen and then fetch the rules again.
|
||||||
|
return q.allSettled(needsUpdate).then( function() {
|
||||||
|
return cli.getPushRules();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Otherwise return the rules that we already have.
|
||||||
|
return rulesets;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MatrixClientPeg.get().addPushRule('global', ruleDefinition.kind, vectorRuleId, body);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_refreshFromServer: function() {
|
_refreshFromServer: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
MatrixClientPeg.get().getPushRules().done(function(rulesets) {
|
MatrixClientPeg.get().getPushRules().then(self._portRulesToNewAPI).done(function(rulesets) {
|
||||||
MatrixClientPeg.get().pushRules = rulesets;
|
MatrixClientPeg.get().pushRules = rulesets;
|
||||||
|
|
||||||
// Get homeserver default rules and triage them by categories
|
// Get homeserver default rules and triage them by categories
|
||||||
|
@ -690,8 +634,6 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// HS default rules
|
// HS default rules
|
||||||
var defaultRules = {master: [], vector: {}, others: []};
|
var defaultRules = {master: [], vector: {}, others: []};
|
||||||
// Push rules defined py Vector to override hs default rules
|
|
||||||
var vectorOverridingRules = {};
|
|
||||||
// Content/keyword rules
|
// Content/keyword rules
|
||||||
var contentRules = {on: [], on_but_disabled:[], loud: [], loud_but_disabled: [], other: []};
|
var contentRules = {on: [], on_but_disabled:[], loud: [], loud_but_disabled: [], other: []};
|
||||||
|
|
||||||
|
@ -700,30 +642,18 @@ module.exports = React.createClass({
|
||||||
var r = rulesets.global[kind][i];
|
var r = rulesets.global[kind][i];
|
||||||
var cat = rule_categories[r.rule_id];
|
var cat = rule_categories[r.rule_id];
|
||||||
r.kind = kind;
|
r.kind = kind;
|
||||||
if (r.rule_id[0] === '.') {
|
|
||||||
if (cat) {
|
|
||||||
if (cat === 'vector') {
|
|
||||||
// Remove disabled, useless actions
|
|
||||||
r.actions = r.actions.reduce(function(array, action){
|
|
||||||
if (action.value !== false) {
|
|
||||||
array.push(action);
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
},[]);
|
|
||||||
|
|
||||||
defaultRules.vector[r.rule_id] = r;
|
if (r.rule_id[0] === '.') {
|
||||||
}
|
if (cat === 'vector') {
|
||||||
else {
|
defaultRules.vector[r.rule_id] = r;
|
||||||
defaultRules[cat].push(r);
|
}
|
||||||
}
|
else if (cat === 'master') {
|
||||||
|
defaultRules.master.push(r);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
defaultRules['others'].push(r);
|
defaultRules['others'].push(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (r.rule_id.startsWith('im.vector')) {
|
|
||||||
vectorOverridingRules[r.rule_id] = r;
|
|
||||||
}
|
|
||||||
else if (kind === 'content') {
|
else if (kind === 'content') {
|
||||||
switch (self._contentRuleVectorStateKind(r)) {
|
switch (self._contentRuleVectorStateKind(r)) {
|
||||||
case PushRuleVectorState.ON:
|
case PushRuleVectorState.ON:
|
||||||
|
@ -804,14 +734,14 @@ module.exports = React.createClass({
|
||||||
self.state.vectorPushRules = [];
|
self.state.vectorPushRules = [];
|
||||||
|
|
||||||
var vectorRuleIds = [
|
var vectorRuleIds = [
|
||||||
'im.vector.rule.contains_display_name',
|
'.m.rule.contains_display_name',
|
||||||
'_keywords',
|
'_keywords',
|
||||||
'im.vector.rule.room_one_to_one',
|
'.m.rule.room_one_to_one',
|
||||||
'im.vector.rule.room_message',
|
'.m.rule.message',
|
||||||
'im.vector.rule.invite_for_me',
|
'.m.rule.invite_for_me',
|
||||||
//'im.vector.rule.member_event',
|
//'im.vector.rule.member_event',
|
||||||
'im.vector.rule.call',
|
'.m.rule.call',
|
||||||
'im.vector.rule.notices'
|
'.m.rule.suppress_notices'
|
||||||
];
|
];
|
||||||
for (var i in vectorRuleIds) {
|
for (var i in vectorRuleIds) {
|
||||||
var vectorRuleId = vectorRuleIds[i];
|
var vectorRuleId = vectorRuleIds[i];
|
||||||
|
@ -828,13 +758,7 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var rule = vectorOverridingRules[vectorRuleId];
|
var rule = defaultRules.vector[vectorRuleId];
|
||||||
var isHSDefaultRule = false;
|
|
||||||
if (!rule) {
|
|
||||||
// If the rule is not defined, look at the hs default one
|
|
||||||
rule = defaultRules.vector[ruleDefinition.hsDefaultRuleId];
|
|
||||||
isHSDefaultRule = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translate the rule actions and its enabled value into vector state
|
// Translate the rule actions and its enabled value into vector state
|
||||||
var vectorState;
|
var vectorState;
|
||||||
|
@ -843,9 +767,9 @@ module.exports = React.createClass({
|
||||||
var state = PushRuleVectorState[stateKey];
|
var state = PushRuleVectorState[stateKey];
|
||||||
var vectorStateToActions = ruleDefinition.vectorStateToActions[state];
|
var vectorStateToActions = ruleDefinition.vectorStateToActions[state];
|
||||||
|
|
||||||
if (!vectorStateToActions) {
|
if (vectorStateToActions === ACTION_DISABLED) {
|
||||||
// No defined actions means that this vector state expects a disabled default hs rule
|
// No defined actions means that this vector state expects a disabled default hs rule
|
||||||
if (isHSDefaultRule && rule.enabled === ruleDefinition.vectorStateToHsDefaultRuleEnabled[state]) {
|
if (rule.enabled === false) {
|
||||||
vectorState = state;
|
vectorState = state;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -853,14 +777,8 @@ module.exports = React.createClass({
|
||||||
else {
|
else {
|
||||||
// The actions must match to the ones expected by vector state
|
// The actions must match to the ones expected by vector state
|
||||||
if (JSON.stringify(rule.actions) === JSON.stringify(vectorStateToActions)) {
|
if (JSON.stringify(rule.actions) === JSON.stringify(vectorStateToActions)) {
|
||||||
if (isHSDefaultRule) {
|
// And the rule must be enabled.
|
||||||
// In the case of a default hs push rule, the enabled value must also match
|
if (rule.enabled === true) {
|
||||||
if (rule.enabled === ruleDefinition.vectorStateToHsDefaultRuleEnabled[state]) {
|
|
||||||
vectorState = state;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
vectorState = state;
|
vectorState = state;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -870,7 +788,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
if (!vectorState) {
|
if (!vectorState) {
|
||||||
console.error("Cannot translate rule actions into Vector rule state. Rule: " + rule);
|
console.error("Cannot translate rule actions into Vector rule state. Rule: " + rule);
|
||||||
vectorState = PushRuleVectorState.OFF;
|
vectorState = PushRuleVectorState.OFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -882,9 +800,7 @@ module.exports = React.createClass({
|
||||||
"description" : ruleDefinition.description,
|
"description" : ruleDefinition.description,
|
||||||
"rule": rule,
|
"rule": rule,
|
||||||
"vectorState": vectorState,
|
"vectorState": vectorState,
|
||||||
"isHSDefaultRule": isHSDefaultRule,
|
});
|
||||||
"hsDefaultRule": defaultRules.vector[ruleDefinition.hsDefaultRuleId]
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -913,39 +829,21 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_updatePushRuleActions: function(rule, actions, enabled) {
|
_updatePushRuleActions: function(rule, actions, enabled) {
|
||||||
// Workaround for SYN-590 : Push rule update fails
|
|
||||||
// Remove the rule and recreate it with the new actions
|
|
||||||
var cli = MatrixClientPeg.get();
|
var cli = MatrixClientPeg.get();
|
||||||
var deferred = q.defer();
|
var deferred = q.defer();
|
||||||
|
|
||||||
cli.deletePushRule('global', rule.kind, rule.rule_id).done(function() {
|
|
||||||
cli.addPushRule('global', rule.kind, rule.rule_id, {
|
|
||||||
conditions: rule.conditions,
|
|
||||||
actions: actions,
|
|
||||||
pattern: rule.pattern
|
|
||||||
}).done(function() {
|
|
||||||
|
|
||||||
// Then, if requested, enabled or disabled the rule
|
return cli.setPushRuleActions(
|
||||||
if (undefined != enabled) {
|
'global', rule.kind, rule.rule_id, actions
|
||||||
cli.setPushRuleEnabled('global', rule.kind, rule.rule_id, enabled).done(function() {
|
).then( function() {
|
||||||
deferred.resolve();
|
// Then, if requested, enabled or disabled the rule
|
||||||
}, function(err) {
|
if (undefined != enabled) {
|
||||||
deferred.reject(err);
|
return cli.setPushRuleEnabled(
|
||||||
});
|
'global', rule.kind, rule.rule_id, enabled
|
||||||
}
|
);
|
||||||
else {
|
}
|
||||||
deferred.resolve();
|
});
|
||||||
}
|
|
||||||
}, function(err) {
|
|
||||||
deferred.reject(err);
|
|
||||||
});
|
|
||||||
}, function(err) {
|
|
||||||
deferred.reject(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
renderNotifRulesTableRow: function(title, className, pushRuleVectorState) {
|
renderNotifRulesTableRow: function(title, className, pushRuleVectorState) {
|
||||||
return (
|
return (
|
||||||
<tr key = {className}>
|
<tr key = {className}>
|
||||||
|
@ -1019,7 +917,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// When enabled, the master rule inhibits all existing rules
|
// When enabled, the master rule inhibits all existing rules
|
||||||
// So do not show all notification settings
|
// So do not show all notification settings
|
||||||
if (this.state.masterPushRule.enabled) {
|
if (this.state.masterPushRule && this.state.masterPushRule.enabled) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{masterPushRuleDiv}
|
{masterPushRuleDiv}
|
||||||
|
|
Loading…
Reference in a new issue