From a17df609f32b44834cbd0e4bccc3a977182bf013 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Fri, 12 Aug 2016 15:19:34 +0100
Subject: [PATCH] Read all 4 different notif states

Can't yet set loud / mute
---
 .../NotificationStateContextMenu.js           | 28 ++------
 src/notifications/RoomNotifs.js               | 70 +++++++++++++++++++
 2 files changed, 76 insertions(+), 22 deletions(-)
 create mode 100644 src/notifications/RoomNotifs.js

diff --git a/src/components/views/context_menus/NotificationStateContextMenu.js b/src/components/views/context_menus/NotificationStateContextMenu.js
index 8430f8efc4..21b17fe668 100644
--- a/src/components/views/context_menus/NotificationStateContextMenu.js
+++ b/src/components/views/context_menus/NotificationStateContextMenu.js
@@ -21,6 +21,7 @@ var React = require('react');
 var classNames = require('classnames');
 var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var dis = require('matrix-react-sdk/lib/dispatcher');
+var RoomNotifs = require('../../../notifications/RoomNotifs');
 
 module.exports = React.createClass({
     displayName: 'NotificationStateContextMenu',
@@ -31,23 +32,6 @@ module.exports = React.createClass({
         onFinished: React.PropTypes.func,
     },
 
-    getInitialState: function() {
-        var areNotifsMuted = false;
-        var cli = MatrixClientPeg.get();
-        if (!cli.isGuest()) {
-            var roomPushRule = cli.getRoomPushRule("global", this.props.room.roomId);
-            if (roomPushRule) {
-                if (0 <= roomPushRule.actions.indexOf("dont_notify")) {
-                    areNotifsMuted = true;
-                }
-            }
-        }
-
-        return {
-            areNotifsMuted: areNotifsMuted,
-        };
-    },
-
     _save: function( areNotifsMuted ) {
         var self = this;
         const roomId = this.props.room.roomId;
@@ -100,26 +84,26 @@ module.exports = React.createClass({
     },
 
     render: function() {
-        var cli = MatrixClientPeg.get();
+        const vectorRoomNotifState = RoomNotifs.getVectorRoomNotifsState(this.props.room.roomId);
 
         var alertMeClasses = classNames({
             'mx_NotificationStateContextMenu_field': true,
-            'mx_NotificationStateContextMenu_fieldDisabled': true,
+            'mx_NotificationStateContextMenu_fieldSet': vectorRoomNotifState == 'all_messages_loud',
         });
 
         var allNotifsClasses = classNames({
             'mx_NotificationStateContextMenu_field': true,
-            'mx_NotificationStateContextMenu_fieldSet': !this.state.areNotifsMuted,
+            'mx_NotificationStateContextMenu_fieldSet': vectorRoomNotifState == 'all_messages',
         });
 
         var mentionsClasses = classNames({
             'mx_NotificationStateContextMenu_field': true,
-            'mx_NotificationStateContextMenu_fieldSet': this.state.areNotifsMuted,
+            'mx_NotificationStateContextMenu_fieldSet': vectorRoomNotifState == 'mentions_only',
         });
 
         var muteNotifsClasses = classNames({
             'mx_NotificationStateContextMenu_field': true,
-            'mx_NotificationStateContextMenu_fieldDisabled': true,
+            'mx_NotificationStateContextMenu_fieldDisabled': vectorRoomNotifState == 'mute',
         });
 
         return (
diff --git a/src/notifications/RoomNotifs.js b/src/notifications/RoomNotifs.js
new file mode 100644
index 0000000000..35b1f1252e
--- /dev/null
+++ b/src/notifications/RoomNotifs.js
@@ -0,0 +1,70 @@
+/*
+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.
+*/
+
+import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
+import PushProcessor from 'matrix-js-sdk/lib/pushprocessor';
+
+export function getVectorRoomNotifsState(roomId) {
+    // look through the override rules for a rule affecting this room:
+    // if one exists, it will take precedence.
+    for (const rule of MatrixClientPeg.get().pushRules['global'].override) {
+        if (isRuleForRoom(roomId, rule)) {
+            if (isMuteRule(rule)) {
+                return 'mute';
+            }
+        }
+    }
+
+    // for everything else, look at the room rule.
+    const roomRule = MatrixClientPeg.get().getRoomPushRule('global', roomId);
+
+    // XXX: We have to assume the default is to notify for all messages
+    // (in particular this will be 'wrong' for one to one rooms because
+    // they will notify loudly for all messages)
+    if (!roomRule) return 'all_messages';
+
+    // a mute at the room level will still allow mentions
+    // to notify
+    if (isMuteRule(roomRule)) return 'mentions_only';
+
+    const actionsObject = PushProcessor.actionListToActionsObject(roomRule.actions);
+    if (actionsObject.tweaks.sound) return 'all_messages_loud';
+
+    return null;
+}
+
+function isRuleForRoom(roomId, rule) {
+    if (rule.conditions.length !== 1) {
+        return false;
+    }
+    const cond = rule.conditions[0];
+    if (
+        cond.kind == 'event_match'  &&
+        cond.key == 'room_id' &&
+        cond.pattern == roomId
+    ) {
+        return true;
+    }
+    return false;
+}
+
+function isMuteRule(rule) {
+    return (
+        rule.actions.length == 1 &&
+        rule.actions[0] == 'dont_notify'
+    );
+}
+