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/structures/RoomView.js b/src/components/structures/RoomView.js
index 425852f07f..eb38cba953 100644
--- a/src/components/structures/RoomView.js
+++ b/src/components/structures/RoomView.js
@@ -1116,195 +1116,6 @@ module.exports = React.createClass({
return ret;
},
- uploadNewState: function(newVals) {
- var old_name = this.state.room.name;
-
- var old_topic = this.state.room.currentState.getStateEvents('m.room.topic', '');
- if (old_topic) {
- old_topic = old_topic.getContent().topic;
- } else {
- old_topic = "";
- }
-
- var old_join_rule = this.state.room.currentState.getStateEvents('m.room.join_rules', '');
- if (old_join_rule) {
- old_join_rule = old_join_rule.getContent().join_rule;
- } else {
- old_join_rule = "invite";
- }
-
- var old_history_visibility = this.state.room.currentState.getStateEvents('m.room.history_visibility', '');
- if (old_history_visibility) {
- old_history_visibility = old_history_visibility.getContent().history_visibility;
- } else {
- old_history_visibility = "shared";
- }
-
- var old_guest_read = (old_history_visibility === "world_readable");
-
- var old_guest_join = this.state.room.currentState.getStateEvents('m.room.guest_access', '');
- if (old_guest_join) {
- old_guest_join = (old_guest_join.getContent().guest_access === "can_join");
- }
- else {
- old_guest_join = false;
- }
-
- var deferreds = [];
-
- if (old_name != newVals.name && newVals.name != undefined) {
- deferreds.push(
- MatrixClientPeg.get().setRoomName(this.state.room.roomId, newVals.name)
- );
- }
-
- if (old_topic != newVals.topic && newVals.topic != undefined) {
- deferreds.push(
- MatrixClientPeg.get().setRoomTopic(this.state.room.roomId, newVals.topic)
- );
- }
-
- if (old_join_rule != newVals.join_rule && newVals.join_rule != undefined) {
- deferreds.push(
- MatrixClientPeg.get().sendStateEvent(
- this.state.room.roomId, "m.room.join_rules", {
- join_rule: newVals.join_rule,
- }, ""
- )
- );
- }
-
- // XXX: EVIL HACK: for now, don't let Vector clobber 'joined' visibility to 'invited'
- // just because it doesn't know about 'joined' yet. In future we should fix it
- // properly - https://github.com/vector-im/vector-web/issues/731
- if (old_history_visibility === "joined") {
- old_history_visibility = "invited";
- }
-
- var visibilityDeferred;
- if (old_history_visibility != newVals.history_visibility &&
- newVals.history_visibility != undefined) {
- visibilityDeferred =
- MatrixClientPeg.get().sendStateEvent(
- this.state.room.roomId, "m.room.history_visibility", {
- history_visibility: newVals.history_visibility,
- }, ""
- );
- }
-
- if (old_guest_read != newVals.guest_read ||
- old_guest_join != newVals.guest_join)
- {
- var guestDeferred =
- MatrixClientPeg.get().setGuestAccess(this.state.room.roomId, {
- allowRead: newVals.guest_read,
- allowJoin: newVals.guest_join
- });
-
- if (visibilityDeferred) {
- visibilityDeferred = visibilityDeferred.then(guestDeferred);
- }
- else {
- visibilityDeferred = guestDeferred;
- }
- }
-
- if (visibilityDeferred) {
- deferreds.push(visibilityDeferred);
- }
-
- // 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(
- this.state.room.roomId, "m.room.power_levels", newVals.power_levels, ""
- )
- );
- }
-
- if (newVals.tag_operations) {
- var oplist = [];
- for (var i = 0; i < newVals.tag_operations.length; i++) {
- var tag_operation = newVals.tag_operations[i];
- switch (tag_operation.type) {
- case 'put':
- oplist.push(
- MatrixClientPeg.get().setRoomTag(
- this.props.roomId, tag_operation.tag, {}
- )
- );
- break;
- case 'delete':
- oplist.push(
- MatrixClientPeg.get().deleteRoomTag(
- this.props.roomId, tag_operation.tag
- )
- );
- break;
- default:
- console.log("Unknown tag operation, ignoring: " + tag_operation.type);
- }
- }
-
- if (oplist.length) {
- var deferred = oplist[0];
- oplist.splice(1).forEach(function (f) {
- deferred = deferred.then(f);
- });
- deferreds.push(deferred);
- }
- }
-
- if (newVals.color_scheme) {
- deferreds.push(
- MatrixClientPeg.get().setRoomAccountData(
- this.state.room.roomId, "org.matrix.room.color_scheme", newVals.color_scheme
- )
- );
- }
-
- deferreds.push(this.refs.room_settings.saveAliases());
-
- if (deferreds.length) {
- var self = this;
- q.allSettled(deferreds).then(
- function(results) {
- var fails = results.filter(function(result) { return result.state !== "fulfilled" });
- if (fails.length) {
- fails.forEach(function(result) {
- console.error(result.reason);
- });
- var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
- Modal.createDialog(ErrorDialog, {
- title: "Failed to set state",
- description: fails.map(function(result) { return result.reason }).join("\n"),
- });
- self.refs.room_settings.resetState();
- }
- else {
- self.setState({
- editingRoomSettings: false
- });
- }
- }).finally(function() {
- self.setState({
- uploadingRoomSettings: false,
- });
- });
- } else {
- this.setState({
- editingRoomSettings: false,
- uploadingRoomSettings: false,
- });
- }
- },
-
_collectEventNode: function(eventId, node) {
if (this.eventNodes == undefined) this.eventNodes = {};
this.eventNodes[eventId] = node;
@@ -1409,23 +1220,39 @@ module.exports = React.createClass({
this.showSettings(true);
},
- onSaveClick: function() {
+ onSettingsSaveClick: function() {
this.setState({
uploadingRoomSettings: true,
});
-
- this.uploadNewState({
- name: this.refs.header.getRoomName(),
- topic: this.refs.header.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(),
- tag_operations: this.refs.room_settings.getTagOperations(),
- guest_join: this.refs.room_settings.canGuestsJoin(),
- guest_read: this.refs.room_settings.canGuestsRead(),
- color_scheme: this.refs.room_settings.getColorScheme(),
- });
+
+ this.refs.room_settings.setName(this.refs.header.getRoomName());
+ this.refs.room_settings.setTopic(this.refs.header.getTopic());
+
+ this.refs.room_settings.save().then((results) => {
+ var fails = results.filter(function(result) { return result.state !== "fulfilled" });
+ console.log("Settings saved with %s errors", fails.length);
+ if (fails.length) {
+ fails.forEach(function(result) {
+ console.error(result.reason);
+ });
+ var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
+ Modal.createDialog(ErrorDialog, {
+ title: "Failed to save settings",
+ description: fails.map(function(result) { return result.reason }).join("\n"),
+ });
+ // still editing room settings
+ }
+ else {
+ this.setState({
+ editingRoomSettings: false
+ });
+ }
+ }).finally(() => {
+ this.setState({
+ uploadingRoomSettings: false,
+ editingRoomSettings: false
+ });
+ }).done();
},
onCancelClick: function() {
@@ -1828,7 +1655,7 @@ module.exports = React.createClass({
var aux = null;
if (this.state.editingRoomSettings) {
- aux = ;
+ aux = ;
}
else if (this.state.uploadingRoomSettings) {
aux = ;
@@ -1997,7 +1824,7 @@ module.exports = React.createClass({
editing={this.state.editingRoomSettings}
onSearchClick={this.onSearchClick}
onSettingsClick={this.onSettingsClick}
- onSaveClick={this.onSaveClick}
+ onSaveClick={this.onSettingsSaveClick}
onCancelClick={this.onCancelClick}
onForgetClick={
(myMember && myMember.membership === "leave") ? this.onForgetClick : null
diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js
index 0dd00852fa..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", {
@@ -114,7 +113,7 @@ module.exports = React.createClass({
}
}
- return q.allSettled(promises);
+ return promises;
},
aliasEventsToDictionary: function(aliasEvents) { // m.room.alias events
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 (
+
+ );
+ })}
+
+ );
+ }
+});
diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js
index b716b2e9df..10af37ebf0 100644
--- a/src/components/views/rooms/RoomSettings.js
+++ b/src/components/views/rooms/RoomSettings.js
@@ -17,23 +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"],
-];
+var ObjectUtils = require("../../../ObjectUtils");
module.exports = React.createClass({
displayName: 'RoomSettings',
@@ -45,87 +31,171 @@ 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] = {};
});
+ var areNotifsMuted = false;
+ 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"),
+ join_rule: this._yankValueFromEvent("m.room.join_rules", "join_rule"),
+ 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: areNotifsMuted
};
},
+
+ setName: function(name) {
+ this.setState({
+ name: name
+ });
+ },
+
+ setTopic: function(topic) {
+ this.setState({
+ topic: topic
+ });
+ },
+
+ save: function() {
+ var stateWasSetDefer = q.defer();
+ // the caller may have JUST called setState on stuff, so we need to re-render before saving
+ // else we won't use the latest values of things.
+ // We can be a bit cheeky here and set a loading flag, and listen for the callback on that
+ // to know when things have been set.
+ this.setState({ _loading: true}, () => {
+ stateWasSetDefer.resolve();
+ this.setState({ _loading: false});
+ });
+
+ return stateWasSetDefer.promise.then(() => {
+ return this._save();
+ });
+ },
+
+ _save: function() {
+ const roomId = this.props.room.roomId;
+ var promises = this.saveAliases(); // returns Promise[]
+ var originalState = this.getInitialState();
+
+ // 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));
+
+ // name and topic
+ if (this._hasDiff(this.state.name, originalState.name)) {
+ promises.push(MatrixClientPeg.get().setRoomName(roomId, this.state.name));
+ }
+ if (this._hasDiff(this.state.topic, originalState.topic)) {
+ promises.push(MatrixClientPeg.get().setRoomTopic(roomId, this.state.topic));
+ }
+
+ if (this.state.history_visibility !== originalState.history_visibility) {
+ promises.push(MatrixClientPeg.get().sendStateEvent(
+ roomId, "m.room.history_visibility",
+ { history_visibility: this.state.history_visibility },
+ ""
+ ));
+ }
+
+ if (this.state.join_rule !== originalState.join_rule) {
+ promises.push(MatrixClientPeg.get().sendStateEvent(
+ roomId, "m.room.join_rules",
+ { join_rule: this.state.join_rule },
+ ""
+ ));
+ }
+
+ if (this.state.guest_access !== originalState.guest_access) {
+ promises.push(MatrixClientPeg.get().sendStateEvent(
+ roomId, "m.room.guest_access",
+ { guest_access: this.state.guest_access },
+ ""
+ ));
+ }
+
+
+ if (this.state.areNotifsMuted !== originalState.areNotifsMuted) {
+ promises.push(MatrixClientPeg.get().setRoomMutePushRule(
+ "global", roomId, this.state.areNotifsMuted
+ ));
+ }
+
+ // power levels
+ var powerLevels = this._getPowerLevels();
+ if (powerLevels) {
+ promises.push(MatrixClientPeg.get().sendStateEvent(
+ roomId, "m.room.power_levels", powerLevels, ""
+ ));
+ }
+
+ // tags
+ if (this.state.tags_changed) {
+ var tagDiffs = ObjectUtils.getKeyValueArrayDiffs(originalState.tags, this.state.tags);
+ // [ {place: add, key: "m.favourite", val: "yep"} ]
+ tagDiffs.forEach(function(diff) {
+ switch (diff.place) {
+ case "add":
+ promises.push(
+ MatrixClientPeg.get().setRoomTag(roomId, diff.key, {})
+ );
+ break;
+ case "del":
+ promises.push(
+ MatrixClientPeg.get().deleteRoomTag(roomId, diff.key)
+ );
+ break;
+ default:
+ console.error("Unknown tag operation: %s", diff.place);
+ break;
+ }
+ });
+ }
+ console.log("Performing %s operations", promises.length);
+
+ // color scheme
+ promises.push(this.saveColor());
+
+ return q.allSettled(promises);
+ },
saveAliases: function() {
- if (!this.refs.alias_settings) { return q(); }
+ if (!this.refs.alias_settings) { return [q()]; }
return this.refs.alias_settings.saveSettings();
},
- resetState: function() {
- this.setState(this.getInitialState());
+ saveColor: function() {
+ if (!this.refs.color_settings) { return q(); }
+ return this.refs.color_settings.saveSettings();
},
- canGuestsJoin: function() {
- return this.refs.guests_join.checked;
+ _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;
},
- canGuestsRead: function() {
- return this.refs.guests_read.checked;
- },
-
- getTopic: function() {
- return this.refs.topic ? this.refs.topic.value : "";
- },
-
- getJoinRules: function() {
- return this.refs.is_private.checked ? "invite" : "public";
- },
-
- getHistoryVisibility: function() {
- return this.refs.share_history.checked ? "shared" : "invited";
- },
-
- areNotificationsMuted: function() {
- return this.refs.are_notifications_muted.checked;
- },
-
- getPowerLevels: function() {
+ _getPowerLevels: function() {
if (!this.state.power_levels_changed) return undefined;
- var power_levels = this.props.room.currentState.getStateEvents('m.room.power_levels', '');
- power_levels = power_levels.getContent();
+ var powerLevels = this.props.room.currentState.getStateEvents('m.room.power_levels', '');
+ powerLevels = powerLevels ? powerLevels.getContent() : {};
- var new_power_levels = {
+ var newPowerLevels = {
ban: parseInt(this.refs.ban.getValue()),
kick: parseInt(this.refs.kick.getValue()),
redact: parseInt(this.refs.redact.getValue()),
@@ -133,39 +203,11 @@ module.exports = React.createClass({
events_default: parseInt(this.refs.events_default.getValue()),
state_default: parseInt(this.refs.state_default.getValue()),
users_default: parseInt(this.refs.users_default.getValue()),
- users: power_levels.users,
- events: power_levels.events,
+ users: powerLevels.users,
+ events: powerLevels.events,
};
- return new_power_levels;
- },
-
- getTagOperations: function() {
- if (!this.state.tags_changed) return undefined;
-
- var ops = [];
-
- var delta = {};
- Object.keys(this.props.room.tags).forEach(function(oldTag) {
- delta[oldTag] = delta[oldTag] || 0;
- delta[oldTag]--;
- });
- Object.keys(this.state.tags).forEach(function(newTag) {
- delta[newTag] = delta[newTag] || 0;
- delta[newTag]++;
- });
- Object.keys(delta).forEach(function(tag) {
- if (delta[tag] == 1) {
- ops.push({ type: "put", tag: tag });
- } else if (delta[tag] == -1) {
- ops.push({ type: "delete", tag: tag });
- } else {
- console.error("Calculated tag delta of " + delta[tag] +
- " - this should never happen!");
- }
- });
-
- return ops;
+ return newPowerLevels;
},
onPowerLevelsChanged: function() {
@@ -173,27 +215,30 @@ 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],
- };
+
+ _yankValueFromEvent: function(stateEventType, keyName, defaultValue) {
+ // E.g.("m.room.name","name") would yank the "name" content key from "m.room.name"
+ var event = this.props.room.currentState.getStateEvents(stateEventType, '');
+ if (!event) {
+ return defaultValue;
+ }
+ return event.getContent()[keyName] || defaultValue;
},
- onColorSchemeChanged: function(index) {
- // preview what the user just changed the scheme to.
- Tinter.tint(room_colors[index][0], room_colors[index][1]);
-
+ _onHistoryRadioToggle: function(ev) {
this.setState({
- color_scheme_changed: true,
- color_scheme_index: index,
+ history_visibility: ev.target.value
});
},
+
+ _onToggle: function(keyName, checkedValue, uncheckedValue, ev) {
+ console.log("Checkbox toggle: %s %s", keyName, ev.target.checked);
+ var state = {};
+ state[keyName] = ev.target.checked ? checkedValue : uncheckedValue;
+ this.setState(state);
+ },
- onTagChange: function(tagName, event) {
+ _onTagChange: function(tagName, event) {
if (event.target.checked) {
if (tagName === 'm.favourite') {
delete this.state.tags['m.lowpriority'];
@@ -202,13 +247,12 @@ module.exports = React.createClass({
delete this.state.tags['m.favourite'];
}
- this.state.tags[tagName] = this.state.tags[tagName] || {};
+ this.state.tags[tagName] = this.state.tags[tagName] || ["yep"];
}
else {
delete this.state.tags[tagName];
}
- // XXX: hacky say to deep-edit state
this.setState({
tags: this.state.tags,
tags_changed: true
@@ -220,34 +264,14 @@ 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');
- var join_rule = this.props.room.currentState.getStateEvents('m.room.join_rules', '');
- if (join_rule) join_rule = join_rule.getContent().join_rule;
-
- var history_visibility = this.props.room.currentState.getStateEvents('m.room.history_visibility', '');
- if (history_visibility) history_visibility = history_visibility.getContent().history_visibility;
-
var power_levels = this.props.room.currentState.getStateEvents('m.room.power_levels', '');
- var guest_access = this.props.room.currentState.getStateEvents('m.room.guest_access', '');
- if (guest_access) {
- 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 ? power_levels.events : {}) || {};
-
var user_id = MatrixClientPeg.get().credentials.userId;
-
if (power_levels) {
power_levels = power_levels.getContent();
@@ -305,41 +329,14 @@ module.exports = React.createClass({
if (events_levels['m.room.canonical_alias'] !== undefined) {
canonical_alias_level = events_levels['m.room.canonical_alias'];
}
- var can_set_canonical_alias = current_user_level >= canonical_alias_level;
-
- var can_set_tag = true;
+ var canSetCanonicalAlias = current_user_level >= canonical_alias_level;
+ var canSetTag = true;
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 (
-
- );
- })}
-
-
;
-
- var user_levels_section;
+ var userLevelsSection;
if (Object.keys(user_levels).length) {
- user_levels_section =
+ userLevelsSection =
Privileged Users
@@ -354,13 +351,13 @@ module.exports = React.createClass({
;
}
else {
- user_levels_section = No users have specific privileges in this room.
+ userLevelsSection = No users have specific privileges in this room.
}
var banned = this.props.room.getMembersWithMembership("ban");
- var banned_users_section;
+ var bannedUsersSection;
if (banned.length) {
- banned_users_section =
+ bannedUsersSection =
Banned users
@@ -375,10 +372,13 @@ module.exports = React.createClass({
;
}
- var create_event = this.props.room.currentState.getStateEvents('m.room.create', '');
- var unfederatable_section;
- if (create_event.getContent()["m.federate"] === false) {
- unfederatable_section = Ths room is not accessible by remote Matrix servers.
+ var unfederatableSection;
+ if (this._yankValueFromEvent("m.room.create", "m.federate") === false) {
+ unfederatableSection = (
+
+ Ths room is not accessible by remote Matrix servers.
+
+ );
}
// TODO: support editing custom events_levels
@@ -395,43 +395,89 @@ module.exports = React.createClass({
}
});
- var tags_section =
+ var tagsSection =
Tagged as:
- { can_set_tag ?
+ { canSetTag ?
tags.map(function(tag, i) {
return (
+ onChange={ self._onTagChange.bind(self, tag.name) }/>
{ tag.label }
);
}) : tags.map(function(tag) { return tag.label; }).join(", ")
}
+ // If there is no history_visibility, it is assumed to be 'shared'.
+ // http://matrix.org/docs/spec/r0.0.0/client_server.html#id31
+ var historyVisibility = this.state.history_visibility || "shared";
+
// FIXME: disable guests_read if the user hasn't turned on shared history
return (
- { tags_section }
+ { tagsSection }
- { room_colors_section }
+
+
Room Colour
+
+
@@ -476,12 +522,12 @@ module.exports = React.createClass({
);
})}
- { unfederatable_section }
+ { unfederatableSection }
- { user_levels_section }
+ { userLevelsSection }
- { banned_users_section }
+ { bannedUsersSection }
Advanced