Merge pull request #241 from matrix-org/matthew/room-visibility

rework roomsettings for new visibility UI
This commit is contained in:
Matthew Hodgson 2016-03-22 12:30:21 +00:00
commit e141a44103

View file

@ -55,9 +55,20 @@ module.exports = React.createClass({
power_levels_changed: false, power_levels_changed: false,
tags_changed: false, tags_changed: false,
tags: tags, tags: tags,
areNotifsMuted: areNotifsMuted areNotifsMuted: areNotifsMuted,
// isRoomPublished: // set in componentWillMount
}; };
}, },
componentWillMount: function() {
MatrixClientPeg.get().getRoomDirectoryVisibility(
this.props.room.roomId
).done((result) => {
this.setState({ isRoomPublished: result.visibility === "public" });
}, (err) => {
console.error("Failed to get room visibility: " + err);
});
},
setName: function(name) { setName: function(name) {
this.setState({ this.setState({
@ -112,6 +123,13 @@ module.exports = React.createClass({
)); ));
} }
if (this.state.isRoomPublished !== originalState.isRoomPublished) {
promises.push(MatrixClientPeg.get().setRoomDirectoryVisibility(
roomId,
this.state.isRoomPublished ? "public" : "private"
));
}
if (this.state.join_rule !== originalState.join_rule) { if (this.state.join_rule !== originalState.join_rule) {
promises.push(MatrixClientPeg.get().sendStateEvent( promises.push(MatrixClientPeg.get().sendStateEvent(
roomId, "m.room.join_rules", roomId, "m.room.join_rules",
@ -252,6 +270,43 @@ module.exports = React.createClass({
}); });
}, },
_onRoomAccessRadioToggle: function(ev) {
// join_rule
// INVITE | PUBLIC
// ----------------------+----------------
// guest CAN_JOIN | inv_only | pub_with_guest
// access ----------------------+----------------
// FORBIDDEN | inv_only | pub_no_guest
// ----------------------+----------------
switch (ev.target.value) {
case "invite_only":
this.setState({
join_rule: "invite",
// we always set guests can_join here as it makes no sense to have
// an invite-only room that guests can't join. If you explicitly
// invite them, you clearly want them to join, whether they're a
// guest or not. In practice, guest_access should probably have
// been implemented as part of the join_rules enum.
guest_access: "can_join",
});
break;
case "public_no_guests":
this.setState({
join_rule: "public",
guest_access: "forbidden",
});
break;
case "public_with_guests":
this.setState({
join_rule: "public",
guest_access: "can_join",
});
break;
}
},
_onToggle: function(keyName, checkedValue, uncheckedValue, ev) { _onToggle: function(keyName, checkedValue, uncheckedValue, ev) {
console.log("Checkbox toggle: %s %s", keyName, ev.target.checked); console.log("Checkbox toggle: %s %s", keyName, ev.target.checked);
var state = {}; var state = {};
@ -280,6 +335,13 @@ module.exports = React.createClass({
}); });
}, },
mayChangeRoomAccess: function() {
var cli = MatrixClientPeg.get();
var roomState = this.props.room.currentState;
return (roomState.mayClientSendStateEvent("m.room.join_rules", cli) &&
roomState.mayClientSendStateEvent("m.room.guest_access", cli))
},
render: function() { render: function() {
// TODO: go through greying out things you don't have permission to change // TODO: go through greying out things you don't have permission to change
// (or turning them into informative stuff) // (or turning them into informative stuff)
@ -427,7 +489,31 @@ module.exports = React.createClass({
// http://matrix.org/docs/spec/r0.0.0/client_server.html#id31 // http://matrix.org/docs/spec/r0.0.0/client_server.html#id31
var historyVisibility = this.state.history_visibility || "shared"; var historyVisibility = this.state.history_visibility || "shared";
// FIXME: disable guests_read if the user hasn't turned on shared history var addressWarning;
var aliasEvents = this.props.room.currentState.getStateEvents('m.room.aliases') || [];
var aliasCount = 0;
aliasEvents.forEach((event) => {
aliasCount += event.getContent().aliases.length;
});
if (this.state.join_rule === "public" && aliasCount == 0) {
addressWarning =
<div className="mx_RoomSettings_warning">
To link to a room it must have <a href="#addresses">an address</a>.
</div>
}
var inviteGuestWarning;
if (this.state.join_rule !== "public" && this.state.guest_access === "forbidden") {
inviteGuestWarning =
<div className="mx_RoomSettings_warning">
Guests cannot join this room even if explicitly invited. <a href="#" onClick={ (e) => {
this.setState({ join_rule: "invite", guest_access: "can_join" });
e.preventDefault();
}}>Click here to fix</a>.
</div>
}
return ( return (
<div className="mx_RoomSettings"> <div className="mx_RoomSettings">
@ -440,43 +526,64 @@ module.exports = React.createClass({
defaultChecked={this.state.areNotifsMuted}/> defaultChecked={this.state.areNotifsMuted}/>
Mute notifications for this room Mute notifications for this room
</label> </label>
<label> <div className="mx_RoomSettings_settings">
<input type="checkbox" disabled={ !roomState.mayClientSendStateEvent("m.room.join_rules", cli) } <h3>Who can access this room?</h3>
onChange={this._onToggle.bind(this, "join_rule", "invite", "public")} { inviteGuestWarning }
defaultChecked={this.state.join_rule !== "public"}/> <label>
Make this room private <input type="radio" name="roomVis" value="invite_only"
</label> disabled={ !this.mayChangeRoomAccess() }
<label> onChange={this._onRoomAccessRadioToggle}
<input type="checkbox" disabled={ !roomState.mayClientSendStateEvent("m.room.guest_access", cli) } checked={this.state.join_rule !== "public"}/>
onChange={this._onToggle.bind(this, "guest_access", "can_join", "forbidden")} Only people who have been invited
defaultChecked={this.state.guest_access === "can_join"}/> </label>
Let guests join this room <label>
</label> <input type="radio" name="roomVis" value="public_no_guests"
disabled={ !this.mayChangeRoomAccess() }
onChange={this._onRoomAccessRadioToggle}
checked={this.state.join_rule === "public" && this.state.guest_access !== "can_join"}/>
Anyone who knows the room's link, apart from guests
</label>
<label>
<input type="radio" name="roomVis" value="public_with_guests"
disabled={ !this.mayChangeRoomAccess() }
onChange={this._onRoomAccessRadioToggle}
checked={this.state.join_rule === "public" && this.state.guest_access === "can_join"}/>
Anyone who knows the room's link, including guests
</label>
{ addressWarning }
<br/>
<label>
<input type="checkbox" disabled={ !roomState.mayClientSendStateEvent("m.room.aliases", cli) }
onChange={ this._onToggle.bind(this, "isRoomPublished", true, false)}
checked={this.state.isRoomPublished}/>
List this room in { MatrixClientPeg.get().getDomain() }'s directory?
</label>
</div>
<div className="mx_RoomSettings_settings"> <div className="mx_RoomSettings_settings">
<h3>Who can read history?</h3> <h3>Who can read history?</h3>
<label htmlFor="hvis_wr"> <label>
<input type="radio" id="hvis_wr" name="historyVis" value="world_readable" <input type="radio" name="historyVis" value="world_readable"
disabled={ !roomState.mayClientSendStateEvent("m.room.history_visibility", cli) } disabled={ !roomState.mayClientSendStateEvent("m.room.history_visibility", cli) }
checked={historyVisibility === "world_readable"} checked={historyVisibility === "world_readable"}
onChange={this._onHistoryRadioToggle} /> onChange={this._onHistoryRadioToggle} />
Anyone Anyone
</label> </label>
<label htmlFor="hvis_sh"> <label>
<input type="radio" id="hvis_sh" name="historyVis" value="shared" <input type="radio" name="historyVis" value="shared"
disabled={ !roomState.mayClientSendStateEvent("m.room.history_visibility", cli) } disabled={ !roomState.mayClientSendStateEvent("m.room.history_visibility", cli) }
checked={historyVisibility === "shared"} checked={historyVisibility === "shared"}
onChange={this._onHistoryRadioToggle} /> onChange={this._onHistoryRadioToggle} />
Members only (since the point in time of selecting this option) Members only (since the point in time of selecting this option)
</label> </label>
<label htmlFor="hvis_inv"> <label>
<input type="radio" id="hvis_inv" name="historyVis" value="invited" <input type="radio" name="historyVis" value="invited"
disabled={ !roomState.mayClientSendStateEvent("m.room.history_visibility", cli) } disabled={ !roomState.mayClientSendStateEvent("m.room.history_visibility", cli) }
checked={historyVisibility === "invited"} checked={historyVisibility === "invited"}
onChange={this._onHistoryRadioToggle} /> onChange={this._onHistoryRadioToggle} />
Members only (since they were invited) Members only (since they were invited)
</label> </label>
<label htmlFor="hvis_joi"> <label >
<input type="radio" id="hvis_joi" name="historyVis" value="joined" <input type="radio" name="historyVis" value="joined"
disabled={ !roomState.mayClientSendStateEvent("m.room.history_visibility", cli) } disabled={ !roomState.mayClientSendStateEvent("m.room.history_visibility", cli) }
checked={historyVisibility === "joined"} checked={historyVisibility === "joined"}
onChange={this._onHistoryRadioToggle} /> onChange={this._onHistoryRadioToggle} />
@ -495,6 +602,8 @@ module.exports = React.createClass({
<ColorSettings ref="color_settings" room={this.props.room} /> <ColorSettings ref="color_settings" room={this.props.room} />
</div> </div>
<a id="addresses"/>
<AliasSettings ref="alias_settings" <AliasSettings ref="alias_settings"
roomId={this.props.room.roomId} roomId={this.props.room.roomId}
canSetCanonicalAlias={ roomState.mayClientSendStateEvent("m.room.canonical_alias", cli) } canSetCanonicalAlias={ roomState.mayClientSendStateEvent("m.room.canonical_alias", cli) }