diff --git a/karma.conf.js b/karma.conf.js
index e59a6c9e15..89437c203a 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -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'],
},
},
],
diff --git a/package.json b/package.json
index 7c4bd714ef..c259700c92 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js
index 82aea0bb76..dbcb59a20a 100644
--- a/src/HtmlUtils.js
+++ b/src/HtmlUtils.js
@@ -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: {
diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js
index 94bd5d6b8f..52313430d4 100644
--- a/src/components/views/rooms/MemberInfo.js
+++ b/src/components/views/rooms/MemberInfo.js
@@ -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({
-
+
{ this.props.member.name }
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js
index 7d5ce473d6..6d26e7884d 100644
--- a/src/components/views/rooms/MessageComposer.js
+++ b/src/components/views/rooms/MessageComposer.js
@@ -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[i].name}
+ );
}
- this.refs.uploadInput.value = null;
+
+ Modal.createDialog(QuestionDialog, {
+ title: "Upload Files",
+ description: (
+
+
Are you sure you want upload the following files?
+
+ {fileList}
+
+
+ ),
+ 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
);
diff --git a/test/components/structures/MessagePanel-test.js b/test/components/structures/MessagePanel-test.js
index 3e984e8134..f775388617 100644
--- a/test/components/structures/MessagePanel-test.js
+++ b/test/components/structures/MessagePanel-test.js
@@ -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
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