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:
parent
8103a795ec
commit
d8dedae084
3 changed files with 73 additions and 79 deletions
|
@ -132,46 +132,25 @@ var commands = {
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Join a room
|
// 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) {
|
if (args) {
|
||||||
var matches = args.match(/^(\S+)$/);
|
var matches = args.match(/^(\S+)$/);
|
||||||
if (matches) {
|
if (matches) {
|
||||||
var room_alias = matches[1];
|
var room_alias = matches[1];
|
||||||
if (room_alias[0] !== '#') {
|
if (room_alias[0] !== '#') {
|
||||||
return reject("Usage: /join #alias:domain");
|
return reject(this.getUsage());
|
||||||
}
|
}
|
||||||
if (!room_alias.match(/:/)) {
|
if (!room_alias.match(/:/)) {
|
||||||
room_alias += ':' + MatrixClientPeg.get().getDomain();
|
room_alias += ':' + MatrixClientPeg.get().getDomain();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find a room with this alias
|
dis.dispatch({
|
||||||
// XXX: do we need to do this? Doesn't the JS SDK suppress duplicate attempts to join the same room?
|
action: 'view_room',
|
||||||
var foundRoom = MatrixTools.getRoomForAlias(
|
room_alias: room_alias,
|
||||||
MatrixClientPeg.get().getRooms(),
|
auto_join: true,
|
||||||
room_alias
|
});
|
||||||
);
|
|
||||||
|
|
||||||
if (foundRoom) { // we've already joined this room, view it if it's not archived.
|
return success();
|
||||||
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 reject(this.getUsage());
|
return reject(this.getUsage());
|
||||||
|
|
|
@ -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
|
// 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
|
// 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.
|
// to them, supply the room alias. If both are supplied, the room ID will be ignored.
|
||||||
this._viewRoom(
|
this._viewRoom(payload);
|
||||||
payload.room_id, payload.room_alias, payload.show_settings, payload.event_id,
|
|
||||||
payload.third_party_invite, payload.oob_data
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case 'view_prev_room':
|
case 'view_prev_room':
|
||||||
roomIndexDelta = -1;
|
roomIndexDelta = -1;
|
||||||
|
@ -423,7 +420,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
roomIndex = (roomIndex + roomIndexDelta) % allRooms.length;
|
roomIndex = (roomIndex + roomIndexDelta) % allRooms.length;
|
||||||
if (roomIndex < 0) roomIndex = allRooms.length - 1;
|
if (roomIndex < 0) roomIndex = allRooms.length - 1;
|
||||||
this._viewRoom(allRooms[roomIndex].roomId);
|
this._viewRoom({ room_id: allRooms[roomIndex].room_id });
|
||||||
break;
|
break;
|
||||||
case 'view_indexed_room':
|
case 'view_indexed_room':
|
||||||
var allRooms = RoomListSorter.mostRecentActivityFirst(
|
var allRooms = RoomListSorter.mostRecentActivityFirst(
|
||||||
|
@ -431,7 +428,7 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
var roomIndex = payload.roomIndex;
|
var roomIndex = payload.roomIndex;
|
||||||
if (allRooms[roomIndex]) {
|
if (allRooms[roomIndex]) {
|
||||||
this._viewRoom(allRooms[roomIndex].roomId);
|
this._viewRoom({ room_id: allRooms[roomIndex].roomId });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'view_user_settings':
|
case 'view_user_settings':
|
||||||
|
@ -491,39 +488,45 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// switch view to the given room
|
// switch view to the given room
|
||||||
//
|
//
|
||||||
// eventId is optional and will cause a switch to the context of that
|
// @param {Object} room_info Object containing data about the room to be joined
|
||||||
// particular event.
|
// @param {string} room_info.room_id ID of the room to join. One of room_id or room_alias must be given.
|
||||||
// @param {Object} thirdPartyInvite Object containing data about the third party
|
// @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.
|
// we received to join the room, if any.
|
||||||
// @param {string} thirdPartyInvite.inviteSignUrl 3pid invite sign URL
|
// @param {string} room_info.third_party_invite.inviteSignUrl 3pid invite sign URL
|
||||||
// @param {string} thirdPartyInvite.invitedwithEmail The email address the invite was sent to
|
// @param {string} room_info.third_party_invite.invitedwithEmail The email address the invite was sent to
|
||||||
// @param {Object} oob_data Object of additional data about the room
|
// @param {Object} room_info.oob_data Object of additional data about the room
|
||||||
// that has been passed out-of-band (eg.
|
// that has been passed out-of-band (eg.
|
||||||
// room name and avatar from an invite email)
|
// 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
|
// before we switch room, record the scroll state of the current room
|
||||||
this._updateScrollMap();
|
this._updateScrollMap();
|
||||||
|
|
||||||
this.focusComposer = true;
|
this.focusComposer = true;
|
||||||
|
|
||||||
var newState = {
|
var newState = {
|
||||||
initialEventId: eventId,
|
initialEventId: room_info.event_id,
|
||||||
highlightedEventId: eventId,
|
highlightedEventId: room_info.event_id,
|
||||||
initialEventPixelOffset: undefined,
|
initialEventPixelOffset: undefined,
|
||||||
page_type: this.PageTypes.RoomView,
|
page_type: this.PageTypes.RoomView,
|
||||||
thirdPartyInvite: thirdPartyInvite,
|
thirdPartyInvite: room_info.third_party_invite,
|
||||||
roomOobData: oob_data,
|
roomOobData: room_info.oob_data,
|
||||||
currentRoomAlias: roomAlias,
|
currentRoomAlias: room_info.room_alias,
|
||||||
|
autoJoin: room_info.auto_join,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!roomAlias) {
|
if (!room_info.room_alias) {
|
||||||
newState.currentRoomId = roomId;
|
newState.currentRoomId = room_info.room_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we aren't given an explicit event id, look for one in the
|
// if we aren't given an explicit event id, look for one in the
|
||||||
// scrollStateMap.
|
// scrollStateMap.
|
||||||
if (!eventId) {
|
if (!room_info.event_id) {
|
||||||
var scrollState = this.scrollStateMap[roomId];
|
var scrollState = this.scrollStateMap[room_info.room_id];
|
||||||
if (scrollState) {
|
if (scrollState) {
|
||||||
newState.initialEventId = scrollState.focussedEvent;
|
newState.initialEventId = scrollState.focussedEvent;
|
||||||
newState.initialEventPixelOffset = scrollState.pixelOffset;
|
newState.initialEventPixelOffset = scrollState.pixelOffset;
|
||||||
|
@ -536,8 +539,8 @@ module.exports = React.createClass({
|
||||||
// the new screen yet (we won't be showing it yet)
|
// the new screen yet (we won't be showing it yet)
|
||||||
// The normal case where this happens is navigating
|
// The normal case where this happens is navigating
|
||||||
// to the room in the URL bar on page load.
|
// to the room in the URL bar on page load.
|
||||||
var presentedId = roomAlias || roomId;
|
var presentedId = room_info.room_alias || room_info.room_id;
|
||||||
var room = MatrixClientPeg.get().getRoom(roomId);
|
var room = MatrixClientPeg.get().getRoom(room_info.room_id);
|
||||||
if (room) {
|
if (room) {
|
||||||
var theAlias = MatrixTools.getDisplayAliasForRoom(room);
|
var theAlias = MatrixTools.getDisplayAliasForRoom(room);
|
||||||
if (theAlias) presentedId = theAlias;
|
if (theAlias) presentedId = theAlias;
|
||||||
|
@ -553,15 +556,15 @@ module.exports = React.createClass({
|
||||||
// Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
|
// Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventId) {
|
if (room_info.event_id) {
|
||||||
presentedId += "/"+eventId;
|
presentedId += "/"+event_id;
|
||||||
}
|
}
|
||||||
this.notifyNewScreen('room/'+presentedId);
|
this.notifyNewScreen('room/'+presentedId);
|
||||||
newState.ready = true;
|
newState.ready = true;
|
||||||
}
|
}
|
||||||
this.setState(newState);
|
this.setState(newState);
|
||||||
|
|
||||||
if (this.refs.roomView && showSettings) {
|
if (this.refs.roomView && room_info.showSettings) {
|
||||||
this.refs.roomView.showSettings(true);
|
this.refs.roomView.showSettings(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1030,6 +1033,7 @@ module.exports = React.createClass({
|
||||||
<RoomView
|
<RoomView
|
||||||
ref="roomView"
|
ref="roomView"
|
||||||
roomAddress={this.state.currentRoomAlias || this.state.currentRoomId}
|
roomAddress={this.state.currentRoomAlias || this.state.currentRoomId}
|
||||||
|
autoJoin={this.state.autoJoin}
|
||||||
onRoomIdResolved={this.onRoomIdResolved}
|
onRoomIdResolved={this.onRoomIdResolved}
|
||||||
eventId={this.state.initialEventId}
|
eventId={this.state.initialEventId}
|
||||||
thirdPartyInvite={this.state.thirdPartyInvite}
|
thirdPartyInvite={this.state.thirdPartyInvite}
|
||||||
|
|
|
@ -159,7 +159,7 @@ module.exports = React.createClass({
|
||||||
roomId: result.room_id,
|
roomId: result.room_id,
|
||||||
roomLoading: !room,
|
roomLoading: !room,
|
||||||
hasUnsentMessages: this._hasUnsentMessages(room),
|
hasUnsentMessages: this._hasUnsentMessages(room),
|
||||||
}, this._updatePeeking);
|
}, this._onHaveRoom);
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
roomLoading: false,
|
roomLoading: false,
|
||||||
|
@ -172,11 +172,11 @@ module.exports = React.createClass({
|
||||||
room: room,
|
room: room,
|
||||||
roomLoading: !room,
|
roomLoading: !room,
|
||||||
hasUnsentMessages: this._hasUnsentMessages(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:
|
// 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 peek into (search engine) (we can /peek)
|
||||||
// - This is a room we can publicly join or were invited to. (we can /join)
|
// - 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
|
// 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
|
// which must be by alias or invite wherever possible (peeking currently does
|
||||||
// not work over federation).
|
// 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) => {
|
// NB. We peek if we are not in the room, although if we try to peek into
|
||||||
this.setState({
|
// a room in which we have a member event (ie. we've left) synapse will just
|
||||||
room: room,
|
// send us the same data as we get in the sync (ie. the last events we saw).
|
||||||
roomLoading: false,
|
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;
|
||||||
this._onRoomLoaded(room);
|
|
||||||
}, (err) => {
|
if (!user_is_in_room && this.state.roomId) {
|
||||||
// This won't necessarily be a MatrixError, but we duck-type
|
if (this.props.autoJoin) {
|
||||||
// here and say if it's got an 'errcode' key with the right value,
|
this.onJoinButtonClicked();
|
||||||
// it means we can't peek.
|
} else if (this.state.roomId) {
|
||||||
if (err.errcode == "M_GUEST_ACCESS_FORBIDDEN") {
|
console.log("Attempting to peek into room %s", this.state.roomId);
|
||||||
// This is fine: the room just isn't peekable (we assume).
|
|
||||||
|
MatrixClientPeg.get().peekInRoom(this.state.roomId).then((room) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
room: room,
|
||||||
roomLoading: false,
|
roomLoading: false,
|
||||||
});
|
});
|
||||||
} else {
|
this._onRoomLoaded(room);
|
||||||
throw err;
|
}, (err) => {
|
||||||
}
|
// This won't necessarily be a MatrixError, but we duck-type
|
||||||
}).done();
|
// here and say if it's got an 'errcode' key with the right value,
|
||||||
} else if (this.state.room) {
|
// 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();
|
MatrixClientPeg.get().stopPeeking();
|
||||||
this._onRoomLoaded(this.state.room);
|
this._onRoomLoaded(this.state.room);
|
||||||
}
|
}
|
||||||
|
@ -992,7 +1003,7 @@ module.exports = React.createClass({
|
||||||
this.setState({
|
this.setState({
|
||||||
rejecting: true
|
rejecting: true
|
||||||
});
|
});
|
||||||
MatrixClientPeg.get().leave(this.props.roomAddress).done(function() {
|
MatrixClientPeg.get().leave(this.props.roomId).done(function() {
|
||||||
dis.dispatch({ action: 'view_next_room' });
|
dis.dispatch({ action: 'view_next_room' });
|
||||||
self.setState({
|
self.setState({
|
||||||
rejecting: false
|
rejecting: false
|
||||||
|
|
Loading…
Reference in a new issue