[Room] New push rule methods
This commit is contained in:
		
							parent
							
								
									579570a19e
								
							
						
					
					
						commit
						fd43196c9d
					
				|  | @ -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 } | ||||||
|  |  | ||||||
|  | @ -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 New Issue