Merge remote-tracking branch 'upstream/develop' into feature-autocomplete

This commit is contained in:
Aviral Dasgupta
2016-07-03 00:00:02 +05:30
20 changed files with 464 additions and 290 deletions

View File

@@ -24,7 +24,6 @@ var PresetValues = {
Custom: "custom",
};
var q = require('q');
var encryption = require("../../encryption");
var sdk = require('../../index');
module.exports = React.createClass({
@@ -108,17 +107,8 @@ module.exports = React.createClass({
var deferred = cli.createRoom(options);
var response;
if (this.state.encrypt) {
deferred = deferred.then(function(res) {
response = res;
return encryption.enableEncryption(
cli, response.room_id, options.invite
);
}).then(function() {
return q(response) }
);
// TODO
}
this.setState({

View File

@@ -108,10 +108,14 @@ module.exports = React.createClass({
return window.localStorage.getItem("mx_hs_url");
}
else {
return this.props.config.default_hs_url || "https://matrix.org";
return this.getDefaultHsUrl();
}
},
getDefaultHsUrl() {
return this.props.config.default_hs_url || "https://matrix.org";
},
getFallbackHsUrl: function() {
return this.props.config.fallback_hs_url;
},
@@ -126,10 +130,14 @@ module.exports = React.createClass({
return window.localStorage.getItem("mx_is_url");
}
else {
return this.props.config.default_is_url || "https://vector.im"
return this.getDefaultIsUrl();
}
},
getDefaultIsUrl() {
return this.props.config.default_is_url || "https://vector.im";
},
componentWillMount: function() {
this.favicon = new Favico({animation: 'none'});
},
@@ -151,8 +159,8 @@ module.exports = React.createClass({
this.onLoggedIn({
userId: this.props.startingQueryParams.guest_user_id,
accessToken: this.props.startingQueryParams.guest_access_token,
homeserverUrl: this.props.config.default_hs_url,
identityServerUrl: this.props.config.default_is_url,
homeserverUrl: this.getDefaultHsUrl(),
identityServerUrl: this.getDefaultIsUrl(),
guest: true
});
}
@@ -403,10 +411,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 +428,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].roomId });
break;
case 'view_indexed_room':
var allRooms = RoomListSorter.mostRecentActivityFirst(
@@ -431,7 +436,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 +496,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 {boolean=} room_info.show_settings Makes RoomView show the room settings dialog.
// @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.
// @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.invitedEmail 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 +547,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 +564,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 += "/"+room_info.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 +1041,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}
@@ -1109,8 +1121,8 @@ module.exports = React.createClass({
email={this.props.startingQueryParams.email}
username={this.state.upgradeUsername}
guestAccessToken={this.state.guestAccessToken}
defaultHsUrl={this.props.config.default_hs_url}
defaultIsUrl={this.props.config.default_is_url}
defaultHsUrl={this.getDefaultHsUrl()}
defaultIsUrl={this.getDefaultIsUrl()}
brand={this.props.config.brand}
customHsUrl={this.getCurrentHsUrl()}
customIsUrl={this.getCurrentIsUrl()}
@@ -1124,8 +1136,8 @@ module.exports = React.createClass({
} else if (this.state.screen == 'forgot_password') {
return (
<ForgotPassword
defaultHsUrl={this.props.config.default_hs_url}
defaultIsUrl={this.props.config.default_is_url}
defaultHsUrl={this.getDefaultHsUrl()}
defaultIsUrl={this.getDefaultIsUrl()}
customHsUrl={this.getCurrentHsUrl()}
customIsUrl={this.getCurrentIsUrl()}
onComplete={this.onLoginClick}
@@ -1136,13 +1148,13 @@ module.exports = React.createClass({
<Login
onLoggedIn={this.onLoggedIn}
onRegisterClick={this.onRegisterClick}
defaultHsUrl={this.props.config.default_hs_url}
defaultIsUrl={this.props.config.default_is_url}
defaultHsUrl={this.getDefaultHsUrl()}
defaultIsUrl={this.getDefaultIsUrl()}
customHsUrl={this.getCurrentHsUrl()}
customIsUrl={this.getCurrentIsUrl()}
fallbackHsUrl={this.getFallbackHsUrl()}
onForgotPasswordClick={this.onForgotPasswordClick}
onLoginAsGuestClick={this.props.enableGuest && this.props.config && this.props.config.default_hs_url ? this._registerAsGuest.bind(this, true) : undefined}
onLoginAsGuestClick={this.props.enableGuest && this.props.config && this._registerAsGuest.bind(this, true)}
onCancelClick={ this.state.guestCreds ? this.onReturnToGuestClick : null }
/>
);

View File

@@ -119,6 +119,11 @@ module.exports = React.createClass({
guestsCanJoin: false,
canPeek: false,
// error object, as from the matrix client/server API
// If we failed to load information about the room,
// store the error here.
roomLoadError: null,
// this is true if we are fully scrolled-down, and are looking at
// the end of the live timeline. It has the effect of hiding the
// 'scroll to bottom' knob, among a couple of other things.
@@ -161,10 +166,11 @@ module.exports = React.createClass({
roomId: result.room_id,
roomLoading: !room,
hasUnsentMessages: this._hasUnsentMessages(room),
}, this._updatePeeking);
}, this._onHaveRoom);
}, (err) => {
this.setState({
roomLoading: false,
roomLoadError: err,
});
});
} else {
@@ -174,11 +180,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)
@@ -189,29 +195,44 @@ 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 user_is_in_room = null;
if (this.state.room) {
user_is_in_room = this.state.room.hasMembershipState(
MatrixClientPeg.get().credentials.userId, 'join'
);
}
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);
}
@@ -999,7 +1020,7 @@ module.exports = React.createClass({
this.setState({
rejecting: true
});
MatrixClientPeg.get().leave(this.props.roomAddress).done(function() {
MatrixClientPeg.get().leave(this.state.roomId).done(function() {
dis.dispatch({ action: 'view_next_room' });
self.setState({
rejecting: false
@@ -1274,6 +1295,7 @@ module.exports = React.createClass({
// We have no room object for this room, only the ID.
// We've got to this room by following a link, possibly a third party invite.
var room_alias = this.props.roomAddress[0] == '#' ? this.props.roomAddress : null;
return (
<div className="mx_RoomView">
<RoomHeader ref="header"
@@ -1284,7 +1306,8 @@ module.exports = React.createClass({
<div className="mx_RoomView_auxPanel">
<RoomPreviewBar onJoinClick={ this.onJoinButtonClicked }
onRejectClick={ this.onRejectThreepidInviteButtonClicked }
canJoin={ true } canPreview={ false }
canPreview={ false } error={ this.state.roomLoadError }
roomAlias={room_alias}
spinner={this.state.joining}
inviterName={inviterName}
invitedEmail={invitedEmail}
@@ -1322,7 +1345,7 @@ module.exports = React.createClass({
<RoomPreviewBar onJoinClick={ this.onJoinButtonClicked }
onRejectClick={ this.onRejectButtonClicked }
inviterName={ inviterName }
canJoin={ true } canPreview={ false }
canPreview={ false }
spinner={this.state.joining}
room={this.state.room}
/>
@@ -1392,7 +1415,7 @@ module.exports = React.createClass({
invitedEmail = this.props.thirdPartyInvite.invitedEmail;
}
aux = (
<RoomPreviewBar onJoinClick={this.onJoinButtonClicked} canJoin={true}
<RoomPreviewBar onJoinClick={this.onJoinButtonClicked}
onRejectClick={this.onRejectThreepidInviteButtonClicked}
spinner={this.state.joining}
inviterName={inviterName}

View File

@@ -232,7 +232,9 @@ module.exports = React.createClass({displayName: 'Login',
<div className="mx_Login_box">
<LoginHeader />
<div>
<h2>Sign in</h2>
<h2>Sign in
{ loader }
</h2>
{ this.componentForStep(this._getCurrentFlowStep()) }
<ServerConfig ref="serverConfig"
withToggleButton={true}
@@ -244,7 +246,6 @@ module.exports = React.createClass({displayName: 'Login',
onIsUrlChanged={this.onIsUrlChanged}
delayTimeMs={1000}/>
<div className="mx_Login_error">
{ loader }
{ this.state.errorText }
</div>
<a className="mx_Login_create" onClick={this.props.onRegisterClick} href="#">