Merge pull request #552 from matrix-org/rav/event_tile_withmatrixclient
Update EventTile to use WithMatrixClient instead of MatrixClientPeg
This commit is contained in:
commit
ec999f6fa1
4 changed files with 108 additions and 63 deletions
|
@ -21,8 +21,8 @@ var classNames = require("classnames");
|
||||||
var Modal = require('../../../Modal');
|
var Modal = require('../../../Modal');
|
||||||
|
|
||||||
var sdk = require('../../../index');
|
var sdk = require('../../../index');
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg')
|
|
||||||
var TextForEvent = require('../../../TextForEvent');
|
var TextForEvent = require('../../../TextForEvent');
|
||||||
|
import WithMatrixClient from '../../../wrappers/WithMatrixClient';
|
||||||
|
|
||||||
var ContextualMenu = require('../../structures/ContextualMenu');
|
var ContextualMenu = require('../../structures/ContextualMenu');
|
||||||
var dispatcher = require("../../../dispatcher");
|
var dispatcher = require("../../../dispatcher");
|
||||||
|
@ -63,22 +63,13 @@ var MAX_READ_AVATARS = 5;
|
||||||
// | '--------------------------------------' |
|
// | '--------------------------------------' |
|
||||||
// '----------------------------------------------------------'
|
// '----------------------------------------------------------'
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = WithMatrixClient(React.createClass({
|
||||||
displayName: 'EventTile',
|
displayName: 'EventTile',
|
||||||
|
|
||||||
statics: {
|
|
||||||
haveTileForEvent: function(e) {
|
|
||||||
if (e.isRedacted()) return false;
|
|
||||||
if (eventTileTypes[e.getType()] == undefined) return false;
|
|
||||||
if (eventTileTypes[e.getType()] == 'messages.TextualEvent') {
|
|
||||||
return TextForEvent.textForEvent(e) !== '';
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
/* MatrixClient instance for sender verification etc */
|
||||||
|
matrixClient: React.PropTypes.object.isRequired,
|
||||||
|
|
||||||
/* the MatrixEvent to show */
|
/* the MatrixEvent to show */
|
||||||
mxEvent: React.PropTypes.object.isRequired,
|
mxEvent: React.PropTypes.object.isRequired,
|
||||||
|
|
||||||
|
@ -153,7 +144,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
this._suppressReadReceiptAnimation = false;
|
this._suppressReadReceiptAnimation = false;
|
||||||
MatrixClientPeg.get().on("deviceVerificationChanged",
|
this.props.matrixClient.on("deviceVerificationChanged",
|
||||||
this.onDeviceVerificationChanged);
|
this.onDeviceVerificationChanged);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -176,11 +167,9 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
var client = MatrixClientPeg.get();
|
var client = this.props.matrixClient;
|
||||||
if (client) {
|
client.removeListener("deviceVerificationChanged",
|
||||||
client.removeListener("deviceVerificationChanged",
|
this.onDeviceVerificationChanged);
|
||||||
this.onDeviceVerificationChanged);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onDeviceVerificationChanged: function(userId, device) {
|
onDeviceVerificationChanged: function(userId, device) {
|
||||||
|
@ -193,7 +182,7 @@ module.exports = React.createClass({
|
||||||
var verified = null;
|
var verified = null;
|
||||||
|
|
||||||
if (mxEvent.isEncrypted()) {
|
if (mxEvent.isEncrypted()) {
|
||||||
verified = MatrixClientPeg.get().isEventSenderVerified(mxEvent);
|
verified = this.props.matrixClient.isEventSenderVerified(mxEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -246,11 +235,11 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
shouldHighlight: function() {
|
shouldHighlight: function() {
|
||||||
var actions = MatrixClientPeg.get().getPushActionsForEvent(this.props.mxEvent);
|
var actions = this.props.matrixClient.getPushActionsForEvent(this.props.mxEvent);
|
||||||
if (!actions || !actions.tweaks) { return false; }
|
if (!actions || !actions.tweaks) { return false; }
|
||||||
|
|
||||||
// don't show self-highlights from another of our clients
|
// don't show self-highlights from another of our clients
|
||||||
if (this.props.mxEvent.getSender() === MatrixClientPeg.get().credentials.userId)
|
if (this.props.mxEvent.getSender() === this.props.matrixClient.credentials.userId)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -387,7 +376,7 @@ module.exports = React.createClass({
|
||||||
throw new Error("Event type not supported");
|
throw new Error("Event type not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
var e2eEnabled = MatrixClientPeg.get().isRoomEncrypted(this.props.mxEvent.getRoomId());
|
var e2eEnabled = this.props.matrixClient.isRoomEncrypted(this.props.mxEvent.getRoomId());
|
||||||
var isSending = (['sending', 'queued', 'encrypting'].indexOf(this.props.eventSendStatus) !== -1);
|
var isSending = (['sending', 'queued', 'encrypting'].indexOf(this.props.eventSendStatus) !== -1);
|
||||||
|
|
||||||
var classes = classNames({
|
var classes = classNames({
|
||||||
|
@ -481,7 +470,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.tileShape === "notif") {
|
if (this.props.tileShape === "notif") {
|
||||||
var room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
var room = this.props.matrixClient.getRoom(this.props.mxEvent.getRoomId());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes}>
|
<div className={classes}>
|
||||||
|
@ -554,4 +543,14 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
}));
|
||||||
|
|
||||||
|
module.exports.haveTileForEvent = function(e) {
|
||||||
|
if (e.isRedacted()) return false;
|
||||||
|
if (eventTileTypes[e.getType()] == undefined) return false;
|
||||||
|
if (eventTileTypes[e.getType()] == 'messages.TextualEvent') {
|
||||||
|
return TextForEvent.textForEvent(e) !== '';
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -20,30 +20,44 @@ var TestUtils = require('react-addons-test-utils');
|
||||||
var expect = require('expect');
|
var expect = require('expect');
|
||||||
|
|
||||||
var sdk = require('matrix-react-sdk');
|
var sdk = require('matrix-react-sdk');
|
||||||
var MatrixClientPeg = require('MatrixClientPeg');
|
|
||||||
|
|
||||||
var MessagePanel = sdk.getComponent('structures.MessagePanel');
|
var MessagePanel = sdk.getComponent('structures.MessagePanel');
|
||||||
|
|
||||||
var test_utils = require('test-utils');
|
var test_utils = require('test-utils');
|
||||||
var mockclock = require('mock-clock');
|
var mockclock = require('mock-clock');
|
||||||
|
|
||||||
|
var client;
|
||||||
|
|
||||||
|
// wrap MessagePanel with a component which provides the MatrixClient in the context.
|
||||||
|
const WrappedMessagePanel = React.createClass({
|
||||||
|
childContextTypes: {
|
||||||
|
matrixClient: React.PropTypes.object,
|
||||||
|
},
|
||||||
|
|
||||||
|
getChildContext: function() {
|
||||||
|
return {
|
||||||
|
matrixClient: client,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return <MessagePanel {...this.props} />;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
describe('MessagePanel', function () {
|
describe('MessagePanel', function () {
|
||||||
var sandbox;
|
|
||||||
var clock = mockclock.clock();
|
var clock = mockclock.clock();
|
||||||
var realSetTimeout = window.setTimeout;
|
var realSetTimeout = window.setTimeout;
|
||||||
var events = mkEvents();
|
var events = mkEvents();
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
test_utils.beforeEach(this);
|
test_utils.beforeEach(this);
|
||||||
sandbox = test_utils.stubClient(sandbox);
|
client = test_utils.createTestClient();
|
||||||
|
|
||||||
var client = MatrixClientPeg.get();
|
|
||||||
client.credentials = {userId: '@me:here'};
|
client.credentials = {userId: '@me:here'};
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
clock.uninstall();
|
clock.uninstall();
|
||||||
sandbox.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function mkEvents() {
|
function mkEvents() {
|
||||||
|
@ -61,7 +75,7 @@ describe('MessagePanel', function () {
|
||||||
|
|
||||||
it('should show the events', function() {
|
it('should show the events', function() {
|
||||||
var res = TestUtils.renderIntoDocument(
|
var res = TestUtils.renderIntoDocument(
|
||||||
<MessagePanel className="cls" events={events} />
|
<WrappedMessagePanel className="cls" events={events} />
|
||||||
);
|
);
|
||||||
|
|
||||||
// just check we have the right number of tiles for now
|
// just check we have the right number of tiles for now
|
||||||
|
@ -72,7 +86,7 @@ describe('MessagePanel', function () {
|
||||||
|
|
||||||
it('should show the read-marker in the right place', function() {
|
it('should show the read-marker in the right place', function() {
|
||||||
var res = TestUtils.renderIntoDocument(
|
var res = TestUtils.renderIntoDocument(
|
||||||
<MessagePanel className="cls" events={events} readMarkerEventId={events[4].getId()}
|
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[4].getId()}
|
||||||
readMarkerVisible={true} />
|
readMarkerVisible={true} />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -96,7 +110,7 @@ describe('MessagePanel', function () {
|
||||||
|
|
||||||
// first render with the RM in one place
|
// first render with the RM in one place
|
||||||
var mp = ReactDOM.render(
|
var mp = ReactDOM.render(
|
||||||
<MessagePanel className="cls" events={events} readMarkerEventId={events[4].getId()}
|
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[4].getId()}
|
||||||
readMarkerVisible={true}
|
readMarkerVisible={true}
|
||||||
/>, parentDiv);
|
/>, parentDiv);
|
||||||
|
|
||||||
|
@ -112,7 +126,7 @@ describe('MessagePanel', function () {
|
||||||
|
|
||||||
// now move the RM
|
// now move the RM
|
||||||
mp = ReactDOM.render(
|
mp = ReactDOM.render(
|
||||||
<MessagePanel className="cls" events={events} readMarkerEventId={events[6].getId()}
|
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[6].getId()}
|
||||||
readMarkerVisible={true}
|
readMarkerVisible={true}
|
||||||
/>, parentDiv);
|
/>, parentDiv);
|
||||||
|
|
||||||
|
@ -147,7 +161,7 @@ describe('MessagePanel', function () {
|
||||||
|
|
||||||
// first render with the RM in one place
|
// first render with the RM in one place
|
||||||
var mp = ReactDOM.render(
|
var mp = ReactDOM.render(
|
||||||
<MessagePanel className="cls" events={events} readMarkerEventId={events[4].getId()}
|
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[4].getId()}
|
||||||
readMarkerVisible={true}
|
readMarkerVisible={true}
|
||||||
/>, parentDiv);
|
/>, parentDiv);
|
||||||
|
|
||||||
|
@ -159,7 +173,7 @@ describe('MessagePanel', function () {
|
||||||
|
|
||||||
// now move the RM
|
// now move the RM
|
||||||
mp = ReactDOM.render(
|
mp = ReactDOM.render(
|
||||||
<MessagePanel className="cls" events={events} readMarkerEventId={events[6].getId()}
|
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[6].getId()}
|
||||||
readMarkerVisible={true}
|
readMarkerVisible={true}
|
||||||
/>, parentDiv);
|
/>, parentDiv);
|
||||||
|
|
||||||
|
@ -175,7 +189,7 @@ describe('MessagePanel', function () {
|
||||||
|
|
||||||
// and move the RM again
|
// and move the RM again
|
||||||
mp = ReactDOM.render(
|
mp = ReactDOM.render(
|
||||||
<MessagePanel className="cls" events={events} readMarkerEventId={events[8].getId()}
|
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[8].getId()}
|
||||||
readMarkerVisible={true}
|
readMarkerVisible={true}
|
||||||
/>, parentDiv);
|
/>, parentDiv);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,24 @@ var test_utils = require('test-utils');
|
||||||
var ROOM_ID = '!room:localhost';
|
var ROOM_ID = '!room:localhost';
|
||||||
var USER_ID = '@me:localhost';
|
var USER_ID = '@me:localhost';
|
||||||
|
|
||||||
|
// wrap TimelinePanel with a component which provides the MatrixClient in the context.
|
||||||
|
const WrappedTimelinePanel = React.createClass({
|
||||||
|
childContextTypes: {
|
||||||
|
matrixClient: React.PropTypes.object,
|
||||||
|
},
|
||||||
|
|
||||||
|
getChildContext: function() {
|
||||||
|
return {
|
||||||
|
matrixClient: peg.get(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return <TimelinePanel ref="panel" {...this.props} />;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('TimelinePanel', function() {
|
describe('TimelinePanel', function() {
|
||||||
var sandbox;
|
var sandbox;
|
||||||
var timelineSet;
|
var timelineSet;
|
||||||
|
@ -105,11 +123,12 @@ describe('TimelinePanel', function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var scrollDefer;
|
var scrollDefer;
|
||||||
var panel = ReactDOM.render(
|
var rendered = ReactDOM.render(
|
||||||
<TimelinePanel timelineSet={timelineSet} onScroll={() => {scrollDefer.resolve()}}
|
<WrappedTimelinePanel timelineSet={timelineSet} onScroll={() => {scrollDefer.resolve()}}
|
||||||
/>,
|
/>,
|
||||||
parentDiv,
|
parentDiv,
|
||||||
);
|
);
|
||||||
|
var panel = rendered.refs.panel;
|
||||||
var scrollingDiv = ReactTestUtils.findRenderedDOMComponentWithClass(
|
var scrollingDiv = ReactTestUtils.findRenderedDOMComponentWithClass(
|
||||||
panel, "gm-scroll-view");
|
panel, "gm-scroll-view");
|
||||||
|
|
||||||
|
@ -188,10 +207,11 @@ describe('TimelinePanel', function() {
|
||||||
return q(true);
|
return q(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
var panel = ReactDOM.render(
|
var rendered = ReactDOM.render(
|
||||||
<TimelinePanel timelineSet={timelineSet}/>,
|
<WrappedTimelinePanel timelineSet={timelineSet}/>,
|
||||||
parentDiv
|
parentDiv
|
||||||
);
|
);
|
||||||
|
var panel = rendered.refs.panel;
|
||||||
|
|
||||||
var messagePanel = ReactTestUtils.findRenderedComponentWithType(
|
var messagePanel = ReactTestUtils.findRenderedComponentWithType(
|
||||||
panel, sdk.getComponent('structures.MessagePanel'));
|
panel, sdk.getComponent('structures.MessagePanel'));
|
||||||
|
@ -236,14 +256,14 @@ describe('TimelinePanel', function() {
|
||||||
console.log("added events to timeline");
|
console.log("added events to timeline");
|
||||||
|
|
||||||
var scrollDefer;
|
var scrollDefer;
|
||||||
var panel = ReactDOM.render(
|
var rendered = ReactDOM.render(
|
||||||
<TimelinePanel timelineSet={timelineSet} onScroll={() => {scrollDefer.resolve()}}
|
<WrappedTimelinePanel timelineSet={timelineSet} onScroll={() => {scrollDefer.resolve()}}
|
||||||
timelineCap={TIMELINE_CAP}
|
timelineCap={TIMELINE_CAP}
|
||||||
/>,
|
/>,
|
||||||
parentDiv
|
parentDiv
|
||||||
);
|
);
|
||||||
console.log("TimelinePanel rendered");
|
console.log("TimelinePanel rendered");
|
||||||
|
var panel = rendered.refs.panel;
|
||||||
var messagePanel = ReactTestUtils.findRenderedComponentWithType(
|
var messagePanel = ReactTestUtils.findRenderedComponentWithType(
|
||||||
panel, sdk.getComponent('structures.MessagePanel'));
|
panel, sdk.getComponent('structures.MessagePanel'));
|
||||||
var scrollingDiv = ReactTestUtils.findRenderedDOMComponentWithClass(
|
var scrollingDiv = ReactTestUtils.findRenderedDOMComponentWithClass(
|
||||||
|
|
|
@ -24,23 +24,49 @@ export function beforeEach(context) {
|
||||||
* Stub out the MatrixClient, and configure the MatrixClientPeg object to
|
* Stub out the MatrixClient, and configure the MatrixClientPeg object to
|
||||||
* return it when get() is called.
|
* return it when get() is called.
|
||||||
*
|
*
|
||||||
|
* TODO: once the components are updated to get their MatrixClients from
|
||||||
|
* the react context, we can get rid of this and just inject a test client
|
||||||
|
* via the context instead.
|
||||||
|
*
|
||||||
* @returns {sinon.Sandbox}; remember to call sandbox.restore afterwards.
|
* @returns {sinon.Sandbox}; remember to call sandbox.restore afterwards.
|
||||||
*/
|
*/
|
||||||
export function stubClient() {
|
export function stubClient() {
|
||||||
var sandbox = sinon.sandbox.create();
|
var sandbox = sinon.sandbox.create();
|
||||||
|
|
||||||
var client = {
|
var client = createTestClient();
|
||||||
|
|
||||||
|
// stub out the methods in MatrixClientPeg
|
||||||
|
//
|
||||||
|
// 'sandbox.restore()' doesn't work correctly on inherited methods,
|
||||||
|
// so we do this for each method
|
||||||
|
var methods = ['get', 'unset', 'replaceUsingCreds'];
|
||||||
|
for (var i = 0; i < methods.length; i++) {
|
||||||
|
sandbox.stub(peg, methods[i]);
|
||||||
|
}
|
||||||
|
// MatrixClientPeg.get() is called a /lot/, so implement it with our own
|
||||||
|
// fast stub function rather than a sinon stub
|
||||||
|
peg.get = function() { return client; };
|
||||||
|
return sandbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a stubbed-out MatrixClient
|
||||||
|
*
|
||||||
|
* @returns {object} MatrixClient stub
|
||||||
|
*/
|
||||||
|
export function createTestClient() {
|
||||||
|
return {
|
||||||
getHomeserverUrl: sinon.stub(),
|
getHomeserverUrl: sinon.stub(),
|
||||||
getIdentityServerUrl: sinon.stub(),
|
getIdentityServerUrl: sinon.stub(),
|
||||||
|
|
||||||
getPushActionsForEvent: sinon.stub(),
|
getPushActionsForEvent: sinon.stub(),
|
||||||
getRoom: sinon.stub().returns(this.mkStubRoom()),
|
getRoom: sinon.stub().returns(mkStubRoom()),
|
||||||
getRooms: sinon.stub().returns([]),
|
getRooms: sinon.stub().returns([]),
|
||||||
loginFlows: sinon.stub(),
|
loginFlows: sinon.stub(),
|
||||||
on: sinon.stub(),
|
on: sinon.stub(),
|
||||||
removeListener: sinon.stub(),
|
removeListener: sinon.stub(),
|
||||||
isRoomEncrypted: sinon.stub().returns(false),
|
isRoomEncrypted: sinon.stub().returns(false),
|
||||||
peekInRoom: sinon.stub().returns(q(this.mkStubRoom())),
|
peekInRoom: sinon.stub().returns(q(mkStubRoom())),
|
||||||
|
|
||||||
paginateEventTimeline: sinon.stub().returns(q()),
|
paginateEventTimeline: sinon.stub().returns(q()),
|
||||||
sendReadReceipt: sinon.stub().returns(q()),
|
sendReadReceipt: sinon.stub().returns(q()),
|
||||||
|
@ -59,22 +85,8 @@ export function stubClient() {
|
||||||
sendHtmlMessage: () => q({}),
|
sendHtmlMessage: () => q({}),
|
||||||
getSyncState: () => "SYNCING",
|
getSyncState: () => "SYNCING",
|
||||||
};
|
};
|
||||||
|
|
||||||
// stub out the methods in MatrixClientPeg
|
|
||||||
//
|
|
||||||
// 'sandbox.restore()' doesn't work correctly on inherited methods,
|
|
||||||
// so we do this for each method
|
|
||||||
var methods = ['get', 'unset', 'replaceUsingCreds'];
|
|
||||||
for (var i = 0; i < methods.length; i++) {
|
|
||||||
sandbox.stub(peg, methods[i]);
|
|
||||||
}
|
|
||||||
// MatrixClientPeg.get() is called a /lot/, so implement it with our own
|
|
||||||
// fast stub function rather than a sinon stub
|
|
||||||
peg.get = function() { return client; };
|
|
||||||
return sandbox;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an Event.
|
* Create an Event.
|
||||||
* @param {Object} opts Values for the event.
|
* @param {Object} opts Values for the event.
|
||||||
|
|
Loading…
Reference in a new issue