mirror of https://github.com/vector-im/riot-web
				
				
				
			Merge pull request #420 from matrix-org/dbkr/make_notif_silder_work
Make the notification slider workpull/21833/head
						commit
						e29be619c9
					
				|  | @ -0,0 +1,161 @@ | |||
| /* | ||||
| 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 './MatrixClientPeg'; | ||||
| import PushProcessor from 'matrix-js-sdk/lib/pushprocessor'; | ||||
| import q from 'q'; | ||||
| 
 | ||||
| export const ALL_MESSAGES_LOUD = 'all_messages_loud'; | ||||
| export const ALL_MESSAGES = 'all_messages'; | ||||
| export const MENTIONS_ONLY = 'mentions_only'; | ||||
| export const MUTE = 'mute'; | ||||
| 
 | ||||
| export function getRoomNotifsState(roomId) { | ||||
|     if (MatrixClientPeg.get().isGuest()) return RoomNotifs.ALL_MESSAGES; | ||||
| 
 | ||||
|     // look through the override rules for a rule affecting this room:
 | ||||
|     // if one exists, it will take precedence.
 | ||||
|     const muteRule = findOverrideMuteRule(roomId); | ||||
|     if (muteRule) { | ||||
|         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 || !roomRule.enabled) 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; | ||||
| } | ||||
| 
 | ||||
| export function setRoomNotifsState(roomId, newState) { | ||||
|     if (newState == MUTE) { | ||||
|         return setRoomNotifsStateMuted(roomId); | ||||
|     } else { | ||||
|         return setRoomNotifsStateUnmuted(roomId, newState); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function setRoomNotifsStateMuted(roomId) { | ||||
|     const cli = MatrixClientPeg.get(); | ||||
|     const promises = []; | ||||
| 
 | ||||
|     // delete the room rule
 | ||||
|     const roomRule = cli.getRoomPushRule('global', roomId); | ||||
|     if (roomRule) { | ||||
|         promises.push(cli.deletePushRule('global', 'room', roomRule.rule_id)); | ||||
|     } | ||||
| 
 | ||||
|     // add/replace an override rule to squelch everything in this room
 | ||||
|     // NB. We use the room ID as the name of this rule too, although this
 | ||||
|     // is an override rule, not a room rule: it still pertains to this room
 | ||||
|     // though, so using the room ID as the rule ID is logical and prevents
 | ||||
|     // duplicate copies of the rule.
 | ||||
|     promises.push(cli.addPushRule('global', 'override', roomId, { | ||||
|         conditions: [ | ||||
|             { | ||||
|                 kind: 'event_match', | ||||
|                 key: 'room_id', | ||||
|                 pattern: roomId, | ||||
|             } | ||||
|         ], | ||||
|         actions: [ | ||||
|             'dont_notify', | ||||
|         ] | ||||
|     })); | ||||
| 
 | ||||
|     return q.all(promises); | ||||
| } | ||||
| 
 | ||||
| function setRoomNotifsStateUnmuted(roomId, newState) { | ||||
|     const cli = MatrixClientPeg.get(); | ||||
|     const promises = []; | ||||
| 
 | ||||
|     const overrideMuteRule = findOverrideMuteRule(roomId); | ||||
|     if (overrideMuteRule) { | ||||
|         promises.push(cli.deletePushRule('global', 'override', overrideMuteRule.rule_id)); | ||||
|     } | ||||
| 
 | ||||
|     if (newState == 'all_messages') { | ||||
|         promises.push(cli.deletePushRule('global', 'room', roomId)); | ||||
|     } else if (newState == 'mentions_only') { | ||||
|         promises.push(cli.addPushRule('global', 'room', roomId, { | ||||
|             actions: [ | ||||
|                 'dont_notify', | ||||
|             ] | ||||
|         })); | ||||
|         // https://matrix.org/jira/browse/SPEC-400
 | ||||
|         promises.push(cli.setPushRuleEnabled('global', 'room', roomId, true)); | ||||
|     } else if ('all_messages_loud') { | ||||
|         promises.push(cli.addPushRule('global', 'room', roomId, { | ||||
|             actions: [ | ||||
|                 'notify', | ||||
|                 { | ||||
|                     set_tweak: 'sound', | ||||
|                     value: 'default', | ||||
|                 } | ||||
|             ] | ||||
|         })); | ||||
|         // https://matrix.org/jira/browse/SPEC-400
 | ||||
|         promises.push(cli.setPushRuleEnabled('global', 'room', roomId, true)); | ||||
|     } | ||||
| 
 | ||||
|     return q.all(promises); | ||||
| } | ||||
| 
 | ||||
| function findOverrideMuteRule(roomId) { | ||||
|     for (const rule of MatrixClientPeg.get().pushRules['global'].override) { | ||||
|         if (isRuleForRoom(roomId, rule)) { | ||||
|             if (isMuteRule(rule) && rule.enabled) { | ||||
|                 return rule; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     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' | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
|  | @ -47,16 +47,6 @@ module.exports = React.createClass({ | |||
|             tags[tagName] = ['yep']; | ||||
|         }); | ||||
| 
 | ||||
|         var areNotifsMuted = false; | ||||
|         if (!MatrixClientPeg.get().isGuest()) { | ||||
|             var roomPushRule = MatrixClientPeg.get().getRoomPushRule("global", this.props.room.roomId); | ||||
|             if (roomPushRule) { | ||||
|                 if (0 <= roomPushRule.actions.indexOf("dont_notify")) { | ||||
|                     areNotifsMuted = true; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return { | ||||
|             name: this._yankValueFromEvent("m.room.name", "name"), | ||||
|             topic: this._yankValueFromEvent("m.room.topic", "topic"), | ||||
|  | @ -66,7 +56,6 @@ module.exports = React.createClass({ | |||
|             power_levels_changed: false, | ||||
|             tags_changed: false, | ||||
|             tags: tags, | ||||
|             areNotifsMuted: areNotifsMuted, | ||||
|             // isRoomPublished is loaded async in componentWillMount so when the component
 | ||||
|             // inits, the saved value will always be undefined, however getInitialState()
 | ||||
|             // is also called from the saving code so we must return the correct value here
 | ||||
|  | @ -188,12 +177,6 @@ module.exports = React.createClass({ | |||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         if (this.state.areNotifsMuted !== originalState.areNotifsMuted) { | ||||
|             promises.push(MatrixClientPeg.get().setRoomMutePushRule( | ||||
|                 "global", roomId, this.state.areNotifsMuted | ||||
|             )); | ||||
|         } | ||||
| 
 | ||||
|         // power levels
 | ||||
|         var powerLevels = this._getPowerLevels(); | ||||
|         if (powerLevels) { | ||||
|  | @ -647,12 +630,6 @@ module.exports = React.createClass({ | |||
|                 { tagsSection } | ||||
| 
 | ||||
|                 <div className="mx_RoomSettings_toggles"> | ||||
|                     <label> | ||||
|                         <input type="checkbox" disabled={ cli.isGuest() } | ||||
|                                onChange={this._onToggle.bind(this, "areNotifsMuted", true, false)} | ||||
|                                defaultChecked={this.state.areNotifsMuted}/> | ||||
|                         'Mention only' notifications for this room | ||||
|                     </label> | ||||
|                     <div className="mx_RoomSettings_settings"> | ||||
|                         <h3>Who can access this room?</h3> | ||||
|                         { inviteGuestWarning } | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ var dis = require("../../../dispatcher"); | |||
| var MatrixClientPeg = require('../../../MatrixClientPeg'); | ||||
| var sdk = require('../../../index'); | ||||
| var ContextualMenu = require('../../structures/ContextualMenu'); | ||||
| var RoomNotifs = require('../../../RoomNotifs'); | ||||
| 
 | ||||
| module.exports = React.createClass({ | ||||
|     displayName: 'RoomTile', | ||||
|  | @ -43,43 +44,41 @@ module.exports = React.createClass({ | |||
|     }, | ||||
| 
 | ||||
|     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({ | ||||
|             hover : false, | ||||
|             badgeHover : false, | ||||
|             notificationTagMenu: false, | ||||
|             roomTagMenu: false, | ||||
|             areNotifsMuted: areNotifsMuted, | ||||
|             notifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId), | ||||
|         }); | ||||
|     }, | ||||
| 
 | ||||
|     onAction: function(payload) { | ||||
|         switch (payload.action) { | ||||
|             case 'notification_change': | ||||
|                 // Is the notification about this room?
 | ||||
|                 if (payload.roomId === this.props.room.roomId) { | ||||
|                     this.setState( { areNotifsMuted : payload.areNotifsMuted }); | ||||
|                 } | ||||
|                 break; | ||||
|     _shouldShowNotifBadge: function() { | ||||
|         const showBadgeInStates = [RoomNotifs.ALL_MESSAGES, RoomNotifs.ALL_MESSAGES_LOUD]; | ||||
|         return showBadgeInStates.indexOf(this.state.notifState) > -1; | ||||
|     }, | ||||
| 
 | ||||
|     _shouldShowMentionBadge: function() { | ||||
|         return this.state.notifState != RoomNotifs.MUTE; | ||||
|     }, | ||||
| 
 | ||||
|     onAccountData: function(accountDataEvent) { | ||||
|         if (accountDataEvent.getType() == 'm.push_rules') { | ||||
|             this.setState({ | ||||
|                 notifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId), | ||||
|             }); | ||||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     componentDidMount: function() { | ||||
|         this.dispatcherRef = dis.register(this.onAction); | ||||
|     componentWillMount: function() { | ||||
|         MatrixClientPeg.get().on("accountData", this.onAccountData); | ||||
|     }, | ||||
| 
 | ||||
|     componentWillUnmount: function() { | ||||
|         dis.unregister(this.dispatcherRef); | ||||
|         var cli = MatrixClientPeg.get(); | ||||
|         if (cli) { | ||||
|             MatrixClientPeg.get().removeListener("accountData", this.onAccountData); | ||||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     onClick: function() { | ||||
|  | @ -179,15 +178,19 @@ module.exports = React.createClass({ | |||
|         var notificationCount = this.props.room.getUnreadNotificationCount(); | ||||
|         // var highlightCount = this.props.room.getUnreadNotificationCount("highlight");
 | ||||
| 
 | ||||
|         const notifBadges = notificationCount > 0 && this._shouldShowNotifBadge(); | ||||
|         const mentionBadges = this.props.highlight && this._shouldShowMentionBadge(); | ||||
|         const badges = notifBadges || mentionBadges; | ||||
| 
 | ||||
|         var classes = classNames({ | ||||
|             'mx_RoomTile': true, | ||||
|             'mx_RoomTile_selected': this.props.selected, | ||||
|             'mx_RoomTile_unread': this.props.unread, | ||||
|             'mx_RoomTile_unreadNotify': notificationCount > 0 && !this.state.areNotifsMuted, | ||||
|             'mx_RoomTile_highlight': this.props.highlight, | ||||
|             'mx_RoomTile_unreadNotify': notifBadges, | ||||
|             'mx_RoomTile_highlight': mentionBadges, | ||||
|             'mx_RoomTile_invited': (me && me.membership == 'invite'), | ||||
|             'mx_RoomTile_notificationTagMenu': this.state.notificationTagMenu, | ||||
|             'mx_RoomTile_noBadges': !(this.props.highlight || (notificationCount > 0 && !this.state.areNotifsMuted)) | ||||
|             'mx_RoomTile_noBadges': !badges, | ||||
|         }); | ||||
| 
 | ||||
|         var avatarClasses = classNames({ | ||||
|  | @ -214,7 +217,7 @@ module.exports = React.createClass({ | |||
| 
 | ||||
|         if (this.state.badgeHover || this.state.notificationTagMenu) { | ||||
|             badgeContent = "\u00B7\u00B7\u00B7"; | ||||
|         } else if (this.props.highlight || (notificationCount > 0 && !this.state.areNotifsMuted)) { | ||||
|         } else if (badges) { | ||||
|             var limitedCount = (notificationCount > 99) ? '99+' : notificationCount; | ||||
|             badgeContent = notificationCount ? limitedCount : '!'; | ||||
|         } else { | ||||
|  | @ -230,7 +233,7 @@ module.exports = React.createClass({ | |||
|             var nameClasses = classNames({ | ||||
|                 'mx_RoomTile_name': true, | ||||
|                 'mx_RoomTile_invite': this.props.isInvite, | ||||
|                 'mx_RoomTile_badgeShown': this.props.highlight || (notificationCount > 0 && !this.state.areNotifsMuted) || this.state.badgeHover || this.state.notificationTagMenu, | ||||
|                 'mx_RoomTile_badgeShown': badges || this.state.badgeHover || this.state.notificationTagMenu, | ||||
|             }); | ||||
| 
 | ||||
|             if (this.props.selected) { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Richard van der Hoff
						Richard van der Hoff