move notifications logic over from riot-web
This commit is contained in:
parent
8ab8f76254
commit
178fb647ad
6 changed files with 508 additions and 0 deletions
125
src/notifications/ContentRules.js
Normal file
125
src/notifications/ContentRules.js
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var PushRuleVectorState = require('./PushRuleVectorState');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* Extract the keyword rules from a list of rules, and parse them
|
||||||
|
* into a form which is useful for Vector's UI.
|
||||||
|
*
|
||||||
|
* Returns an object containing:
|
||||||
|
* rules: the primary list of keyword rules
|
||||||
|
* vectorState: a PushRuleVectorState indicating whether those rules are
|
||||||
|
* OFF/ON/LOUD
|
||||||
|
* externalRules: a list of other keyword rules, with states other than
|
||||||
|
* vectorState
|
||||||
|
*/
|
||||||
|
parseContentRules: function(rulesets) {
|
||||||
|
// first categorise the keyword rules in terms of their actions
|
||||||
|
var contentRules = this._categoriseContentRules(rulesets);
|
||||||
|
|
||||||
|
// Decide which content rules to display in Vector UI.
|
||||||
|
// Vector displays a single global rule for a list of keywords
|
||||||
|
// whereas Matrix has a push rule per keyword.
|
||||||
|
// Vector can set the unique rule in ON, LOUD or OFF state.
|
||||||
|
// Matrix has enabled/disabled plus a combination of (highlight, sound) tweaks.
|
||||||
|
|
||||||
|
// The code below determines which set of user's content push rules can be
|
||||||
|
// displayed by the vector UI.
|
||||||
|
// Push rules that does not fit, ie defined by another Matrix client, ends
|
||||||
|
// in externalRules.
|
||||||
|
// There is priority in the determination of which set will be the displayed one.
|
||||||
|
// The set with rules that have LOUD tweaks is the first choice. Then, the ones
|
||||||
|
// with ON tweaks (no tweaks).
|
||||||
|
|
||||||
|
if (contentRules.loud.length) {
|
||||||
|
return {
|
||||||
|
vectorState: PushRuleVectorState.LOUD,
|
||||||
|
rules: contentRules.loud,
|
||||||
|
externalRules: [].concat(contentRules.loud_but_disabled, contentRules.on, contentRules.on_but_disabled, contentRules.other),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (contentRules.loud_but_disabled.length) {
|
||||||
|
return {
|
||||||
|
vectorState: PushRuleVectorState.OFF,
|
||||||
|
rules: contentRules.loud_but_disabled,
|
||||||
|
externalRules: [].concat(contentRules.on, contentRules.on_but_disabled, contentRules.other),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (contentRules.on.length) {
|
||||||
|
return {
|
||||||
|
vectorState: PushRuleVectorState.ON,
|
||||||
|
rules: contentRules.on,
|
||||||
|
externalRules: [].concat(contentRules.on_but_disabled, contentRules.other),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (contentRules.on_but_disabled.length) {
|
||||||
|
return {
|
||||||
|
vectorState: PushRuleVectorState.OFF,
|
||||||
|
rules: contentRules.on_but_disabled,
|
||||||
|
externalRules: contentRules.other,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
vectorState: PushRuleVectorState.ON,
|
||||||
|
rules: [],
|
||||||
|
externalRules: contentRules.other,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_categoriseContentRules: function(rulesets) {
|
||||||
|
var contentRules = {on: [], on_but_disabled:[], loud: [], loud_but_disabled: [], other: []};
|
||||||
|
for (var kind in rulesets.global) {
|
||||||
|
for (var i = 0; i < Object.keys(rulesets.global[kind]).length; ++i) {
|
||||||
|
var r = rulesets.global[kind][i];
|
||||||
|
|
||||||
|
// check it's not a default rule
|
||||||
|
if (r.rule_id[0] === '.' || kind !== 'content') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
r.kind = kind; // is this needed? not sure
|
||||||
|
|
||||||
|
switch (PushRuleVectorState.contentRuleVectorStateKind(r)) {
|
||||||
|
case PushRuleVectorState.ON:
|
||||||
|
if (r.enabled) {
|
||||||
|
contentRules.on.push(r);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
contentRules.on_but_disabled.push(r);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PushRuleVectorState.LOUD:
|
||||||
|
if (r.enabled) {
|
||||||
|
contentRules.loud.push(r);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
contentRules.loud_but_disabled.push(r);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
contentRules.other.push(r);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contentRules;
|
||||||
|
},
|
||||||
|
};
|
89
src/notifications/NotificationUtils.js
Normal file
89
src/notifications/NotificationUtils.js
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
// Encodes a dictionary of {
|
||||||
|
// "notify": true/false,
|
||||||
|
// "sound": string or undefined,
|
||||||
|
// "highlight: true/false,
|
||||||
|
// }
|
||||||
|
// to a list of push actions.
|
||||||
|
encodeActions: function(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.
|
||||||
|
decodeActions: function(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;
|
||||||
|
},
|
||||||
|
};
|
94
src/notifications/PushRuleVectorState.js
Normal file
94
src/notifications/PushRuleVectorState.js
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var StandardActions = require('./StandardActions');
|
||||||
|
var NotificationUtils = require('./NotificationUtils');
|
||||||
|
|
||||||
|
var states = {
|
||||||
|
/** The push rule is disabled */
|
||||||
|
OFF: "off",
|
||||||
|
|
||||||
|
/** The user will receive push notification for this rule */
|
||||||
|
ON: "on",
|
||||||
|
|
||||||
|
/** The user will receive push notification for this rule with sound and
|
||||||
|
highlight if this is legitimate */
|
||||||
|
LOUD: "loud",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* Enum for state of a push rule as defined by the Vector UI.
|
||||||
|
* @readonly
|
||||||
|
* @enum {string}
|
||||||
|
*/
|
||||||
|
states: states,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a PushRuleVectorState to a list of actions
|
||||||
|
*
|
||||||
|
* @return [object] list of push-rule actions
|
||||||
|
*/
|
||||||
|
actionsFor: function(pushRuleVectorState) {
|
||||||
|
if (pushRuleVectorState === this.ON) {
|
||||||
|
return StandardActions.ACTION_NOTIFY;
|
||||||
|
}
|
||||||
|
else if (pushRuleVectorState === this.LOUD) {
|
||||||
|
return StandardActions.ACTION_HIGHLIGHT_DEFAULT_SOUND;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a pushrule's actions to a PushRuleVectorState.
|
||||||
|
*
|
||||||
|
* Determines whether a content rule is in the PushRuleVectorState.ON
|
||||||
|
* category or in PushRuleVectorState.LOUD, regardless of its enabled
|
||||||
|
* state. Returns null if it does not match these categories.
|
||||||
|
*/
|
||||||
|
contentRuleVectorStateKind: function(rule) {
|
||||||
|
var decoded = NotificationUtils.decodeActions(rule.actions);
|
||||||
|
|
||||||
|
if (!decoded) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count tweaks to determine if it is a ON or LOUD rule
|
||||||
|
var tweaks = 0;
|
||||||
|
if (decoded.sound) {
|
||||||
|
tweaks++;
|
||||||
|
}
|
||||||
|
if (decoded.highlight) {
|
||||||
|
tweaks++;
|
||||||
|
}
|
||||||
|
var stateKind = null;
|
||||||
|
switch (tweaks) {
|
||||||
|
case 0:
|
||||||
|
stateKind = this.ON;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
stateKind = this.LOUD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return stateKind;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var k in states) {
|
||||||
|
module.exports[k] = states[k];
|
||||||
|
};
|
30
src/notifications/StandardActions.js
Normal file
30
src/notifications/StandardActions.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var NotificationUtils = require('./NotificationUtils');
|
||||||
|
|
||||||
|
var encodeActions = NotificationUtils.encodeActions;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
ACTION_NOTIFY: encodeActions({notify: true}),
|
||||||
|
ACTION_NOTIFY_DEFAULT_SOUND: encodeActions({notify: true, sound: "default"}),
|
||||||
|
ACTION_NOTIFY_RING_SOUND: encodeActions({notify: true, sound: "ring"}),
|
||||||
|
ACTION_HIGHLIGHT_DEFAULT_SOUND: encodeActions({notify: true, sound: "default", highlight: true}),
|
||||||
|
ACTION_DONT_NOTIFY: encodeActions({notify: false}),
|
||||||
|
ACTION_DISABLED: null,
|
||||||
|
};
|
146
src/notifications/VectorPushRulesDefinitions.js
Normal file
146
src/notifications/VectorPushRulesDefinitions.js
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import { _td } from 'matrix-react-sdk/lib/languageHandler';
|
||||||
|
|
||||||
|
var StandardActions = require('./StandardActions');
|
||||||
|
var PushRuleVectorState = require('./PushRuleVectorState');
|
||||||
|
|
||||||
|
class VectorPushRuleDefinition {
|
||||||
|
constructor(opts) {
|
||||||
|
this.kind = opts.kind;
|
||||||
|
this.description = opts.description;
|
||||||
|
this.vectorStateToActions = opts.vectorStateToActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate the rule actions and its enabled value into vector state
|
||||||
|
ruleToVectorState(rule) {
|
||||||
|
var enabled = false;
|
||||||
|
var actions = null;
|
||||||
|
if (rule) {
|
||||||
|
enabled = rule.enabled;
|
||||||
|
actions = rule.actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var stateKey in PushRuleVectorState.states) {
|
||||||
|
var state = PushRuleVectorState.states[stateKey];
|
||||||
|
var vectorStateToActions = this.vectorStateToActions[state];
|
||||||
|
|
||||||
|
if (!vectorStateToActions) {
|
||||||
|
// No defined actions means that this vector state expects a disabled (or absent) rule
|
||||||
|
if (!enabled) {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The actions must match to the ones expected by vector state
|
||||||
|
if (enabled && JSON.stringify(rule.actions) === JSON.stringify(vectorStateToActions)) {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error("Cannot translate rule actions into Vector rule state. Rule: " +
|
||||||
|
JSON.stringify(rule));
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The descriptions of rules managed by the Vector UI.
|
||||||
|
*/
|
||||||
|
module.exports = {
|
||||||
|
// Messages containing user's display name
|
||||||
|
".m.rule.contains_display_name": new VectorPushRuleDefinition({
|
||||||
|
kind: "override",
|
||||||
|
description: _td("Messages containing my display name"), // passed through _t() translation in src/components/views/settings/Notifications.js
|
||||||
|
vectorStateToActions: { // The actions for each vector state, or null to disable the rule.
|
||||||
|
on: StandardActions.ACTION_NOTIFY,
|
||||||
|
loud: StandardActions.ACTION_HIGHLIGHT_DEFAULT_SOUND,
|
||||||
|
off: StandardActions.ACTION_DISABLED
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Messages containing user's username (localpart/MXID)
|
||||||
|
".m.rule.contains_user_name": new VectorPushRuleDefinition({
|
||||||
|
kind: "override",
|
||||||
|
description: _td("Messages containing my user name"), // passed through _t() translation in src/components/views/settings/Notifications.js
|
||||||
|
vectorStateToActions: { // The actions for each vector state, or null to disable the rule.
|
||||||
|
on: StandardActions.ACTION_NOTIFY,
|
||||||
|
loud: StandardActions.ACTION_HIGHLIGHT_DEFAULT_SOUND,
|
||||||
|
off: StandardActions.ACTION_DISABLED
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Messages just sent to the user in a 1:1 room
|
||||||
|
".m.rule.room_one_to_one": new VectorPushRuleDefinition({
|
||||||
|
kind: "underride",
|
||||||
|
description: _td("Messages in one-to-one chats"), // passed through _t() translation in src/components/views/settings/Notifications.js
|
||||||
|
vectorStateToActions: {
|
||||||
|
on: StandardActions.ACTION_NOTIFY,
|
||||||
|
loud: StandardActions.ACTION_NOTIFY_DEFAULT_SOUND,
|
||||||
|
off: StandardActions.ACTION_DONT_NOTIFY
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// By opposition, all other room messages are from group chat rooms.
|
||||||
|
".m.rule.message": new VectorPushRuleDefinition({
|
||||||
|
kind: "underride",
|
||||||
|
description: _td("Messages in group chats"), // passed through _t() translation in src/components/views/settings/Notifications.js
|
||||||
|
vectorStateToActions: {
|
||||||
|
on: StandardActions.ACTION_NOTIFY,
|
||||||
|
loud: StandardActions.ACTION_NOTIFY_DEFAULT_SOUND,
|
||||||
|
off: StandardActions.ACTION_DONT_NOTIFY
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Invitation for the user
|
||||||
|
".m.rule.invite_for_me": new VectorPushRuleDefinition({
|
||||||
|
kind: "underride",
|
||||||
|
description: _td("When I'm invited to a room"), // passed through _t() translation in src/components/views/settings/Notifications.js
|
||||||
|
vectorStateToActions: {
|
||||||
|
on: StandardActions.ACTION_NOTIFY,
|
||||||
|
loud: StandardActions.ACTION_NOTIFY_DEFAULT_SOUND,
|
||||||
|
off: StandardActions.ACTION_DISABLED
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Incoming call
|
||||||
|
".m.rule.call": new VectorPushRuleDefinition({
|
||||||
|
kind: "underride",
|
||||||
|
description: _td("Call invitation"), // passed through _t() translation in src/components/views/settings/Notifications.js
|
||||||
|
vectorStateToActions: {
|
||||||
|
on: StandardActions.ACTION_NOTIFY,
|
||||||
|
loud: StandardActions.ACTION_NOTIFY_RING_SOUND,
|
||||||
|
off: StandardActions.ACTION_DISABLED
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Notifications from bots
|
||||||
|
".m.rule.suppress_notices": new VectorPushRuleDefinition({
|
||||||
|
kind: "override",
|
||||||
|
description: _td("Messages sent by bot"), // passed through _t() translation in src/components/views/settings/Notifications.js
|
||||||
|
vectorStateToActions: {
|
||||||
|
// .m.rule.suppress_notices is a "negative" rule, we have to invert its enabled value for vector UI
|
||||||
|
on: StandardActions.ACTION_DISABLED,
|
||||||
|
loud: StandardActions.ACTION_NOTIFY_DEFAULT_SOUND,
|
||||||
|
off: StandardActions.ACTION_DONT_NOTIFY,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
};
|
24
src/notifications/index.js
Normal file
24
src/notifications/index.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
NotificationUtils: require('./NotificationUtils'),
|
||||||
|
PushRuleVectorState: require('./PushRuleVectorState'),
|
||||||
|
VectorPushRulesDefinitions: require('./VectorPushRulesDefinitions'),
|
||||||
|
ContentRules: require('./ContentRules'),
|
||||||
|
};
|
Loading…
Add table
Add a link
Reference in a new issue