[Room] New push rule methods
This commit is contained in:
		
							parent
							
								
									579570a19e
								
							
						
					
					
						commit
						fd43196c9d
					
				|  | @ -852,4 +852,107 @@ class Room { | |||
|     return ownPowerLevel >= | ||||
|         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(sync["next_batch"] == matrix.prevBatch, true); | ||||
| 
 | ||||
|       expect(matrix.accountData.length, 2); | ||||
|       expect(matrix.accountData.length, 3); | ||||
|       expect(matrix.getDirectChatFromUserId("@bob:example.com"), | ||||
|           "!726s6s6q:example.com"); | ||||
|       expect(matrix.roomList.rooms[1].directChatMatrixID, "@bob:example.com"); | ||||
|  | @ -147,7 +147,7 @@ void main() { | |||
|       expect( | ||||
|           matrix.presences["@alice:example.com"].presence, PresenceType.online); | ||||
|       expect(presenceCounter, 1); | ||||
|       expect(accountDataCounter, 2); | ||||
|       expect(accountDataCounter, 3); | ||||
| 
 | ||||
|       matrix.connection.onEvent.add( | ||||
|         EventUpdate( | ||||
|  | @ -283,13 +283,16 @@ void main() { | |||
| 
 | ||||
|       List<UserUpdate> eventUpdateList = await userUpdateListFuture; | ||||
| 
 | ||||
|       expect(eventUpdateList.length, 4); | ||||
|       expect(eventUpdateList.length, 5); | ||||
| 
 | ||||
|       expect(eventUpdateList[0].eventType == "m.presence", true); | ||||
|       expect(eventUpdateList[0].type == "presence", true); | ||||
|       expect(eventUpdateList[0].eventType, "m.presence"); | ||||
|       expect(eventUpdateList[0].type, "presence"); | ||||
| 
 | ||||
|       expect(eventUpdateList[1].eventType == "org.example.custom.config", true); | ||||
|       expect(eventUpdateList[1].type == "account_data", true); | ||||
|       expect(eventUpdateList[1].eventType, "m.push_rules"); | ||||
|       expect(eventUpdateList[1].type, "account_data"); | ||||
| 
 | ||||
|       expect(eventUpdateList[2].eventType, "org.example.custom.config"); | ||||
|       expect(eventUpdateList[2].type, "account_data"); | ||||
|     }); | ||||
| 
 | ||||
|     test('Login', () async { | ||||
|  |  | |||
|  | @ -75,6 +75,173 @@ class FakeMatrixApi extends MockClient { | |||
|     }, | ||||
|     "account_data": { | ||||
|       "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", | ||||
|           "content": {"custom_config_key": "custom_config_value"} | ||||
|  |  | |||
|  | @ -335,5 +335,12 @@ void main() { | |||
|           await room.sendFileEvent(testFile, "m.file", txid: "testtxid"); | ||||
|       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