Merge branch 'room-enhance-push-rules' into 'master'
[Room] New push rule methods Closes #13 See merge request famedly/famedlysdk!132
This commit is contained in:
commit
a9a1a5ddd5
|
@ -852,4 +852,107 @@ class Room {
|
||||||
return ownPowerLevel >=
|
return ownPowerLevel >=
|
||||||
getState("m.room.power_levels").content["events"][eventType];
|
getState("m.room.power_levels").content["events"][eventType];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the [PushRuleState] for this room, based on the m.push_rules stored in
|
||||||
|
/// the account_data.
|
||||||
|
PushRuleState get pushRuleState {
|
||||||
|
if (!client.accountData.containsKey("m.push_rules") ||
|
||||||
|
!(client.accountData["m.push_rules"].content["global"] is Map))
|
||||||
|
return PushRuleState.notify;
|
||||||
|
final Map<String, dynamic> globalPushRules =
|
||||||
|
client.accountData["m.push_rules"].content["global"];
|
||||||
|
if (globalPushRules == null) return PushRuleState.notify;
|
||||||
|
|
||||||
|
if (globalPushRules["override"] is List) {
|
||||||
|
for (var i = 0; i < globalPushRules["override"].length; i++) {
|
||||||
|
if (globalPushRules["override"][i]["rule_id"] == id) {
|
||||||
|
if (globalPushRules["override"][i]["actions"]
|
||||||
|
.indexOf("dont_notify") !=
|
||||||
|
-1) {
|
||||||
|
return PushRuleState.dont_notify;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (globalPushRules["room"] is List) {
|
||||||
|
for (var i = 0; i < globalPushRules["room"].length; i++) {
|
||||||
|
if (globalPushRules["room"][i]["rule_id"] == id) {
|
||||||
|
if (globalPushRules["room"][i]["actions"].indexOf("dont_notify") !=
|
||||||
|
-1) {
|
||||||
|
return PushRuleState.mentions_only;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PushRuleState.notify;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sends a request to the homeserver to set the [PushRuleState] for this room.
|
||||||
|
/// Returns ErrorResponse if something goes wrong.
|
||||||
|
Future<dynamic> setPushRuleState(PushRuleState newState) async {
|
||||||
|
if (newState == pushRuleState) return null;
|
||||||
|
dynamic resp;
|
||||||
|
switch (newState) {
|
||||||
|
// All push notifications should be sent to the user
|
||||||
|
case PushRuleState.notify:
|
||||||
|
if (pushRuleState == PushRuleState.dont_notify)
|
||||||
|
resp = await client.connection.jsonRequest(
|
||||||
|
type: HTTPType.DELETE,
|
||||||
|
action: "/client/r0/pushrules/global/override/$id",
|
||||||
|
data: {});
|
||||||
|
else if (pushRuleState == PushRuleState.mentions_only)
|
||||||
|
resp = await client.connection.jsonRequest(
|
||||||
|
type: HTTPType.DELETE,
|
||||||
|
action: "/client/r0/pushrules/global/room/$id",
|
||||||
|
data: {});
|
||||||
|
break;
|
||||||
|
// Only when someone mentions the user, a push notification should be sent
|
||||||
|
case PushRuleState.mentions_only:
|
||||||
|
if (pushRuleState == PushRuleState.dont_notify) {
|
||||||
|
resp = await client.connection.jsonRequest(
|
||||||
|
type: HTTPType.DELETE,
|
||||||
|
action: "/client/r0/pushrules/global/override/$id",
|
||||||
|
data: {});
|
||||||
|
if (resp == ErrorResponse) return resp;
|
||||||
|
resp = await client.connection.jsonRequest(
|
||||||
|
type: HTTPType.PUT,
|
||||||
|
action: "/client/r0/pushrules/global/room/$id",
|
||||||
|
data: {
|
||||||
|
"actions": ["dont_notify"]
|
||||||
|
});
|
||||||
|
} else if (pushRuleState == PushRuleState.notify)
|
||||||
|
resp = await client.connection.jsonRequest(
|
||||||
|
type: HTTPType.PUT,
|
||||||
|
action: "/client/r0/pushrules/global/room/$id",
|
||||||
|
data: {
|
||||||
|
"actions": ["dont_notify"]
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
// No push notification should be ever sent for this room.
|
||||||
|
case PushRuleState.dont_notify:
|
||||||
|
if (pushRuleState == PushRuleState.mentions_only) {
|
||||||
|
resp = await client.connection.jsonRequest(
|
||||||
|
type: HTTPType.DELETE,
|
||||||
|
action: "/client/r0/pushrules/global/room/$id",
|
||||||
|
data: {});
|
||||||
|
if (resp == ErrorResponse) return resp;
|
||||||
|
}
|
||||||
|
resp = await client.connection.jsonRequest(
|
||||||
|
type: HTTPType.PUT,
|
||||||
|
action: "/client/r0/pushrules/global/override/$id",
|
||||||
|
data: {
|
||||||
|
"actions": ["dont_notify"],
|
||||||
|
"conditions": [
|
||||||
|
{"key": "room_id", "kind": "event_match", "pattern": id}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum PushRuleState { notify, mentions_only, dont_notify }
|
||||||
|
|
64
lib/src/utils/PushRule.dart
Normal file
64
lib/src/utils/PushRule.dart
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
class PushRule {
|
||||||
|
final String ruleId;
|
||||||
|
final bool isDefault;
|
||||||
|
final bool enabled;
|
||||||
|
final List<Conditions> conditions;
|
||||||
|
final List<dynamic> actions;
|
||||||
|
|
||||||
|
PushRule(
|
||||||
|
{this.ruleId,
|
||||||
|
this.isDefault,
|
||||||
|
this.enabled,
|
||||||
|
this.conditions,
|
||||||
|
this.actions});
|
||||||
|
|
||||||
|
PushRule.fromJson(Map<String, dynamic> json)
|
||||||
|
: ruleId = json['rule_id'],
|
||||||
|
isDefault = json['is_default'],
|
||||||
|
enabled = json['enabled'],
|
||||||
|
conditions = _getConditionsFromJson(json['conditions']),
|
||||||
|
actions = json['actions'];
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['rule_id'] = this.ruleId;
|
||||||
|
data['is_default'] = this.isDefault;
|
||||||
|
data['enabled'] = this.enabled;
|
||||||
|
if (this.conditions != null) {
|
||||||
|
data['conditions'] = this.conditions.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
data['actions'] = this.actions;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<Conditions> _getConditionsFromJson(List<dynamic> json) {
|
||||||
|
List<Conditions> conditions = [];
|
||||||
|
if (json == null) return conditions;
|
||||||
|
for (int i = 0; i < json.length; i++) {
|
||||||
|
conditions.add(Conditions.fromJson(json[i]));
|
||||||
|
}
|
||||||
|
return conditions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Conditions {
|
||||||
|
String key;
|
||||||
|
String kind;
|
||||||
|
String pattern;
|
||||||
|
|
||||||
|
Conditions({this.key, this.kind, this.pattern});
|
||||||
|
|
||||||
|
Conditions.fromJson(Map<String, dynamic> json) {
|
||||||
|
key = json['key'];
|
||||||
|
kind = json['kind'];
|
||||||
|
pattern = json['pattern'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['key'] = this.key;
|
||||||
|
data['kind'] = this.kind;
|
||||||
|
data['pattern'] = this.pattern;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -120,7 +120,7 @@ void main() {
|
||||||
expect(firstSync, true);
|
expect(firstSync, true);
|
||||||
expect(sync["next_batch"] == matrix.prevBatch, true);
|
expect(sync["next_batch"] == matrix.prevBatch, true);
|
||||||
|
|
||||||
expect(matrix.accountData.length, 2);
|
expect(matrix.accountData.length, 3);
|
||||||
expect(matrix.getDirectChatFromUserId("@bob:example.com"),
|
expect(matrix.getDirectChatFromUserId("@bob:example.com"),
|
||||||
"!726s6s6q:example.com");
|
"!726s6s6q:example.com");
|
||||||
expect(matrix.roomList.rooms[1].directChatMatrixID, "@bob:example.com");
|
expect(matrix.roomList.rooms[1].directChatMatrixID, "@bob:example.com");
|
||||||
|
@ -147,7 +147,7 @@ void main() {
|
||||||
expect(
|
expect(
|
||||||
matrix.presences["@alice:example.com"].presence, PresenceType.online);
|
matrix.presences["@alice:example.com"].presence, PresenceType.online);
|
||||||
expect(presenceCounter, 1);
|
expect(presenceCounter, 1);
|
||||||
expect(accountDataCounter, 2);
|
expect(accountDataCounter, 3);
|
||||||
|
|
||||||
matrix.connection.onEvent.add(
|
matrix.connection.onEvent.add(
|
||||||
EventUpdate(
|
EventUpdate(
|
||||||
|
@ -283,13 +283,16 @@ void main() {
|
||||||
|
|
||||||
List<UserUpdate> eventUpdateList = await userUpdateListFuture;
|
List<UserUpdate> eventUpdateList = await userUpdateListFuture;
|
||||||
|
|
||||||
expect(eventUpdateList.length, 4);
|
expect(eventUpdateList.length, 5);
|
||||||
|
|
||||||
expect(eventUpdateList[0].eventType == "m.presence", true);
|
expect(eventUpdateList[0].eventType, "m.presence");
|
||||||
expect(eventUpdateList[0].type == "presence", true);
|
expect(eventUpdateList[0].type, "presence");
|
||||||
|
|
||||||
expect(eventUpdateList[1].eventType == "org.example.custom.config", true);
|
expect(eventUpdateList[1].eventType, "m.push_rules");
|
||||||
expect(eventUpdateList[1].type == "account_data", true);
|
expect(eventUpdateList[1].type, "account_data");
|
||||||
|
|
||||||
|
expect(eventUpdateList[2].eventType, "org.example.custom.config");
|
||||||
|
expect(eventUpdateList[2].type, "account_data");
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Login', () async {
|
test('Login', () async {
|
||||||
|
|
|
@ -75,6 +75,173 @@ class FakeMatrixApi extends MockClient {
|
||||||
},
|
},
|
||||||
"account_data": {
|
"account_data": {
|
||||||
"events": [
|
"events": [
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"global": {
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "sound", "value": "default"},
|
||||||
|
{"set_tweak": "highlight"}
|
||||||
|
],
|
||||||
|
"default": true,
|
||||||
|
"enabled": true,
|
||||||
|
"pattern": "alice",
|
||||||
|
"rule_id": ".m.rule.contains_user_name"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"override": [
|
||||||
|
{
|
||||||
|
"actions": ["dont_notify"],
|
||||||
|
"conditions": [],
|
||||||
|
"default": true,
|
||||||
|
"enabled": false,
|
||||||
|
"rule_id": ".m.rule.master"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actions": ["dont_notify"],
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"key": "content.msgtype",
|
||||||
|
"kind": "event_match",
|
||||||
|
"pattern": "m.notice"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": true,
|
||||||
|
"enabled": true,
|
||||||
|
"rule_id": ".m.rule.suppress_notices"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"room": [
|
||||||
|
{
|
||||||
|
"actions": ["dont_notify"],
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"key": "room_id",
|
||||||
|
"kind": "event_match",
|
||||||
|
"pattern": "!localpart:server.abc",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": true,
|
||||||
|
"enabled": true,
|
||||||
|
"rule_id": "!localpart:server.abc"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sender": [],
|
||||||
|
"underride": [
|
||||||
|
{
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "sound", "value": "ring"},
|
||||||
|
{"set_tweak": "highlight", "value": false}
|
||||||
|
],
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"key": "type",
|
||||||
|
"kind": "event_match",
|
||||||
|
"pattern": "m.call.invite"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": true,
|
||||||
|
"enabled": true,
|
||||||
|
"rule_id": ".m.rule.call"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "sound", "value": "default"},
|
||||||
|
{"set_tweak": "highlight"}
|
||||||
|
],
|
||||||
|
"conditions": [
|
||||||
|
{"kind": "contains_display_name"}
|
||||||
|
],
|
||||||
|
"default": true,
|
||||||
|
"enabled": true,
|
||||||
|
"rule_id": ".m.rule.contains_display_name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "sound", "value": "default"},
|
||||||
|
{"set_tweak": "highlight", "value": false}
|
||||||
|
],
|
||||||
|
"conditions": [
|
||||||
|
{"is": "2", "kind": "room_member_count"},
|
||||||
|
{
|
||||||
|
"key": "type",
|
||||||
|
"kind": "event_match",
|
||||||
|
"pattern": "m.room.message"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": true,
|
||||||
|
"enabled": true,
|
||||||
|
"rule_id": ".m.rule.room_one_to_one"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "sound", "value": "default"},
|
||||||
|
{"set_tweak": "highlight", "value": false}
|
||||||
|
],
|
||||||
|
"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": "@alice:example.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": true,
|
||||||
|
"enabled": true,
|
||||||
|
"rule_id": ".m.rule.invite_for_me"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "highlight", "value": false}
|
||||||
|
],
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"key": "type",
|
||||||
|
"kind": "event_match",
|
||||||
|
"pattern": "m.room.member"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": true,
|
||||||
|
"enabled": true,
|
||||||
|
"rule_id": ".m.rule.member_event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "highlight", "value": false}
|
||||||
|
],
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"key": "type",
|
||||||
|
"kind": "event_match",
|
||||||
|
"pattern": "m.room.message"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": true,
|
||||||
|
"enabled": true,
|
||||||
|
"rule_id": ".m.rule.message"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "m.push_rules"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "org.example.custom.config",
|
"type": "org.example.custom.config",
|
||||||
"content": {"custom_config_key": "custom_config_value"}
|
"content": {"custom_config_key": "custom_config_value"}
|
||||||
|
|
|
@ -335,5 +335,12 @@ void main() {
|
||||||
await room.sendFileEvent(testFile, "m.file", txid: "testtxid");
|
await room.sendFileEvent(testFile, "m.file", txid: "testtxid");
|
||||||
expect(resp, "42");
|
expect(resp, "42");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('pushRuleState', () async {
|
||||||
|
expect(room.pushRuleState, PushRuleState.mentions_only);
|
||||||
|
matrix.accountData["m.push_rules"].content["global"]["override"]
|
||||||
|
.add(matrix.accountData["m.push_rules"].content["global"]["room"][0]);
|
||||||
|
expect(room.pushRuleState, PushRuleState.dont_notify);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue