Merge branch 'develop' into kegan/archived-rooms
This commit is contained in:
commit
8e4d0c0be7
7 changed files with 111 additions and 11 deletions
|
@ -116,8 +116,17 @@ class Register extends Signup {
|
||||||
|
|
||||||
_tryRegister(authDict) {
|
_tryRegister(authDict) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
var bindEmail;
|
||||||
|
|
||||||
|
if (this.username && this.password) {
|
||||||
|
// only need to bind_email when sending u/p - sending it at other
|
||||||
|
// times clobbers the u/p resulting in M_MISSING_PARAM (password)
|
||||||
|
bindEmail = true;
|
||||||
|
}
|
||||||
|
|
||||||
return MatrixClientPeg.get().register(
|
return MatrixClientPeg.get().register(
|
||||||
this.username, this.password, this.params.sessionId, authDict
|
this.username, this.password, this.params.sessionId, authDict, bindEmail
|
||||||
).then(function(result) {
|
).then(function(result) {
|
||||||
self.credentials = result;
|
self.credentials = result;
|
||||||
self.setStep("COMPLETE");
|
self.setStep("COMPLETE");
|
||||||
|
|
|
@ -9,7 +9,17 @@ function textForMemberEvent(ev) {
|
||||||
) : "";
|
) : "";
|
||||||
switch (ev.getContent().membership) {
|
switch (ev.getContent().membership) {
|
||||||
case 'invite':
|
case 'invite':
|
||||||
return senderName + " invited " + targetName + ".";
|
var threePidContent = ev.getContent().third_party_invite;
|
||||||
|
if (threePidContent) {
|
||||||
|
// TODO: When we have third_party_invite.display_name we should
|
||||||
|
// do this as "$displayname received the invitation from $sender"
|
||||||
|
// or equiv
|
||||||
|
return targetName + " received an invitation from " + senderName +
|
||||||
|
".";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return senderName + " invited " + targetName + ".";
|
||||||
|
}
|
||||||
case 'ban':
|
case 'ban':
|
||||||
return senderName + " banned " + targetName + "." + reason;
|
return senderName + " banned " + targetName + "." + reason;
|
||||||
case 'join':
|
case 'join':
|
||||||
|
@ -101,6 +111,12 @@ function textForCallInviteEvent(event) {
|
||||||
return senderName + " placed a " + type + " call." + supported;
|
return senderName + " placed a " + type + " call." + supported;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function textForThreePidInviteEvent(event) {
|
||||||
|
var senderName = event.sender ? event.sender.name : event.getSender();
|
||||||
|
return senderName + " sent an invitation to " + event.getContent().display_name +
|
||||||
|
" to join the room.";
|
||||||
|
};
|
||||||
|
|
||||||
var handlers = {
|
var handlers = {
|
||||||
'm.room.message': textForMessageEvent,
|
'm.room.message': textForMessageEvent,
|
||||||
'm.room.name': textForRoomNameEvent,
|
'm.room.name': textForRoomNameEvent,
|
||||||
|
@ -109,6 +125,7 @@ var handlers = {
|
||||||
'm.call.invite': textForCallInviteEvent,
|
'm.call.invite': textForCallInviteEvent,
|
||||||
'm.call.answer': textForCallAnswerEvent,
|
'm.call.answer': textForCallAnswerEvent,
|
||||||
'm.call.hangup': textForCallHangupEvent,
|
'm.call.hangup': textForCallHangupEvent,
|
||||||
|
'm.room.third_party_invite': textForThreePidInviteEvent
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -41,7 +41,8 @@ module.exports = React.createClass({
|
||||||
config: React.PropTypes.object.isRequired,
|
config: React.PropTypes.object.isRequired,
|
||||||
ConferenceHandler: React.PropTypes.any,
|
ConferenceHandler: React.PropTypes.any,
|
||||||
onNewScreen: React.PropTypes.func,
|
onNewScreen: React.PropTypes.func,
|
||||||
registrationUrl: React.PropTypes.string
|
registrationUrl: React.PropTypes.string,
|
||||||
|
startingQueryParams: React.PropTypes.object
|
||||||
},
|
},
|
||||||
|
|
||||||
PageTypes: {
|
PageTypes: {
|
||||||
|
@ -75,6 +76,12 @@ module.exports = React.createClass({
|
||||||
return s;
|
return s;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getDefaultProps: function() {
|
||||||
|
return {
|
||||||
|
startingQueryParams: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
this.dispatcherRef = dis.register(this.onAction);
|
this.dispatcherRef = dis.register(this.onAction);
|
||||||
if (this.state.logged_in) {
|
if (this.state.logged_in) {
|
||||||
|
@ -706,6 +713,7 @@ module.exports = React.createClass({
|
||||||
clientSecret={this.state.register_client_secret}
|
clientSecret={this.state.register_client_secret}
|
||||||
sessionId={this.state.register_session_id}
|
sessionId={this.state.register_session_id}
|
||||||
idSid={this.state.register_id_sid}
|
idSid={this.state.register_id_sid}
|
||||||
|
email={this.props.startingQueryParams.email}
|
||||||
hsUrl={this.props.config.default_hs_url}
|
hsUrl={this.props.config.default_hs_url}
|
||||||
isUrl={this.props.config.default_is_url}
|
isUrl={this.props.config.default_is_url}
|
||||||
registrationUrl={this.props.registrationUrl}
|
registrationUrl={this.props.registrationUrl}
|
||||||
|
|
|
@ -40,6 +40,8 @@ var dis = require("../../dispatcher");
|
||||||
var PAGINATE_SIZE = 20;
|
var PAGINATE_SIZE = 20;
|
||||||
var INITIAL_SIZE = 20;
|
var INITIAL_SIZE = 20;
|
||||||
|
|
||||||
|
var DEBUG_SCROLL = false;
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'RoomView',
|
displayName: 'RoomView',
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -151,6 +153,12 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// get the DOM node which has the scrollTop property we care about for our
|
||||||
|
// message panel.
|
||||||
|
//
|
||||||
|
// If the gemini scrollbar is doing its thing, this will be a div within
|
||||||
|
// the message panel (ie, the gemini container); otherwise it will be the
|
||||||
|
// message panel itself.
|
||||||
_getScrollNode: function() {
|
_getScrollNode: function() {
|
||||||
var panel = ReactDOM.findDOMNode(this.refs.messagePanel);
|
var panel = ReactDOM.findDOMNode(this.refs.messagePanel);
|
||||||
if (!panel) return null;
|
if (!panel) return null;
|
||||||
|
@ -309,12 +317,11 @@ module.exports = React.createClass({
|
||||||
if (!this.refs.messagePanel) return;
|
if (!this.refs.messagePanel) return;
|
||||||
|
|
||||||
if (this.state.searchResults) return;
|
if (this.state.searchResults) return;
|
||||||
var scrollState = this.savedScrollState;
|
|
||||||
if (scrollState.atBottom) {
|
if (this.needsScrollReset) {
|
||||||
this.scrollToBottom();
|
if (DEBUG_SCROLL) console.log("Resetting scroll position after tile count change");
|
||||||
} else if (scrollState.lastDisplayedEvent) {
|
this._restoreSavedScrollState();
|
||||||
this.scrollToEvent(scrollState.lastDisplayedEvent,
|
this.needsScrollReset = false;
|
||||||
scrollState.pixelOffset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// have to fill space in case we're accepting an invite
|
// have to fill space in case we're accepting an invite
|
||||||
|
@ -322,6 +329,8 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_paginateCompleted: function() {
|
_paginateCompleted: function() {
|
||||||
|
if (DEBUG_SCROLL) console.log("paginate complete");
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
room: MatrixClientPeg.get().getRoom(this.props.roomId)
|
room: MatrixClientPeg.get().getRoom(this.props.roomId)
|
||||||
});
|
});
|
||||||
|
@ -350,9 +359,11 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
if (this.state.messageCap < this.state.room.timeline.length) {
|
if (this.state.messageCap < this.state.room.timeline.length) {
|
||||||
var cap = Math.min(this.state.messageCap + PAGINATE_SIZE, this.state.room.timeline.length);
|
var cap = Math.min(this.state.messageCap + PAGINATE_SIZE, this.state.room.timeline.length);
|
||||||
|
if (DEBUG_SCROLL) console.log("winding back message cap to", cap);
|
||||||
this.setState({messageCap: cap});
|
this.setState({messageCap: cap});
|
||||||
} else {
|
} else {
|
||||||
var cap = this.state.messageCap + PAGINATE_SIZE;
|
var cap = this.state.messageCap + PAGINATE_SIZE;
|
||||||
|
if (DEBUG_SCROLL) console.log("starting paginate to cap", cap);
|
||||||
this.setState({messageCap: cap, paginating: true});
|
this.setState({messageCap: cap, paginating: true});
|
||||||
MatrixClientPeg.get().scrollback(this.state.room, PAGINATE_SIZE).finally(this._paginateCompleted).done();
|
MatrixClientPeg.get().scrollback(this.state.room, PAGINATE_SIZE).finally(this._paginateCompleted).done();
|
||||||
return true;
|
return true;
|
||||||
|
@ -387,8 +398,33 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onMessageListScroll: function(ev) {
|
onMessageListScroll: function(ev) {
|
||||||
|
var sn = this._getScrollNode();
|
||||||
|
if (DEBUG_SCROLL) console.log("Scroll event: offset now:", sn.scrollTop, "recentEventScroll:", this.recentEventScroll);
|
||||||
|
|
||||||
|
// Sometimes we see attempts to write to scrollTop essentially being
|
||||||
|
// ignored. (Or rather, it is successfully written, but on the next
|
||||||
|
// scroll event, it's been reset again).
|
||||||
|
//
|
||||||
|
// This was observed on Chrome 47, when scrolling using the trackpad in OS
|
||||||
|
// X Yosemite. Can't reproduce on El Capitan. Our theory is that this is
|
||||||
|
// due to Chrome not being able to cope with the scroll offset being reset
|
||||||
|
// while a two-finger drag is in progress.
|
||||||
|
//
|
||||||
|
// By way of a workaround, we detect this situation and just keep
|
||||||
|
// resetting scrollTop until we see the scroll node have the right
|
||||||
|
// value.
|
||||||
|
if (this.recentEventScroll !== undefined) {
|
||||||
|
if(sn.scrollTop < this.recentEventScroll-200) {
|
||||||
|
console.log("Working around vector-im/vector-web#528");
|
||||||
|
this._restoreSavedScrollState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.recentEventScroll = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.refs.messagePanel && !this.state.searchResults) {
|
if (this.refs.messagePanel && !this.state.searchResults) {
|
||||||
this.savedScrollState = this._calculateScrollState();
|
this.savedScrollState = this._calculateScrollState();
|
||||||
|
if (DEBUG_SCROLL) console.log("Saved scroll state", this.savedScrollState);
|
||||||
if (this.savedScrollState.atBottom && this.state.numUnreadMessages != 0) {
|
if (this.savedScrollState.atBottom && this.state.numUnreadMessages != 0) {
|
||||||
this.setState({numUnreadMessages: 0});
|
this.setState({numUnreadMessages: 0});
|
||||||
}
|
}
|
||||||
|
@ -647,6 +683,11 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
if (count != this.lastEventTileCount) {
|
||||||
|
if (DEBUG_SCROLL) console.log("Queuing scroll reset (event count changed; now "+count+"; was "+this.lastEventTileCount+")");
|
||||||
|
this.needsScrollReset = true;
|
||||||
|
}
|
||||||
|
this.lastEventTileCount = count;
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -876,6 +917,7 @@ module.exports = React.createClass({
|
||||||
var scrollNode = this._getScrollNode();
|
var scrollNode = this._getScrollNode();
|
||||||
if (!scrollNode) return;
|
if (!scrollNode) return;
|
||||||
scrollNode.scrollTop = scrollNode.scrollHeight;
|
scrollNode.scrollTop = scrollNode.scrollHeight;
|
||||||
|
if (DEBUG_SCROLL) console.log("Scrolled to bottom; offset now", scrollNode.scrollTop);
|
||||||
},
|
},
|
||||||
|
|
||||||
// scroll the event view to put the given event at the bottom.
|
// scroll the event view to put the given event at the bottom.
|
||||||
|
@ -926,7 +968,28 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
var wrapperRect = ReactDOM.findDOMNode(messageWrapper).getBoundingClientRect();
|
var wrapperRect = ReactDOM.findDOMNode(messageWrapper).getBoundingClientRect();
|
||||||
var boundingRect = node.getBoundingClientRect();
|
var boundingRect = node.getBoundingClientRect();
|
||||||
scrollNode.scrollTop += boundingRect.bottom + pixelOffset - wrapperRect.bottom;
|
var scrollDelta = boundingRect.bottom + pixelOffset - wrapperRect.bottom;
|
||||||
|
if(scrollDelta != 0) {
|
||||||
|
scrollNode.scrollTop += scrollDelta;
|
||||||
|
|
||||||
|
// see the comments in onMessageListScroll regarding recentEventScroll
|
||||||
|
this.recentEventScroll = scrollNode.scrollTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DEBUG_SCROLL) {
|
||||||
|
console.log("Scrolled to event", eventId, "+", pixelOffset+":", scrollNode.scrollTop, "(delta: "+scrollDelta+")");
|
||||||
|
console.log("recentEventScroll now "+this.recentEventScroll);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_restoreSavedScrollState: function() {
|
||||||
|
var scrollState = this.savedScrollState;
|
||||||
|
if (scrollState.atBottom) {
|
||||||
|
this.scrollToBottom();
|
||||||
|
} else if (scrollState.lastDisplayedEvent) {
|
||||||
|
this.scrollToEvent(scrollState.lastDisplayedEvent,
|
||||||
|
scrollState.pixelOffset);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_calculateScrollState: function() {
|
_calculateScrollState: function() {
|
||||||
|
|
|
@ -39,6 +39,7 @@ module.exports = React.createClass({
|
||||||
idSid: React.PropTypes.string,
|
idSid: React.PropTypes.string,
|
||||||
hsUrl: React.PropTypes.string,
|
hsUrl: React.PropTypes.string,
|
||||||
isUrl: React.PropTypes.string,
|
isUrl: React.PropTypes.string,
|
||||||
|
email: React.PropTypes.string,
|
||||||
// registration shouldn't know or care how login is done.
|
// registration shouldn't know or care how login is done.
|
||||||
onLoginClick: React.PropTypes.func.isRequired
|
onLoginClick: React.PropTypes.func.isRequired
|
||||||
},
|
},
|
||||||
|
@ -185,6 +186,7 @@ module.exports = React.createClass({
|
||||||
registerStep = (
|
registerStep = (
|
||||||
<RegistrationForm
|
<RegistrationForm
|
||||||
showEmail={true}
|
showEmail={true}
|
||||||
|
defaultEmail={this.props.email}
|
||||||
minPasswordLength={MIN_PASSWORD_LENGTH}
|
minPasswordLength={MIN_PASSWORD_LENGTH}
|
||||||
onError={this.onFormValidationFailed}
|
onError={this.onFormValidationFailed}
|
||||||
onRegisterClick={this.onFormSubmit} />
|
onRegisterClick={this.onFormSubmit} />
|
||||||
|
|
|
@ -44,6 +44,7 @@ var eventTileTypes = {
|
||||||
'm.call.hangup' : 'messages.TextualEvent',
|
'm.call.hangup' : 'messages.TextualEvent',
|
||||||
'm.room.name' : 'messages.TextualEvent',
|
'm.room.name' : 'messages.TextualEvent',
|
||||||
'm.room.topic' : 'messages.TextualEvent',
|
'm.room.topic' : 'messages.TextualEvent',
|
||||||
|
'm.room.third_party_invite': 'messages.TextualEvent'
|
||||||
};
|
};
|
||||||
|
|
||||||
var MAX_READ_AVATARS = 5;
|
var MAX_READ_AVATARS = 5;
|
||||||
|
|
|
@ -265,7 +265,7 @@ module.exports = React.createClass({
|
||||||
collapsed={ self.props.collapsed } />
|
collapsed={ self.props.collapsed } />
|
||||||
|
|
||||||
<RoomSubList list={ self.state.lists['im.vector.fake.recent'] }
|
<RoomSubList list={ self.state.lists['im.vector.fake.recent'] }
|
||||||
label="Conversations"
|
label="Rooms"
|
||||||
editable={ true }
|
editable={ true }
|
||||||
verb="restore"
|
verb="restore"
|
||||||
order="recent"
|
order="recent"
|
||||||
|
|
Loading…
Reference in a new issue