From 953e13831799d9827e67dea70e71a40abe35df49 Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 11 Jan 2016 17:05:27 +0100 Subject: [PATCH 1/3] Settings page: Made the push notifications settings a separate component. This component is currently implemented at the app level --- src/components/structures/UserSettings.js | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index ddf4229170..9196782070 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -145,10 +145,6 @@ module.exports = React.createClass({ this.logoutModal.closeDialog(); }, - onEnableNotificationsChange: function(event) { - UserSettingsStore.setEnableNotifications(event.target.checked); - }, - render: function() { switch (this.state.phase) { case "UserSettings.LOADING": @@ -166,6 +162,7 @@ module.exports = React.createClass({ var ChangeDisplayName = sdk.getComponent("views.settings.ChangeDisplayName"); var ChangePassword = sdk.getComponent("views.settings.ChangePassword"); var ChangeAvatar = sdk.getComponent('settings.ChangeAvatar'); + var Notifications = sdk.getComponent("settings.Notifications"); var avatarUrl = ( this.state.avatarUrl ? MatrixClientPeg.get().mxcUrlToHttp(this.state.avatarUrl) : null ); @@ -253,22 +250,7 @@ module.exports = React.createClass({

Notifications

-
-
-
- -
-
- -
-
-
+

Advanced

From 79854138932b511e4f5f59449053669f9f91b59c Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 13 Jan 2016 16:32:41 +0100 Subject: [PATCH 2/3] Created TextInputDialog In css, created a generic mx_Dialog_title class for all dialogs --- src/component-index.js | 9 +- src/components/views/dialogs/ErrorDialog.js | 2 +- .../views/dialogs/QuestionDialog.js | 2 +- .../views/dialogs/TextInputDialog.js | 94 +++++++++++++++++++ .../views/login/CustomServerDialog.js | 2 +- 5 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 src/components/views/dialogs/TextInputDialog.js diff --git a/src/component-index.js b/src/component-index.js index 0c08d70b73..bfe1beca71 100644 --- a/src/component-index.js +++ b/src/component-index.js @@ -23,14 +23,14 @@ limitations under the License. module.exports.components = {}; module.exports.components['structures.CreateRoom'] = require('./components/structures/CreateRoom'); +module.exports.components['structures.login.Login'] = require('./components/structures/login/Login'); +module.exports.components['structures.login.PostRegistration'] = require('./components/structures/login/PostRegistration'); +module.exports.components['structures.login.Registration'] = require('./components/structures/login/Registration'); module.exports.components['structures.MatrixChat'] = require('./components/structures/MatrixChat'); module.exports.components['structures.RoomView'] = require('./components/structures/RoomView'); module.exports.components['structures.ScrollPanel'] = require('./components/structures/ScrollPanel'); module.exports.components['structures.UploadBar'] = require('./components/structures/UploadBar'); module.exports.components['structures.UserSettings'] = require('./components/structures/UserSettings'); -module.exports.components['structures.login.Login'] = require('./components/structures/login/Login'); -module.exports.components['structures.login.PostRegistration'] = require('./components/structures/login/PostRegistration'); -module.exports.components['structures.login.Registration'] = require('./components/structures/login/Registration'); module.exports.components['views.avatars.MemberAvatar'] = require('./components/views/avatars/MemberAvatar'); module.exports.components['views.avatars.RoomAvatar'] = require('./components/views/avatars/RoomAvatar'); module.exports.components['views.create_room.CreateRoomButton'] = require('./components/views/create_room/CreateRoomButton'); @@ -39,6 +39,7 @@ module.exports.components['views.create_room.RoomAlias'] = require('./components module.exports.components['views.dialogs.ErrorDialog'] = require('./components/views/dialogs/ErrorDialog'); module.exports.components['views.dialogs.LogoutPrompt'] = require('./components/views/dialogs/LogoutPrompt'); module.exports.components['views.dialogs.QuestionDialog'] = require('./components/views/dialogs/QuestionDialog'); +module.exports.components['views.dialogs.TextInputDialog'] = require('./components/views/dialogs/TextInputDialog'); module.exports.components['views.elements.EditableText'] = require('./components/views/elements/EditableText'); module.exports.components['views.elements.ProgressBar'] = require('./components/views/elements/ProgressBar'); module.exports.components['views.elements.TintableSvg'] = require('./components/views/elements/TintableSvg'); @@ -51,10 +52,10 @@ module.exports.components['views.login.LoginHeader'] = require('./components/vie module.exports.components['views.login.PasswordLogin'] = require('./components/views/login/PasswordLogin'); module.exports.components['views.login.RegistrationForm'] = require('./components/views/login/RegistrationForm'); module.exports.components['views.login.ServerConfig'] = require('./components/views/login/ServerConfig'); +module.exports.components['views.messages.MessageEvent'] = require('./components/views/messages/MessageEvent'); module.exports.components['views.messages.MFileBody'] = require('./components/views/messages/MFileBody'); module.exports.components['views.messages.MImageBody'] = require('./components/views/messages/MImageBody'); module.exports.components['views.messages.MVideoBody'] = require('./components/views/messages/MVideoBody'); -module.exports.components['views.messages.MessageEvent'] = require('./components/views/messages/MessageEvent'); module.exports.components['views.messages.TextualBody'] = require('./components/views/messages/TextualBody'); module.exports.components['views.messages.TextualEvent'] = require('./components/views/messages/TextualEvent'); module.exports.components['views.messages.UnknownBody'] = require('./components/views/messages/UnknownBody'); diff --git a/src/components/views/dialogs/ErrorDialog.js b/src/components/views/dialogs/ErrorDialog.js index ed9364df60..d06cf2de84 100644 --- a/src/components/views/dialogs/ErrorDialog.js +++ b/src/components/views/dialogs/ErrorDialog.js @@ -48,7 +48,7 @@ module.exports = React.createClass({ render: function() { return (
-
+
{this.props.title}
diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js index f415201e45..4eeecd64b3 100644 --- a/src/components/views/dialogs/QuestionDialog.js +++ b/src/components/views/dialogs/QuestionDialog.js @@ -46,7 +46,7 @@ module.exports = React.createClass({ render: function() { return (
-
+
{this.props.title}
diff --git a/src/components/views/dialogs/TextInputDialog.js b/src/components/views/dialogs/TextInputDialog.js new file mode 100644 index 0000000000..3cda852449 --- /dev/null +++ b/src/components/views/dialogs/TextInputDialog.js @@ -0,0 +1,94 @@ +/* +Copyright 2015, 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. +*/ + +var React = require("react"); + +module.exports = React.createClass({ + displayName: 'TextInputDialog', + propTypes: { + title: React.PropTypes.string, + description: React.PropTypes.string, + value: React.PropTypes.string, + button: React.PropTypes.string, + focus: React.PropTypes.bool, + onFinished: React.PropTypes.func.isRequired + }, + + getDefaultProps: function() { + return { + title: "", + value: "", + description: "", + button: "OK", + focus: true + }; + }, + + componentDidMount: function() { + if (this.props.focus) { + // Set the cursor at the end of the text input + this.refs.textinput.value = this.props.value; + } + }, + + onOk: function() { + this.props.onFinished(true, this.refs.textinput.value); + }, + + onCancel: function() { + this.props.onFinished(false); + }, + + onKeyDown: function(e) { + if (e.keyCode === 27) { // escape + e.stopPropagation(); + e.preventDefault(); + this.props.onFinished(false); + } + else if (e.keyCode === 13) { // enter + e.stopPropagation(); + e.preventDefault(); + this.props.onFinished(true, this.refs.textinput.value); + } + }, + + render: function() { + return ( +
+
+ {this.props.title} +
+
+
+ +
+
+ +
+
+
+ + + +
+
+ ); + } +}); diff --git a/src/components/views/login/CustomServerDialog.js b/src/components/views/login/CustomServerDialog.js index 8a67dfd7e6..dc6a49abd6 100644 --- a/src/components/views/login/CustomServerDialog.js +++ b/src/components/views/login/CustomServerDialog.js @@ -22,7 +22,7 @@ module.exports = React.createClass({ render: function() { return (
-
+
Custom Server Options
From f868f7813b031969ec42ab832fd86cf697d682de Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 14 Jan 2016 19:06:48 +0100 Subject: [PATCH 3/3] Room settings: Added notifications mute checkbox --- src/components/structures/RoomView.js | 8 ++++++++ src/components/views/rooms/RoomSettings.js | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index c622a7d769..25d95fdc41 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -804,6 +804,13 @@ module.exports = React.createClass({ ); } + // setRoomMutePushRule will do nothing if there is no change + deferreds.push( + MatrixClientPeg.get().setRoomMutePushRule( + "global", this.state.room.roomId, newVals.are_notifications_muted + ) + ); + if (newVals.power_levels) { deferreds.push( MatrixClientPeg.get().sendStateEvent( @@ -908,6 +915,7 @@ module.exports = React.createClass({ topic: this.refs.room_settings.getTopic(), join_rule: this.refs.room_settings.getJoinRules(), history_visibility: this.refs.room_settings.getHistoryVisibility(), + are_notifications_muted: this.refs.room_settings.areNotificationsMuted(), power_levels: this.refs.room_settings.getPowerLevels(), guest_join: this.refs.room_settings.canGuestsJoin(), guest_read: this.refs.room_settings.canGuestsRead() diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 9e07385d65..e402ac8488 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -51,6 +51,10 @@ module.exports = React.createClass({ return this.refs.share_history.checked ? "shared" : "invited"; }, + areNotificationsMuted: function() { + return this.refs.are_notifications_muted.checked; + }, + getPowerLevels: function() { if (!this.state.power_levels_changed) return undefined; @@ -96,6 +100,14 @@ module.exports = React.createClass({ guest_access = guest_access.getContent().guest_access; } + var are_notifications_muted; + var roomPushRule = MatrixClientPeg.get().getRoomPushRule("global", this.props.room.roomId); + if (roomPushRule) { + if (0 <= roomPushRule.actions.indexOf("dont_notify")) { + are_notifications_muted = true; + } + } + var events_levels = power_levels.events || {}; if (power_levels) { @@ -176,6 +188,11 @@ module.exports = React.createClass({

+

Notifications

+
+ +
+

Power levels