diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js
index 462933cbc6..71910b6f31 100644
--- a/src/components/structures/MatrixChat.js
+++ b/src/components/structures/MatrixChat.js
@@ -65,6 +65,7 @@ module.exports = React.createClass({
collapse_rhs: false,
ready: false,
width: 10000,
+ autoPeek: true, // by default, we peek into rooms when we try to join them
};
if (s.logged_in) {
if (MatrixClientPeg.get().getRooms().length) {
@@ -304,6 +305,9 @@ module.exports = React.createClass({
});
break;
case 'view_room':
+ // by default we autoPeek rooms, unless we were called explicitly with
+ // autoPeek=false by something like RoomDirectory who has already peeked
+ this.setState({ autoPeek : payload.auto_peek === false ? false : true });
this._viewRoom(payload.room_id, payload.show_settings);
break;
case 'view_prev_room':
@@ -787,6 +791,7 @@ module.exports = React.createClass({
);
diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js
index 5604565dd7..b4986e7a33 100644
--- a/src/components/structures/RoomView.js
+++ b/src/components/structures/RoomView.js
@@ -57,7 +57,9 @@ if (DEBUG_SCROLL) {
module.exports = React.createClass({
displayName: 'RoomView',
propTypes: {
- ConferenceHandler: React.PropTypes.any
+ ConferenceHandler: React.PropTypes.any,
+ roomId: React.PropTypes.string,
+ autoPeek: React.PropTypes.bool, // should we try to peek the room on mount, or has whoever invoked us already initiated a peek?
},
/* properties in RoomView objects include:
@@ -78,7 +80,9 @@ module.exports = React.createClass({
syncState: MatrixClientPeg.get().getSyncState(),
hasUnsentMessages: this._hasUnsentMessages(room),
callState: null,
+ autoPeekDone: false, // track whether our autoPeek (if any) has completed)
guestsCanJoin: false,
+ canPeek: false,
readMarkerEventId: room ? room.getEventReadUpTo(MatrixClientPeg.get().credentials.userId) : null,
readMarkerGhostEventId: undefined
}
@@ -86,6 +90,7 @@ module.exports = React.createClass({
componentWillMount: function() {
this.dispatcherRef = dis.register(this.onAction);
+ MatrixClientPeg.get().on("Room", this.onNewRoom);
MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline);
MatrixClientPeg.get().on("Room.name", this.onRoomName);
MatrixClientPeg.get().on("Room.accountData", this.onRoomAccountData);
@@ -110,9 +115,13 @@ module.exports = React.createClass({
// We can't try to /join because this may implicitly accept invites (!)
// We can /peek though. If it fails then we present the join UI. If it
// succeeds then great, show the preview (but we still may be able to /join!).
- if (!this.state.room) {
+ if (!this.state.room && this.props.autoPeek) {
console.log("Attempting to peek into room %s", this.props.roomId);
MatrixClientPeg.get().peekInRoom(this.props.roomId).done(() => {
+ this.setState({
+ autoPeekDone: true;
+ });
+
// we don't need to do anything - JS SDK will emit Room events
// which will update the UI. We *do* however need to know if we
// can join the room so we can fiddle with the UI appropriately.
@@ -120,15 +129,20 @@ module.exports = React.createClass({
if (!peekedRoom) {
return;
}
+
var guestAccessEvent = peekedRoom.currentState.getStateEvents("m.room.guest_access", "");
- if (!guestAccessEvent) {
- return;
- }
- if (guestAccessEvent.getContent().guest_access === "can_join") {
+ if (guestAccessEvent && guestAccessEvent.getContent().guest_access === "can_join") {
this.setState({
guestsCanJoin: true
});
}
+
+ var historyVisibility = peekedRoom.currentState.getStateEvents("m.room.history_visibility", "");
+ if (historyVisibility && historyVisibility.getContent().history_visibility === "world_readable") {
+ this.setState({
+ canPeek: true
+ });
+ }
}, function(err) {
console.error("Failed to peek into room: %s", err);
});
@@ -155,6 +169,7 @@ module.exports = React.createClass({
}
dis.unregister(this.dispatcherRef);
if (MatrixClientPeg.get()) {
+ MatrixClientPeg.get().removeListener("Room", this.onNewRoom);
MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
MatrixClientPeg.get().removeListener("Room.accountData", this.onRoomAccountData);
@@ -278,6 +293,14 @@ module.exports = React.createClass({
});
},
+ onNewRoom: function(room) {
+ if (room.roomId == this.props.roomId) {
+ this.setState({
+ room: room
+ });
+ }
+ },
+
onRoomName: function(room) {
if (room.roomId == this.props.roomId) {
this.setState({
@@ -929,9 +952,10 @@ module.exports = React.createClass({
);
}
+ var visibilityDeferred;
if (old_history_visibility != newVals.history_visibility &&
newVals.history_visibility != undefined) {
- deferreds.push(
+ visibilityDeferred =
MatrixClientPeg.get().sendStateEvent(
this.state.room.roomId, "m.room.history_visibility", {
history_visibility: newVals.history_visibility,
@@ -940,6 +964,27 @@ module.exports = React.createClass({
);
}
+ 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);
+ }
+
if (newVals.power_levels) {
deferreds.push(
MatrixClientPeg.get().sendStateEvent(
@@ -1033,17 +1078,6 @@ module.exports = React.createClass({
);
}
- if (old_guest_read != newVals.guest_read ||
- old_guest_join != newVals.guest_join)
- {
- deferreds.push(
- MatrixClientPeg.get().setGuestAccess(this.state.room.roomId, {
- allowRead: newVals.guest_read,
- allowJoin: newVals.guest_join
- })
- );
- }
-
if (deferreds.length) {
var self = this;
q.allSettled(deferreds).then(
@@ -1391,12 +1425,28 @@ module.exports = React.createClass({
if (!this.state.room) {
if (this.props.roomId) {
- return (
-
- Join Room
-
- );
- } else {
+ if (this.props.autoPeek && !this.state.autoPeekDone) {
+ return (
+
+
+
+ );
+ }
+ else {
+ var joinErrorText = this.state.joinError ? "Failed to join room!" : "";
+ return (
+
+ );
+ }
+ }
+ else {
return (
);
@@ -1417,16 +1467,21 @@ module.exports = React.createClass({
var inviteEvent = myMember.events.member;
var inviterName = inviteEvent.sender ? inviteEvent.sender.name : inviteEvent.getSender();
// XXX: Leaving this intentionally basic for now because invites are about to change totally
+ // FIXME: This comment is now outdated - what do we need to fix? ^
var joinErrorText = this.state.joinError ? "Failed to join room!" : "";
var rejectErrorText = this.state.rejectError ? "Failed to reject invite!" : "";
+
+ // We deliberately don't try to peek into invites, even if we have permission to peek
+ // as they could be a spam vector.
+ // XXX: in future we could give the option of a 'Preview' button which lets them view anyway.
return (
-
-
{inviterName} has invited you to a room
-
-
Join
-
Reject
+
+
{joinErrorText}
{rejectErrorText}
@@ -1544,6 +1599,12 @@ module.exports = React.createClass({
);
}
+ else if (this.state.canPeek &&
+ (!myMember || myMember.membership !== "join")) {
+ aux = (
+
+ );
+ }
var conferenceCallNotification = null;
if (this.state.displayConfCallNotification) {
diff --git a/src/components/views/rooms/RoomPreviewBar.js b/src/components/views/rooms/RoomPreviewBar.js
index 2f12c4c8e2..657aa6a4d9 100644
--- a/src/components/views/rooms/RoomPreviewBar.js
+++ b/src/components/views/rooms/RoomPreviewBar.js
@@ -23,33 +23,57 @@ module.exports = React.createClass({
propTypes: {
onJoinClick: React.PropTypes.func,
- canJoin: React.PropTypes.bool
+ onRejectClick: React.PropTypes.func,
+ inviterName: React.PropTypes.string,
+ canJoin: React.PropTypes.bool,
+ canPreview: React.PropTypes.bool,
},
getDefaultProps: function() {
return {
onJoinClick: function() {},
- canJoin: false
+ canJoin: false,
+ canPreview: true,
};
},
render: function() {
- var joinBlock;
+ var joinBlock, previewBlock;
- if (this.props.canJoin) {
+ if (this.props.inviter) {
+ joinBlock = (
+
+
+ You have been invited to join this room by { this.props.inviterName }
+
+
+
+ );
+
+ }
+ else if (this.props.canJoin) {
joinBlock = (
- Would you like to
join this room?
+ Would you like to
join this room?
+
+ );
+ }
+
+ if (this.props.canPreview) {
+ previewBlock = (
+
+ This is a preview of this room. Room interactions have been disabled.
);
}
return (
-
- This is a preview of this room. Room interactions have been disabled.
-
- {joinBlock}
+ { previewBlock }
+ { joinBlock }
);
}
diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js
index 0ff15a4f43..f41e30091b 100644
--- a/src/components/views/rooms/RoomSettings.js
+++ b/src/components/views/rooms/RoomSettings.js
@@ -660,12 +660,13 @@ module.exports = React.createClass({
}
+ // FIXME: disable guests_read if the user hasn't turned on shared history
return (
Make this room private
- Share message history with new users
- Allow guests to read messages in this room
- Allow guests to join this room
+ Share message history with new participants
+ Let guests join this room
+ Let users read message history without joining
Encrypt room
{ tags_section }