Merge branch 'develop' into matthew/preview_urls

This commit is contained in:
Matthew Hodgson 2016-04-03 01:10:33 +01:00
commit f195d2eb24
6 changed files with 70 additions and 25 deletions

View file

@ -99,7 +99,10 @@ module.exports = function (config) {
path.resolve('./test'),
],
query: {
presets: ['react', 'es2015']
// we're using react 5, for consistency with
// the release build, which doesn't use the
// presets.
// presets: ['react', 'es2015'],
},
},
],

View file

@ -30,7 +30,7 @@
"highlight.js": "^8.9.1",
"linkifyjs": "^2.0.0-beta.4",
"marked": "^0.3.5",
"matrix-js-sdk": "^0.5.1",
"matrix-js-sdk": "matrix-org/matrix-js-sdk#develop",
"optimist": "^0.6.1",
"q": "^1.4.1",
"react": "^0.14.2",
@ -40,13 +40,15 @@
"velocity-animate": "^1.2.3",
"velocity-ui-pack": "^1.2.2"
},
"//babelversion": [
"brief experiments with babel6 seems to show that it generates source ",
"maps which confuse chrome and make setting breakpoints tricky. So ",
"let's stick with v5 for now."
],
"devDependencies": {
"babel": "^5.8.23",
"babel-core": "^6.7.4",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babel-runtime": "^6.6.1",
"babel-core": "^5.8.38",
"babel-loader": "^5.4.0",
"expect": "^1.16.0",
"json-loader": "^0.5.3",
"karma": "^0.13.22",

View file

@ -27,7 +27,7 @@ var sanitizeHtmlParams = {
'del', // for markdown
// deliberately no h1/h2 to stop people shouting.
'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol',
'nl', 'li', 'b', 'i', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div',
'nl', 'li', 'b', 'i', 'u', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div',
'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre'
],
allowedAttributes: {

View file

@ -448,6 +448,20 @@ module.exports = React.createClass({
});
},
onMemberAvatarClick: function () {
var avatarUrl = this.props.member.user.avatarUrl;
if(!avatarUrl) return;
var httpUrl = MatrixClientPeg.get().mxcUrlToHttp(avatarUrl);
var ImageView = sdk.getComponent("elements.ImageView");
var params = {
src: httpUrl,
name: this.props.member.name
};
Modal.createDialog(ImageView, params, "mx_Dialog_lightbox");
},
render: function() {
var startChat, kickButton, banButton, muteButton, giveModButton, spinner;
if (this.props.member.userId !== MatrixClientPeg.get().credentials.userId) {
@ -508,7 +522,7 @@ module.exports = React.createClass({
<div className="mx_MemberInfo">
<img className="mx_MemberInfo_cancel" src="img/cancel.svg" width="18" height="18" onClick={this.onCancel}/>
<div className="mx_MemberInfo_avatar">
<MemberAvatar member={this.props.member} width={48} height={48} />
<MemberAvatar onClick={this.onMemberAvatarClick} member={this.props.member} width={48} height={48} />
</div>
<h2>{ this.props.member.name }</h2>

View file

@ -17,6 +17,7 @@ var React = require('react');
var CallHandler = require('../../../CallHandler');
var MatrixClientPeg = require('../../../MatrixClientPeg');
var Modal = require('../../../Modal');
var sdk = require('../../../index');
var dis = require('../../../dispatcher');
@ -47,11 +48,40 @@ module.exports = React.createClass({
onUploadFileSelected: function(ev) {
var files = ev.target.files;
// MessageComposer shouldn't have to rely on its parent passing in a callback to upload a file
if (files && files.length > 0) {
this.props.uploadFile(files[0]);
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
var TintableSvg = sdk.getComponent("elements.TintableSvg");
var fileList = [];
for(var i=0; i<files.length; i++) {
fileList.push(<li>
<TintableSvg src="img/files.svg" width="16" height="16" /> {files[i].name}
</li>);
}
this.refs.uploadInput.value = null;
Modal.createDialog(QuestionDialog, {
title: "Upload Files",
description: (
<div>
<p>Are you sure you want upload the following files?</p>
<ul style={{listStyle: 'none', textAlign: 'left'}}>
{fileList}
</ul>
</div>
),
onFinished: (shouldUpload) => {
if(shouldUpload) {
// MessageComposer shouldn't have to rely on its parent passing in a callback to upload a file
if (files) {
for(var i=0; i<files.length; i++) {
this.props.uploadFile(files[i]);
}
}
}
this.refs.uploadInput.value = null;
}
});
},
onHangupClick: function() {
@ -130,6 +160,7 @@ module.exports = React.createClass({
<TintableSvg src="img/upload.svg" width="19" height="24"/>
<input ref="uploadInput" type="file"
style={uploadInputStyle}
multiple
onChange={this.onUploadFileSelected} />
</div>
);

View file

@ -91,11 +91,13 @@ describe('MessagePanel', function () {
var tiles = TestUtils.scryRenderedComponentsWithType(
mp, sdk.getComponent('rooms.EventTile'));
var tileContainers = tiles.map(function (t) {
return ReactDOM.findDOMNode(t).parentNode;
});
// find the <li> which wraps the read marker
var rm = TestUtils.findRenderedDOMComponentWithClass(mp, 'mx_RoomView_myReadMarker_container');
var eventContainer = ReactDOM.findDOMNode(tiles[4]).parentNode;
expect(rm.previousSibling).toEqual(eventContainer);
expect(rm.previousSibling).toEqual(tileContainers[4]);
// now move the RM
mp = ReactDOM.render(
@ -108,18 +110,11 @@ describe('MessagePanel', function () {
expect(found.length).toEqual(2);
// the first should be the ghost
var ghost = found[0];
eventContainer = ReactDOM.findDOMNode(tiles[4]).parentNode;
expect(ghost.previousSibling).toEqual(eventContainer);
var hr = ghost.children[0];
// the first should be the ghost
eventContainer = ReactDOM.findDOMNode(tiles[4]).parentNode;
expect(found[0].previousSibling).toEqual(eventContainer);
expect(found[0].previousSibling).toEqual(tileContainers[4]);
var hr = found[0].children[0];
// the second should be the real thing
eventContainer = ReactDOM.findDOMNode(tiles[4]).parentNode;
expect(ghost.previousSibling).toEqual(eventContainer);
expect(found[1].previousSibling).toEqual(tileContainers[6]);
// advance the clock, and then let the browser run an animation frame,
// to let the animation start