Fix /join to be consistent with the other code

Plus a number of other tidyups:

 * Fix /join to dispatch a view_room for the room alias
   with the additional auto_join parameter
 * Make RoomView automatically join the room if the auto_join
   parameter is true and the user isn't already in it
 * Tidy up RoomView's peeking code, also fixing
   https://github.com/vector-im/vector-web/issues/1220
   in react-sdk (although it still requires a synapse change
   to actually fix, but react-sdk does 'the right thing').
 * Remove duplication of usage text from /join command
 * Amalgamate MatrixChat::_viewRoom's many, many parameters
   into an object and sort out case consistency a little.
This commit is contained in:
David Baker 2016-06-20 16:30:51 +01:00
parent 8103a795ec
commit d8dedae084
3 changed files with 73 additions and 79 deletions

View file

@ -132,46 +132,25 @@ var commands = {
}),
// Join a room
join: new Command("join", "<room_alias>", function(room_id, args) {
join: new Command("join", "#alias:domain", function(room_id, args) {
if (args) {
var matches = args.match(/^(\S+)$/);
if (matches) {
var room_alias = matches[1];
if (room_alias[0] !== '#') {
return reject("Usage: /join #alias:domain");
return reject(this.getUsage());
}
if (!room_alias.match(/:/)) {
room_alias += ':' + MatrixClientPeg.get().getDomain();
}
// Try to find a room with this alias
// XXX: do we need to do this? Doesn't the JS SDK suppress duplicate attempts to join the same room?
var foundRoom = MatrixTools.getRoomForAlias(
MatrixClientPeg.get().getRooms(),
room_alias
);
dis.dispatch({
action: 'view_room',
room_alias: room_alias,
auto_join: true,
});
if (foundRoom) { // we've already joined this room, view it if it's not archived.
var me = foundRoom.getMember(MatrixClientPeg.get().credentials.userId);
if (me && me.membership !== "leave") {
dis.dispatch({
action: 'view_room',
room_id: foundRoom.roomId
});
return success();
}
}
// otherwise attempt to join this alias.
return success(
MatrixClientPeg.get().joinRoom(room_alias).then(
function(room) {
dis.dispatch({
action: 'view_room',
room_id: room.roomId
});
})
);
return success();
}
}
return reject(this.getUsage());

View file

@ -403,10 +403,7 @@ module.exports = React.createClass({
// known to be in (eg. user clicks on a room in the recents panel), supply the ID
// If the user is clicking on a room in the context of the alias being presented
// to them, supply the room alias. If both are supplied, the room ID will be ignored.
this._viewRoom(
payload.room_id, payload.room_alias, payload.show_settings, payload.event_id,
payload.third_party_invite, payload.oob_data
);
this._viewRoom(payload);
break;
case 'view_prev_room':
roomIndexDelta = -1;
@ -423,7 +420,7 @@ module.exports = React.createClass({
}
roomIndex = (roomIndex + roomIndexDelta) % allRooms.length;
if (roomIndex < 0) roomIndex = allRooms.length - 1;
this._viewRoom(allRooms[roomIndex].roomId);
this._viewRoom({ room_id: allRooms[roomIndex].room_id });
break;
case 'view_indexed_room':
var allRooms = RoomListSorter.mostRecentActivityFirst(
@ -431,7 +428,7 @@ module.exports = React.createClass({
);
var roomIndex = payload.roomIndex;
if (allRooms[roomIndex]) {
this._viewRoom(allRooms[roomIndex].roomId);
this._viewRoom({ room_id: allRooms[roomIndex].roomId });
}
break;
case 'view_user_settings':
@ -491,39 +488,45 @@ module.exports = React.createClass({
// switch view to the given room
//
// eventId is optional and will cause a switch to the context of that
// particular event.
// @param {Object} thirdPartyInvite Object containing data about the third party
// @param {Object} room_info Object containing data about the room to be joined
// @param {string} room_info.room_id ID of the room to join. One of room_id or room_alias must be given.
// @param {string} room_info.room_alias Alias of the room to join. One of room_id or room_alias must be given.
// @param {boolean} room_info.auto_join If true, automatically attempt to join the room if not already a member.
// @param {string} room_info.show_settings ??
// @param {string} room_info.event_id ID of the event in this room to show: this will cause a switch to the
// context of that particular event. Optional.
// @param {Object} room_info.third_party_invite Object containing data about the third party
// we received to join the room, if any.
// @param {string} thirdPartyInvite.inviteSignUrl 3pid invite sign URL
// @param {string} thirdPartyInvite.invitedwithEmail The email address the invite was sent to
// @param {Object} oob_data Object of additional data about the room
// @param {string} room_info.third_party_invite.inviteSignUrl 3pid invite sign URL
// @param {string} room_info.third_party_invite.invitedwithEmail The email address the invite was sent to
// @param {Object} room_info.oob_data Object of additional data about the room
// that has been passed out-of-band (eg.
// room name and avatar from an invite email)
_viewRoom: function(roomId, roomAlias, showSettings, eventId, thirdPartyInvite, oob_data) {
_viewRoom: function(room_info) {
// before we switch room, record the scroll state of the current room
this._updateScrollMap();
this.focusComposer = true;
var newState = {
initialEventId: eventId,
highlightedEventId: eventId,
initialEventId: room_info.event_id,
highlightedEventId: room_info.event_id,
initialEventPixelOffset: undefined,
page_type: this.PageTypes.RoomView,
thirdPartyInvite: thirdPartyInvite,
roomOobData: oob_data,
currentRoomAlias: roomAlias,
thirdPartyInvite: room_info.third_party_invite,
roomOobData: room_info.oob_data,
currentRoomAlias: room_info.room_alias,
autoJoin: room_info.auto_join,
};
if (!roomAlias) {
newState.currentRoomId = roomId;
if (!room_info.room_alias) {
newState.currentRoomId = room_info.room_id;
}
// if we aren't given an explicit event id, look for one in the
// scrollStateMap.
if (!eventId) {
var scrollState = this.scrollStateMap[roomId];
if (!room_info.event_id) {
var scrollState = this.scrollStateMap[room_info.room_id];
if (scrollState) {
newState.initialEventId = scrollState.focussedEvent;
newState.initialEventPixelOffset = scrollState.pixelOffset;
@ -536,8 +539,8 @@ module.exports = React.createClass({
// the new screen yet (we won't be showing it yet)
// The normal case where this happens is navigating
// to the room in the URL bar on page load.
var presentedId = roomAlias || roomId;
var room = MatrixClientPeg.get().getRoom(roomId);
var presentedId = room_info.room_alias || room_info.room_id;
var room = MatrixClientPeg.get().getRoom(room_info.room_id);
if (room) {
var theAlias = MatrixTools.getDisplayAliasForRoom(room);
if (theAlias) presentedId = theAlias;
@ -553,15 +556,15 @@ module.exports = React.createClass({
// Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
}
if (eventId) {
presentedId += "/"+eventId;
if (room_info.event_id) {
presentedId += "/"+event_id;
}
this.notifyNewScreen('room/'+presentedId);
newState.ready = true;
}
this.setState(newState);
if (this.refs.roomView && showSettings) {
if (this.refs.roomView && room_info.showSettings) {
this.refs.roomView.showSettings(true);
}
},
@ -1030,6 +1033,7 @@ module.exports = React.createClass({
<RoomView
ref="roomView"
roomAddress={this.state.currentRoomAlias || this.state.currentRoomId}
autoJoin={this.state.autoJoin}
onRoomIdResolved={this.onRoomIdResolved}
eventId={this.state.initialEventId}
thirdPartyInvite={this.state.thirdPartyInvite}

View file

@ -159,7 +159,7 @@ module.exports = React.createClass({
roomId: result.room_id,
roomLoading: !room,
hasUnsentMessages: this._hasUnsentMessages(room),
}, this._updatePeeking);
}, this._onHaveRoom);
}, (err) => {
this.setState({
roomLoading: false,
@ -172,11 +172,11 @@ module.exports = React.createClass({
room: room,
roomLoading: !room,
hasUnsentMessages: this._hasUnsentMessages(room),
}, this._updatePeeking);
}, this._onHaveRoom);
}
},
_updatePeeking: function() {
_onHaveRoom: function() {
// if this is an unknown room then we're in one of three states:
// - This is a room we can peek into (search engine) (we can /peek)
// - This is a room we can publicly join or were invited to. (we can /join)
@ -187,29 +187,40 @@ module.exports = React.createClass({
// Note that peeking works by room ID and room ID only, as opposed to joining
// which must be by alias or invite wherever possible (peeking currently does
// not work over federation).
if (!this.state.room && this.state.roomId) {
console.log("Attempting to peek into room %s", this.state.roomId);
MatrixClientPeg.get().peekInRoom(this.state.roomId).then((room) => {
this.setState({
room: room,
roomLoading: false,
});
this._onRoomLoaded(room);
}, (err) => {
// This won't necessarily be a MatrixError, but we duck-type
// here and say if it's got an 'errcode' key with the right value,
// it means we can't peek.
if (err.errcode == "M_GUEST_ACCESS_FORBIDDEN") {
// This is fine: the room just isn't peekable (we assume).
// NB. We peek if we are not in the room, although if we try to peek into
// a room in which we have a member event (ie. we've left) synapse will just
// send us the same data as we get in the sync (ie. the last events we saw).
var my_member = this.state.room ? this.state.room.getMember(MatrixClientPeg.get().credentials.userId) : null;
var user_is_in_room = my_member ? my_member.membership == 'join' : false;
if (!user_is_in_room && this.state.roomId) {
if (this.props.autoJoin) {
this.onJoinButtonClicked();
} else if (this.state.roomId) {
console.log("Attempting to peek into room %s", this.state.roomId);
MatrixClientPeg.get().peekInRoom(this.state.roomId).then((room) => {
this.setState({
room: room,
roomLoading: false,
});
} else {
throw err;
}
}).done();
} else if (this.state.room) {
this._onRoomLoaded(room);
}, (err) => {
// This won't necessarily be a MatrixError, but we duck-type
// here and say if it's got an 'errcode' key with the right value,
// it means we can't peek.
if (err.errcode == "M_GUEST_ACCESS_FORBIDDEN") {
// This is fine: the room just isn't peekable (we assume).
this.setState({
roomLoading: false,
});
} else {
throw err;
}
}).done();
}
} else if (user_is_in_room) {
MatrixClientPeg.get().stopPeeking();
this._onRoomLoaded(this.state.room);
}
@ -992,7 +1003,7 @@ module.exports = React.createClass({
this.setState({
rejecting: true
});
MatrixClientPeg.get().leave(this.props.roomAddress).done(function() {
MatrixClientPeg.get().leave(this.props.roomId).done(function() {
dis.dispatch({ action: 'view_next_room' });
self.setState({
rejecting: false