Skip to content

Commit 6c35908

Browse files
committed
Add example shwing how to customise, make customising work and document all the ways in which browserify will break and how to work around it being dumb.
1 parent 7a8eae0 commit 6c35908

7 files changed

Lines changed: 160 additions & 10 deletions

File tree

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,10 @@ Note that you may need to restart the CSS builder if you add a new file. Note
3030
that `npm start` builds debug versions of the the javascript and CSS, which are
3131
much larger than the production versions build by the `npm run build` commands.
3232

33+
IMPORTANT: If you customise components in your application (and hence require
34+
react from your app) you must be sure to:
35+
36+
1. Make your app depend on react directly
37+
2. If you `npm link` matrix-react-sdk, manually remove the 'react' directory
38+
from matrix-react-sdk's `node_modules` folder, otherwise browserify will
39+
pull in both copies of react which causes the app to break.

examples/custom/CustomMTextTile.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
Copyright 2015 OpenMarket Ltd
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
'use strict';
18+
19+
var React = require('react');
20+
21+
var MTextTileController = require("matrix-react-sdk/src/controllers/molecules/MTextTile");
22+
23+
module.exports = React.createClass({
24+
displayName: 'MTextTile',
25+
mixins: [MTextTileController],
26+
27+
render: function() {
28+
var content = this.props.mxEvent.getContent();
29+
return (
30+
<span className="mx_MTextTile" onClick={this.onClick}>
31+
{content.body}
32+
</span>
33+
);
34+
},
35+
36+
onClick: function(ev) {
37+
global.alert(this.props.mxEvent.getContent().body);
38+
}
39+
});
40+

examples/custom/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
matrix-react-example
2+
====================
3+
4+
An example of how to use the Matrix React SDK to build a more customised app

examples/custom/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html lang="en" style="height: 100%; overflow: hidden">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Matrix Flux</title>
6+
</head>
7+
<body style="height: 100%; ">
8+
<section id="matrixchat" style="height: 100%; "></section>
9+
<script src="bundle.js"></script>
10+
<link rel="stylesheet" href="node_modules/matrix-react-sdk/bundle.css">
11+
</body>
12+
</html>

examples/custom/index.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
Copyright 2015 OpenMarket Ltd
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
'use strict';
18+
19+
// Remember to make your project depend on react directly as soon as
20+
// you add a require('react') to any file in your project. Do not rely
21+
// on react being pulled in via matrix-react-sdk: browserify breaks
22+
// horribly in this situation and can end up pulling in multiple copies
23+
// of react.
24+
var React = require("react");
25+
26+
// We pull in the component broker first, separately, as we need to replace
27+
// components before the SDK loads.
28+
var ComponenetBroker = require("matrix-react-sdk/src/ComponentBroker");
29+
30+
var CustomMTextTile = require('./CustomMTextTile');
31+
32+
ComponenetBroker.set('molecules/MTextTile', CustomMTextTile);
33+
34+
var MatrixReactSdk = require("matrix-react-sdk");
35+
//var MatrixReactSdk = require("../../src/index");
36+
37+
React.render(
38+
<MatrixReactSdk.MatrixChat />,
39+
document.getElementById('matrixchat')
40+
);

examples/custom/package.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "matrix-react-example",
3+
"version": "0.0.1",
4+
"description": "Example usage of matrix-react-sdk",
5+
"author": "matrix.org",
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/matrix-org/matrix-react-sdk"
9+
},
10+
"license": "Apache-2.0",
11+
"devDependencies": {
12+
"browserify": "^10.2.3",
13+
"envify": "^3.4.0",
14+
"http-server": "^0.8.0",
15+
"matrix-react-sdk": "../../",
16+
"npm-css": "^0.2.3",
17+
"parallelshell": "^1.2.0",
18+
"reactify": "^1.1.1",
19+
"uglify-js": "^2.4.23",
20+
"watchify": "^3.2.1"
21+
},
22+
"scripts": {
23+
"build": "browserify -t [ envify --NODE_ENV production ] -g reactify index.js | uglifyjs -c -m -o bundle.js",
24+
"start": "parallelshell 'watchify -v -d -g reactify index.js -o bundle.js' 'http-server'"
25+
},
26+
"dependencies": {
27+
"react": "^0.13.3"
28+
}
29+
}

src/ComponentBroker.js

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,48 @@ limitations under the License.
1616

1717
'use strict';
1818

19-
var components = {};
20-
2119
function load(name) {
2220
var module = require("../skins/base/views/"+name);
23-
components[name] = module;
2421
return module;
2522
};
2623

27-
module.exports = {
24+
var ComponentBroker = function() {
25+
this.components = {};
26+
};
27+
28+
ComponentBroker.prototype = {
2829
get: function(name) {
29-
if (components[name]) return components[name];
30+
if (this.components[name]) {
31+
return this.components[name];
32+
}
3033

31-
components[name] = load(name);
32-
return components[name];
34+
this.components[name] = load(name);
35+
return this.components[name];
3336
},
3437

3538
set: function(name, module) {
36-
components[name] = module;
39+
this.components[name] = module;
3740
}
3841
};
3942

40-
// Statically require all the components we know about,
41-
// otherwise browserify has no way of knowing what module to include
43+
// We define one Component Broker globally, because the intention is
44+
// very much that it is a singleton. Relying on there only being one
45+
// copy of the module can be dicey and not work as browserify's
46+
// behaviour with multiple copies of files etc. is erratic at best.
47+
// XXX: We can still end up with the same file twice in the resulting
48+
// JS bundle which is nonideal.
49+
if (global.componentBroker === undefined) {
50+
global.componentBroker = new ComponentBroker();
51+
}
52+
module.exports = global.componentBroker;
53+
54+
// We need to tell browserify to include all the components
55+
// by direct require syntax in here, but we don't want them
56+
// to be evaluated in this file because then we wouldn't be
57+
// able to override them. if (0) does this.
4258
// Must be in this file (because the require is file-specific) and
4359
// must be at the end because the components include this file.
60+
if (0) {
4461
require('../skins/base/views/atoms/LogoutButton');
4562
require('../skins/base/views/atoms/EnableNotificationsButton');
4663
require('../skins/base/views/atoms/MessageTimestamp');
@@ -62,3 +79,4 @@ require('../skins/base/views/organisms/RoomList');
6279
require('../skins/base/views/organisms/RoomView');
6380
require('../skins/base/views/templates/Login');
6481
require('../skins/base/views/organisms/Notifier');
82+
}

0 commit comments

Comments
 (0)