Merge pull request #307 from matrix-org/dbkr/fix_peeking

Fix peeking and member list vanishing
pull/21833/head
Richard van der Hoff 2016-06-16 11:13:20 +01:00 committed by GitHub
commit 0cc4497ef0
2 changed files with 86 additions and 41 deletions

View File

@ -64,6 +64,13 @@ module.exports = React.createClass({
getInitialState: function() { getInitialState: function() {
var s = { var s = {
// If we are viewing a room by alias, this contains the alias
currentRoomAlias: null,
// The ID of the room we're viewing. This is either populated directly
// in the case where we view a room by ID or by RoomView when it resolves
// what ID an alias points at.
currentRoomId: null,
logged_in: !!(MatrixClientPeg.get() && MatrixClientPeg.get().credentials), logged_in: !!(MatrixClientPeg.get() && MatrixClientPeg.get().credentials),
collapse_lhs: false, collapse_lhs: false,
collapse_rhs: false, collapse_rhs: false,
@ -392,10 +399,10 @@ module.exports = React.createClass({
}); });
break; break;
case 'view_room': case 'view_room':
// Takes both room ID and room alias: if switching to a room the client is already // Takes either a room ID or room alias: if switching to a room the client is already
// know to be in (eg. user clicks on a room in the recents panel), supply only the // known to be in (eg. user clicks on a room in the recents panel), supply the ID
// 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 and optionally the room ID. // to them, supply the room alias. If both are supplied, the room ID will be ignored.
this._viewRoom( this._viewRoom(
payload.room_id, payload.room_alias, payload.show_settings, payload.event_id, payload.room_id, payload.room_alias, payload.show_settings, payload.event_id,
payload.third_party_invite, payload.oob_data payload.third_party_invite, payload.oob_data
@ -409,7 +416,7 @@ module.exports = React.createClass({
); );
var roomIndex = -1; var roomIndex = -1;
for (var i = 0; i < allRooms.length; ++i) { for (var i = 0; i < allRooms.length; ++i) {
if (allRooms[i].roomId == this.state.currentRoom) { if (allRooms[i].roomId == this.state.currentRoomId) {
roomIndex = i; roomIndex = i;
break; break;
} }
@ -506,18 +513,11 @@ module.exports = React.createClass({
page_type: this.PageTypes.RoomView, page_type: this.PageTypes.RoomView,
thirdPartyInvite: thirdPartyInvite, thirdPartyInvite: thirdPartyInvite,
roomOobData: oob_data, roomOobData: oob_data,
currentRoomAlias: roomAlias,
}; };
// If an alias has been provided, we use that and only that, if (!roomAlias) {
// since otherwise we'll prefer to pass in an ID to RoomView newState.currentRoomId = roomId;
// but if we're not in the room, we should join by alias rather
// than ID.
if (roomAlias) {
newState.currentRoomAlias = roomAlias;
newState.currentRoom = null;
} else {
newState.currentRoomAlias = null;
newState.currentRoom = roomId;
} }
// 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
@ -612,13 +612,13 @@ module.exports = React.createClass({
dis.dispatch(self.starting_room_alias_payload); dis.dispatch(self.starting_room_alias_payload);
delete self.starting_room_alias_payload; delete self.starting_room_alias_payload;
} else if (!self.state.page_type) { } else if (!self.state.page_type) {
if (!self.state.currentRoom) { if (!self.state.currentRoomId) {
var firstRoom = null; var firstRoom = null;
if (cli.getRooms() && cli.getRooms().length) { if (cli.getRooms() && cli.getRooms().length) {
firstRoom = RoomListSorter.mostRecentActivityFirst( firstRoom = RoomListSorter.mostRecentActivityFirst(
cli.getRooms() cli.getRooms()
)[0].roomId; )[0].roomId;
self.setState({ready: true, currentRoom: firstRoom, page_type: self.PageTypes.RoomView}); self.setState({ready: true, currentRoomId: firstRoom, page_type: self.PageTypes.RoomView});
} else { } else {
self.setState({ready: true, page_type: self.PageTypes.RoomDirectory}); self.setState({ready: true, page_type: self.PageTypes.RoomDirectory});
} }
@ -628,8 +628,8 @@ module.exports = React.createClass({
// we notifyNewScreen now because now the room will actually be displayed, // we notifyNewScreen now because now the room will actually be displayed,
// and (mostly) now we can get the correct alias. // and (mostly) now we can get the correct alias.
var presentedId = self.state.currentRoom; var presentedId = self.state.currentRoomId;
var room = MatrixClientPeg.get().getRoom(self.state.currentRoom); var room = MatrixClientPeg.get().getRoom(self.state.currentRoomId);
if (room) { if (room) {
var theAlias = MatrixTools.getCanonicalAliasForRoom(room); var theAlias = MatrixTools.getCanonicalAliasForRoom(room);
if (theAlias) presentedId = theAlias; if (theAlias) presentedId = theAlias;
@ -979,10 +979,10 @@ module.exports = React.createClass({
onUserSettingsClose: function() { onUserSettingsClose: function() {
// XXX: use browser history instead to find the previous room? // XXX: use browser history instead to find the previous room?
// or maintain a this.state.pageHistory in _setPage()? // or maintain a this.state.pageHistory in _setPage()?
if (this.state.currentRoom) { if (this.state.currentRoomId) {
dis.dispatch({ dis.dispatch({
action: 'view_room', action: 'view_room',
room_id: this.state.currentRoom, room_id: this.state.currentRoomId,
}); });
} }
else { else {
@ -992,6 +992,13 @@ module.exports = React.createClass({
} }
}, },
onRoomIdResolved: function(room_id) {
// It's the RoomView's resposibility to look up room aliases, but we need the
// ID to pass into things like the Member List, so the Room View tells us when
// its done that resolution so we can display things that take a room ID.
this.setState({currentRoomId: room_id});
},
render: function() { render: function() {
var LeftPanel = sdk.getComponent('structures.LeftPanel'); var LeftPanel = sdk.getComponent('structures.LeftPanel');
var RoomView = sdk.getComponent('structures.RoomView'); var RoomView = sdk.getComponent('structures.RoomView');
@ -1022,17 +1029,18 @@ module.exports = React.createClass({
page_element = ( page_element = (
<RoomView <RoomView
ref="roomView" ref="roomView"
roomAddress={this.state.currentRoom || this.state.currentRoomAlias} roomAddress={this.state.currentRoomAlias || this.state.currentRoomId}
onRoomIdResolved={this.onRoomIdResolved}
eventId={this.state.initialEventId} eventId={this.state.initialEventId}
thirdPartyInvite={this.state.thirdPartyInvite} thirdPartyInvite={this.state.thirdPartyInvite}
oobData={this.state.roomOobData} oobData={this.state.roomOobData}
highlightedEventId={this.state.highlightedEventId} highlightedEventId={this.state.highlightedEventId}
eventPixelOffset={this.state.initialEventPixelOffset} eventPixelOffset={this.state.initialEventPixelOffset}
key={this.state.currentRoom || this.state.currentRoomAlias} key={this.state.currentRoomAlias || this.state.currentRoomId}
opacity={this.state.middleOpacity} opacity={this.state.middleOpacity}
ConferenceHandler={this.props.ConferenceHandler} /> ConferenceHandler={this.props.ConferenceHandler} />
); );
right_panel = <RightPanel roomId={this.state.currentRoom} collapsed={this.state.collapse_rhs} opacity={this.state.sideOpacity} /> right_panel = <RightPanel roomId={this.state.currentRoomId} collapsed={this.state.collapse_rhs} opacity={this.state.sideOpacity} />
break; break;
case this.PageTypes.UserSettings: case this.PageTypes.UserSettings:
page_element = <UserSettings onClose={this.onUserSettingsClose} version={this.state.version} brand={this.props.config.brand} /> page_element = <UserSettings onClose={this.onUserSettingsClose} version={this.state.version} brand={this.props.config.brand} />
@ -1068,7 +1076,7 @@ module.exports = React.createClass({
<div className="mx_MatrixChat_wrapper"> <div className="mx_MatrixChat_wrapper">
{topBar} {topBar}
<div className={bodyClasses}> <div className={bodyClasses}>
<LeftPanel selectedRoom={this.state.currentRoom} collapsed={this.state.collapse_lhs} opacity={this.state.sideOpacity}/> <LeftPanel selectedRoom={this.state.currentRoomId} collapsed={this.state.collapse_lhs} opacity={this.state.sideOpacity}/>
<main className="mx_MatrixChat_middlePanel"> <main className="mx_MatrixChat_middlePanel">
{page_element} {page_element}
</main> </main>

View File

@ -55,9 +55,17 @@ module.exports = React.createClass({
propTypes: { propTypes: {
ConferenceHandler: React.PropTypes.any, ConferenceHandler: React.PropTypes.any,
// the ID for this room (or, if we don't know it, an alias for it) // Either a room ID or room alias for the room to display.
// If the room is being displayed as a result of the user clicking
// on a room alias, the alias should be supplied. Otherwise, a room
// ID should be supplied.
roomAddress: React.PropTypes.string.isRequired, roomAddress: React.PropTypes.string.isRequired,
// If a room alias is passed to roomAddress, a function can be
// provided here that will be called with the ID of the room
// once it has been resolved.
onRoomIdResolved: React.PropTypes.func,
// An object representing a third party invite to join this room // An object representing a third party invite to join this room
// Fields: // Fields:
// * inviteSignUrl (string) The URL used to join this room from an email invite // * inviteSignUrl (string) The URL used to join this room from an email invite
@ -94,24 +102,17 @@ module.exports = React.createClass({
}, },
getInitialState: function() { getInitialState: function() {
var room;
if (this.props.roomAddress[0] == '!') {
room = MatrixClientPeg.get().getRoom(this.props.roomAddress);
} else {
room = MatrixTools.getRoomForAlias(
MatrixClientPeg.get().getRooms(), this.props.roomAddress
);
}
return { return {
room: room, room: null,
roomLoading: !room, roomId: null,
roomLoading: true,
editingRoomSettings: false, editingRoomSettings: false,
uploadingRoomSettings: false, uploadingRoomSettings: false,
numUnreadMessages: 0, numUnreadMessages: 0,
draggingFile: false, draggingFile: false,
searching: false, searching: false,
searchResults: null, searchResults: null,
hasUnsentMessages: this._hasUnsentMessages(room), hasUnsentMessages: false,
callState: null, callState: null,
guestsCanJoin: false, guestsCanJoin: false,
canPeek: false, canPeek: false,
@ -143,6 +144,39 @@ module.exports = React.createClass({
} }
}); });
if (this.props.roomAddress[0] == '#') {
// we always look up the alias from the directory server:
// we want the room that the given alias is pointing to
// right now. We may have joined that alias before but there's
// no guarantee the alias hasn't subsequently been remapped.
MatrixClientPeg.get().getRoomIdForAlias(this.props.roomAddress).done((result) => {
if (this.props.onRoomIdResolved) {
this.props.onRoomIdResolved(result.room_id);
}
var room = MatrixClientPeg.get().getRoom(result.room_id);
this.setState({
room: room,
roomId: result.room_id,
roomLoading: !room,
hasUnsentMessages: this._hasUnsentMessages(room),
}, this._updatePeeking);
}, (err) => {
this.setState({
roomLoading: false,
});
});
} else {
var room = MatrixClientPeg.get().getRoom(this.props.roomAddress);
this.setState({
roomId: this.props.roomAddress,
room: room,
roomLoading: !room,
hasUnsentMessages: this._hasUnsentMessages(room),
}, this._updatePeeking);
}
},
_updatePeeking: 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)
@ -150,10 +184,13 @@ module.exports = React.createClass({
// We can't try to /join because this may implicitly accept invites (!) // 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 // 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!). // succeeds then great, show the preview (but we still may be able to /join!).
if (!this.state.room) { // Note that peeking works by room ID and room ID only, as opposed to joining
console.log("Attempting to peek into room %s", this.props.roomAddress); // 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.props.roomAddress).then((room) => { MatrixClientPeg.get().peekInRoom(this.state.roomId).then((room) => {
this.setState({ this.setState({
room: room, room: room,
roomLoading: false, roomLoading: false,
@ -172,7 +209,7 @@ module.exports = React.createClass({
throw err; throw err;
} }
}).done(); }).done();
} else { } else if (this.state.room) {
MatrixClientPeg.get().stopPeeking(); MatrixClientPeg.get().stopPeeking();
this._onRoomLoaded(this.state.room); this._onRoomLoaded(this.state.room);
} }