diff --git a/src/component-index.js b/src/component-index.js index d5cd6da090..a0c2433dc3 100644 --- a/src/component-index.js +++ b/src/component-index.js @@ -65,6 +65,7 @@ module.exports.components['views.messages.TextualBody'] = require('./components/ module.exports.components['views.messages.TextualEvent'] = require('./components/views/messages/TextualEvent'); module.exports.components['views.messages.UnknownBody'] = require('./components/views/messages/UnknownBody'); module.exports.components['views.room_settings.AliasSettings'] = require('./components/views/room_settings/AliasSettings'); +module.exports.components['views.room_settings.ColorSettings'] = require('./components/views/room_settings/ColorSettings'); module.exports.components['views.rooms.EntityTile'] = require('./components/views/rooms/EntityTile'); module.exports.components['views.rooms.EventTile'] = require('./components/views/rooms/EventTile'); module.exports.components['views.rooms.MemberInfo'] = require('./components/views/rooms/MemberInfo'); diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index 033fdcd8b5..e6cd16fd16 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -68,7 +68,6 @@ module.exports = React.createClass({ }, saveSettings: function() { - console.log("AliasSettings.saveSettings room=%s", this.props.roomId); var promises = []; // save new canonical alias @@ -76,8 +75,8 @@ module.exports = React.createClass({ if (this.props.canonicalAliasEvent) { oldCanonicalAlias = this.props.canonicalAliasEvent.getContent().alias; } - console.log("canon old=%s new=%s", oldCanonicalAlias, this.state.canonicalAlias); if (oldCanonicalAlias !== this.state.canonicalAlias) { + console.log("AliasSettings: Updating canonical alias"); promises.push( MatrixClientPeg.get().sendStateEvent( this.props.roomId, "m.room.canonical_alias", { diff --git a/src/components/views/room_settings/ColorSettings.js b/src/components/views/room_settings/ColorSettings.js new file mode 100644 index 0000000000..bf931b6c05 --- /dev/null +++ b/src/components/views/room_settings/ColorSettings.js @@ -0,0 +1,139 @@ +/* +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. +*/ +var q = require("q"); +var React = require('react'); + +var Tinter = require('../../../Tinter'); +var MatrixClientPeg = require("../../../MatrixClientPeg"); + +var ROOM_COLORS = [ + // magic room default values courtesy of Ribot + ["#76cfa6", "#eaf5f0"], + ["#81bddb", "#eaf1f4"], + ["#bd79cb", "#f3eaf5"], + ["#c65d94", "#f5eaef"], + ["#e55e5e", "#f5eaea"], + ["#eca46f", "#f5eeea"], + ["#dad658", "#f5f4ea"], + ["#80c553", "#eef5ea"], + ["#bb814e", "#eee8e3"], + ["#595959", "#ececec"], +]; + +module.exports = React.createClass({ + displayName: 'ColorSettings', + + propTypes: { + room: React.PropTypes.object.isRequired + }, + + getInitialState: function() { + var data = { + index: 0, + primary_color: ROOM_COLORS[0].primary_color, + secondary_color: ROOM_COLORS[0].secondary_color, + hasChanged: false + }; + var event = this.props.room.getAccountData("org.matrix.room.color_scheme"); + if (!event) { + return data; + } + var scheme = event.getContent(); + data.primary_color = scheme.primary_color; + data.secondary_color = scheme.secondary_color; + data.index = this._getColorIndex(data); + + if (data.index === -1) { + // append the unrecognised colours to our palette + data.index = ROOM_COLORS.length; + ROOM_COLORS.push([ + scheme.primary_color, scheme.secondary_color + ]); + } + return data; + }, + + saveSettings: function() { // : Promise + if (!this.state.hasChanged) { + return q(); // They didn't explicitly give a color to save. + } + var originalState = this.getInitialState(); + if (originalState.primary_color !== this.state.primary_color || + originalState.secondary_color !== this.state.secondary_color) { + console.log("ColorSettings: Saving new color"); + return MatrixClientPeg.get().setRoomAccountData( + this.props.room.roomId, "org.matrix.room.color_scheme", { + primary_color: this.state.primary_color, + secondary_color: this.state.secondary_color + } + ); + } + return q(); // no color diff + }, + + _getColorIndex: function(scheme) { + if (!scheme || !scheme.primary_color || !scheme.secondary_color) { + return -1; + } + // XXX: we should validate these values + for (var i = 0; i < ROOM_COLORS.length; i++) { + var room_color = ROOM_COLORS[i]; + if (room_color[0] === String(scheme.primary_color).toLowerCase() && + room_color[1] === String(scheme.secondary_color).toLowerCase()) { + return i; + } + } + return -1; + }, + + _onColorSchemeChanged: function(index) { + // preview what the user just changed the scheme to. + Tinter.tint(ROOM_COLORS[index][0], ROOM_COLORS[index][1]); + this.setState({ + index: index, + primary_color: ROOM_COLORS[index][0], + secondary_color: ROOM_COLORS[index][1], + hasChanged: true + }); + }, + + render: function() { + return ( +
+ {ROOM_COLORS.map((room_color, i) => { + var selected; + if (i === this.state.index) { + selected = ( +
+ ./ +
+ ); + } + var boundClick = this._onColorSchemeChanged.bind(this, i) + return ( +
+ { selected } +
+
+ ); + })} +
+ ); + } +}); diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 78e8e734a0..24246c393b 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -17,24 +17,9 @@ limitations under the License. var q = require("q"); var React = require('react'); var MatrixClientPeg = require('../../../MatrixClientPeg'); -var Tinter = require('../../../Tinter'); var sdk = require('../../../index'); var Modal = require('../../../Modal'); -var ROOM_COLORS = [ - // magic room default values courtesy of Ribot - ["#76cfa6", "#eaf5f0"], - ["#81bddb", "#eaf1f4"], - ["#bd79cb", "#f3eaf5"], - ["#c65d94", "#f5eaef"], - ["#e55e5e", "#f5eaea"], - ["#eca46f", "#f5eeea"], - ["#dad658", "#f5f4ea"], - ["#80c553", "#eef5ea"], - ["#bb814e", "#eee8e3"], - ["#595959", "#ececec"], -]; - module.exports = React.createClass({ displayName: 'RoomSettings', @@ -45,33 +30,6 @@ module.exports = React.createClass({ }, getInitialState: function() { - // work out the initial color index - var room_color_index = undefined; - var color_scheme_event = this.props.room.getAccountData("org.matrix.room.color_scheme"); - if (color_scheme_event) { - var color_scheme = color_scheme_event.getContent(); - if (color_scheme.primary_color) color_scheme.primary_color = color_scheme.primary_color.toLowerCase(); - if (color_scheme.secondary_color) color_scheme.secondary_color = color_scheme.secondary_color.toLowerCase(); - // XXX: we should validate these values - for (var i = 0; i < ROOM_COLORS.length; i++) { - var room_color = ROOM_COLORS[i]; - if (room_color[0] === color_scheme.primary_color && - room_color[1] === color_scheme.secondary_color) - { - room_color_index = i; - break; - } - } - if (room_color_index === undefined) { - // append the unrecognised colours to our palette - room_color_index = ROOM_COLORS.length; - ROOM_COLORS[room_color_index] = [ color_scheme.primary_color, color_scheme.secondary_color ]; - } - } - else { - room_color_index = 0; - } - var tags = {}; Object.keys(this.props.room.tags).forEach(function(tagName) { tags[tagName] = {}; @@ -84,7 +42,6 @@ module.exports = React.createClass({ are_notifications_muted = true; } } - return { name: this._yankValueFromEvent("m.room.name", "name"), @@ -93,8 +50,6 @@ module.exports = React.createClass({ history_visibility: this._yankValueFromEvent("m.room.history_visibility", "history_visibility"), guest_access: this._yankValueFromEvent("m.room.guest_access", "guest_access"), power_levels_changed: false, - color_scheme_changed: false, - color_scheme_index: room_color_index, tags_changed: false, tags: tags, areNotifsMuted: are_notifications_muted @@ -136,10 +91,10 @@ module.exports = React.createClass({ // diff between original state and this.state to work out what has been changed console.log("Original: %s", JSON.stringify(originalState)); console.log("New: %s", JSON.stringify(this.state)); - if (this.state.name !== originalState.name) { + if (this._hasDiff(this.state.name, originalState.name)) { promises.push(MatrixClientPeg.get().setRoomName(roomId, this.state.name)); } - if (this.state.topic !== originalState.topic) { // TODO: 0-length strings? + if (this._hasDiff(this.state.topic, originalState.topic)) { promises.push(MatrixClientPeg.get().setRoomTopic(roomId, this.state.topic)); } // TODO: @@ -149,7 +104,9 @@ module.exports = React.createClass({ // setRoomMutePushRule // power levels // tags + // color scheme + promises.push(this.saveColor()); // submit diffs @@ -157,10 +114,23 @@ module.exports = React.createClass({ }, saveAliases: function() { - if (!this.refs.alias_settings) { return q(); } + if (!this.refs.alias_settings) { return [q()]; } return this.refs.alias_settings.saveSettings(); }, + saveColor: function() { + if (!this.refs.color_settings) { return q(); } + return this.refs.color_settings.saveSettings(); + }, + + _hasDiff: function(strA, strB) { + // treat undefined as an empty string because other components may blindly + // call setName("") when there has been no diff made to the name! + strA = strA || ""; + strB = strB || ""; + return strA !== strB; + }, + resetState: function() { this.setState(this.getInitialState()); }, @@ -235,25 +205,6 @@ module.exports = React.createClass({ power_levels_changed: true }); }, - - getColorScheme: function() { - if (!this.state.color_scheme_changed) return undefined; - - return { - primary_color: ROOM_COLORS[this.state.color_scheme_index][0], - secondary_color: ROOM_COLORS[this.state.color_scheme_index][1], - }; - }, - - onColorSchemeChanged: function(index) { - // preview what the user just changed the scheme to. - Tinter.tint(ROOM_COLORS[index][0], ROOM_COLORS[index][1]); - - this.setState({ - color_scheme_changed: true, - color_scheme_index: index, - }); - }, _yankValueFromEvent: function(stateEventType, keyName, defaultValue) { // E.g.("m.room.name","name") would yank the "name" content key from "m.room.name" @@ -298,6 +249,7 @@ module.exports = React.createClass({ // (or turning them into informative stuff) var AliasSettings = sdk.getComponent("room_settings.AliasSettings"); + var ColorSettings = sdk.getComponent("room_settings.ColorSettings"); var EditableText = sdk.getComponent('elements.EditableText'); var PowerSelector = sdk.getComponent('elements.PowerSelector'); @@ -371,32 +323,6 @@ module.exports = React.createClass({ var self = this; - var room_colors_section = -
-

Room Colour

-
- {ROOM_COLORS.map(function(room_color, i) { - var selected; - if (i === self.state.color_scheme_index) { - selected = -
- ./ -
- } - var boundClick = self.onColorSchemeChanged.bind(self, i) - return ( -
- { selected } -
-
- ); - })} -
-
; - var user_levels_section; if (Object.keys(user_levels).length) { user_levels_section = @@ -508,7 +434,10 @@ module.exports = React.createClass({ - { room_colors_section } +
+

Room Colour

+ +