├── .meteor
├── .finished-upgraders
├── .gitignore
├── .id
├── packages
├── platforms
├── release
└── versions
├── Message.jsx
├── MessageList.jsx
├── README.md
├── demo.css
├── demo.html
├── demo.jsx
└── styles.css
/.meteor/.finished-upgraders:
--------------------------------------------------------------------------------
1 | # This file contains information which helps Meteor properly upgrade your
2 | # app when you run 'meteor update'. You should check it into version control
3 | # with your project.
4 |
5 | notices-for-0.9.0
6 | notices-for-0.9.1
7 | 0.9.4-platform-file
8 | notices-for-facebook-graph-api-2
9 | 1.2.0-standard-minifiers-package
10 | 1.2.0-meteor-platform-split
11 | 1.2.0-cordova-changes
12 | 1.2.0-breaking-changes
13 |
--------------------------------------------------------------------------------
/.meteor/.gitignore:
--------------------------------------------------------------------------------
1 | local
2 |
--------------------------------------------------------------------------------
/.meteor/.id:
--------------------------------------------------------------------------------
1 | # This file contains a token that is unique to your project.
2 | # Check it into your repository along with the rest of this directory.
3 | # It can be used for purposes such as:
4 | # - ensuring you don't accidentally deploy one app on top of another
5 | # - providing package authors with aggregated statistics
6 |
7 | 167vt1x1eciiy71hmasve
8 |
--------------------------------------------------------------------------------
/.meteor/packages:
--------------------------------------------------------------------------------
1 | # Meteor packages used by this project, one per line.
2 | # Check this file (and the other files in this directory) into your repository.
3 | #
4 | # 'meteor add' and 'meteor remove' will edit this file for you,
5 | # but you can also edit it by hand.
6 |
7 | meteor-base # Packages every Meteor app needs to have
8 | mobile-experience # Packages for a great mobile UX
9 | mongo # The database Meteor supports right now
10 | blaze-html-templates # Compile .html files into Meteor Blaze views
11 | session # Client-side reactive dictionary for your app
12 | jquery # Helpful client-side library
13 | tracker # Meteor's client-side reactive programming library
14 |
15 | standard-minifiers # JS/CSS minifiers run for production mode
16 | es5-shim # ECMAScript 5 compatibility for older browsers.
17 | ecmascript # Enable ECMAScript2015+ syntax in app code
18 |
19 | autopublish # Publish all data to the clients (for prototyping)
20 | insecure # Allow all DB writes from clients (for prototyping)
21 | react
22 | momentjs:moment
23 |
--------------------------------------------------------------------------------
/.meteor/platforms:
--------------------------------------------------------------------------------
1 | server
2 | browser
3 |
--------------------------------------------------------------------------------
/.meteor/release:
--------------------------------------------------------------------------------
1 | METEOR@1.2.1
2 |
--------------------------------------------------------------------------------
/.meteor/versions:
--------------------------------------------------------------------------------
1 | autopublish@1.0.4
2 | autoupdate@1.2.4
3 | babel-compiler@5.8.24_1
4 | babel-runtime@0.1.4
5 | base64@1.0.4
6 | binary-heap@1.0.4
7 | blaze@2.1.3
8 | blaze-html-templates@1.0.1
9 | blaze-tools@1.0.4
10 | boilerplate-generator@1.0.4
11 | caching-compiler@1.0.0
12 | caching-html-compiler@1.0.2
13 | callback-hook@1.0.4
14 | check@1.1.0
15 | coffeescript@1.0.11
16 | cosmos:browserify@0.9.3
17 | ddp@1.2.2
18 | ddp-client@1.2.1
19 | ddp-common@1.2.2
20 | ddp-server@1.2.2
21 | deps@1.0.9
22 | diff-sequence@1.0.1
23 | ecmascript@0.1.6
24 | ecmascript-runtime@0.2.6
25 | ejson@1.0.7
26 | es5-shim@4.1.14
27 | fastclick@1.0.7
28 | geojson-utils@1.0.4
29 | hot-code-push@1.0.0
30 | html-tools@1.0.5
31 | htmljs@1.0.5
32 | http@1.1.1
33 | id-map@1.0.4
34 | insecure@1.0.4
35 | jquery@1.11.4
36 | jsx@0.2.3
37 | launch-screen@1.0.4
38 | livedata@1.0.15
39 | logging@1.0.8
40 | meteor@1.1.10
41 | meteor-base@1.0.1
42 | minifiers@1.1.7
43 | minimongo@1.0.10
44 | mobile-experience@1.0.1
45 | mobile-status-bar@1.0.6
46 | momentjs:moment@2.11.1
47 | mongo@1.1.3
48 | mongo-id@1.0.1
49 | npm-mongo@1.4.39_1
50 | observe-sequence@1.0.7
51 | ordered-dict@1.0.4
52 | promise@0.5.1
53 | random@1.0.5
54 | react@0.14.3
55 | react-meteor-data@0.2.4
56 | react-runtime@0.14.4
57 | react-runtime-dev@0.14.4
58 | react-runtime-prod@0.14.4
59 | reactive-dict@1.1.3
60 | reactive-var@1.0.6
61 | reload@1.1.4
62 | retry@1.0.4
63 | routepolicy@1.0.6
64 | session@1.1.1
65 | spacebars@1.0.7
66 | spacebars-compiler@1.0.7
67 | standard-minifiers@1.0.2
68 | templating@1.1.5
69 | templating-tools@1.0.0
70 | tracker@1.0.9
71 | ui@1.0.8
72 | underscore@1.0.4
73 | url@1.0.5
74 | webapp@1.2.3
75 | webapp-hashing@1.0.5
76 |
--------------------------------------------------------------------------------
/Message.jsx:
--------------------------------------------------------------------------------
1 | Message = React.createClass({
2 | propTypes: {
3 | message: React.PropTypes.object.isRequired
4 | },
5 |
6 | formatTime(time) {
7 | return moment(time).format('h:mm A');
8 | },
9 |
10 | render() {
11 | return (
12 |
{this.formatTime(this.props.message.time)} - {this.props.message.text}
13 | );
14 | }
15 | });
16 |
--------------------------------------------------------------------------------
/MessageList.jsx:
--------------------------------------------------------------------------------
1 | MessageList = React.createClass({
2 | mixins: [ReactMeteorData],
3 |
4 | getMeteorData() {
5 | return {
6 | messages: Messages.find({}).fetch()
7 | }
8 | },
9 |
10 | renderMessages() {
11 | return this.data.messages.map((message) => {
12 | return ;
13 | });
14 | },
15 |
16 | handleSubmit(event) {
17 | event.preventDefault();
18 |
19 | let message = ReactDOM.findDOMNode(this.refs.textInput).value.trim();
20 |
21 | Meteor.call("addMessage", message);
22 |
23 | ReactDOM.findDOMNode(this.refs.textInput).value = "";
24 | },
25 |
26 | renderForm() {
27 | return
34 | },
35 |
36 | render() {
37 | return (
38 |
39 |
42 |
43 | {this.renderForm()}
44 |
45 |
46 | {this.renderMessages()}
47 |
48 |
49 | );
50 | }
51 | });
52 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Meteor + React demo
2 | ===================
3 |
4 | This is the source from a talk at the Toronto React Meetup on January 27, 2016.
5 |
6 | Here is the talk: https://youtu.be/xcej5OboUVM
7 |
8 | Here is a shameless plug for our Meteor + React training: https://www.okgrow.com/training
9 |
10 | Enjoy!
11 |
--------------------------------------------------------------------------------
/demo.css:
--------------------------------------------------------------------------------
1 | /* CSS declarations go here */
2 |
--------------------------------------------------------------------------------
/demo.html:
--------------------------------------------------------------------------------
1 |
2 | demo
3 |
4 |
5 |
6 | Welcome to Meteor + React!
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/demo.jsx:
--------------------------------------------------------------------------------
1 | Messages = new Mongo.Collection("Messages", {});
2 |
3 | Meteor.methods({
4 | addMessage(text) {
5 | let message = {
6 | time: new Date(),
7 | text: text
8 | };
9 |
10 | Messages.insert(message);
11 | }
12 | });
13 |
14 |
15 | if (Meteor.isClient) {
16 | Meteor.startup(function () {
17 | ReactDOM.render(, document.getElementById("render-target"));
18 | });
19 | }
20 |
--------------------------------------------------------------------------------
/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | width: 500px;
3 | margin: 0 auto;
4 | font-family: sans-serif;
5 | color: #333;
6 | font-weight: 100;
7 | }
8 |
9 | nav {
10 | margin-top: 10px;
11 | background: #f6f8f9; /* Old browsers */
12 | background: -moz-linear-gradient(top, #f6f8f9 0%, #e5ebee 50%, #d7dee3 51%, #f5f7f9 100%); /* FF3.6+ */
13 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f6f8f9), color-stop(50%,#e5ebee), color-stop(51%,#d7dee3), color-stop(100%,#f5f7f9)); /* Chrome,Safari4+ */
14 | background: -webkit-linear-gradient(top, #f6f8f9 0%,#e5ebee 50%,#d7dee3 51%,#f5f7f9 100%); /* Chrome10+,Safari5.1+ */
15 | background: -o-linear-gradient(top, #f6f8f9 0%,#e5ebee 50%,#d7dee3 51%,#f5f7f9 100%); /* Opera 11.10+ */
16 | background: -ms-linear-gradient(top, #f6f8f9 0%,#e5ebee 50%,#d7dee3 51%,#f5f7f9 100%); /* IE10+ */
17 | background: linear-gradient(to bottom, #f6f8f9 0%,#e5ebee 50%,#d7dee3 51%,#f5f7f9 100%); /* W3C */
18 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f6f8f9', endColorstr='#f5f7f9',GradientType=0 ); /* IE6-9 */
19 | padding: 10px;
20 | border-radius: 4px;
21 | border: 1px solid #abe;
22 | }
23 |
24 | nav a {
25 | text-decoration: none;
26 | font-family: sans-serif;
27 | color: #567;
28 | font-weight: 400;
29 | font-size: 14px;
30 | }
31 |
32 | nav a:hover {
33 | color: #444;
34 | }
35 |
36 | #login-buttons {
37 | font-weight: 400;
38 | }
39 | #login-buttons a {
40 | text-decoration: none;
41 | }
42 |
43 | h2 {
44 | border-bottom: 1px solid #abe;
45 | font-family: sans-serif;
46 | font-weight: 100;
47 | }
48 |
49 | input[name="message"] {
50 | width: 81%;
51 | padding: 7px 10px;
52 | border-radius: 3px;
53 | border: 1px solid #999;
54 | box-shadow: inset 0px 1px 2px 0px #ccc;
55 | }
56 |
57 | input[value="Send"],
58 | input[value="Delete"],
59 | input[value="Follow"],
60 | input[value="Unfollow"] {
61 | padding: 6px 19px 7px 19px;
62 | color: white;
63 | border-radius: 3px;
64 | cursor: pointer;
65 | }
66 |
67 | input[value="Send"] {
68 | border: 1px solid #3498db;
69 | background-color: #3498db;
70 | }
71 |
72 | input[value="Delete"] {
73 | background-color: #ecf0f1;
74 | border: 1px solid #bdc3c7;
75 | color: #7f8c8d;
76 | text-shadow: 0px 1px 0px #fff;
77 | float: right;
78 | margin-top: -17px;
79 | }
80 |
81 | input[value="Delete"] {
82 | background-color: #ecf0f1;
83 | border: 1px solid #bdc3c7;
84 | color: #7f8c8d;
85 | text-shadow: 0px 1px 0px #fff;
86 | }
87 |
88 | input[value="Follow"] {
89 | background-color: #2ecc71;
90 | border: 1px solid #27ae60;
91 | }
92 | input[value="Unfollow"] {
93 | background-color: #f39c12;
94 | border: 1px solid #e67e22;
95 | }
96 |
97 | input[name="username-search"] {
98 | margin-top: 10px;
99 | width: 477px;
100 | padding: 10px 10px;
101 | border: 1px solid #999;
102 | border-radius: 3px;
103 | font-size: 16px;
104 | box-shadow: inset 0px 1px 3px 0px #ccc;
105 | }
106 |
107 | .countdown {
108 | font-weight: bold;
109 | }
110 |
111 | ul {
112 | list-style-type: none;
113 | padding-left: 0px;
114 | }
115 |
116 | ul li {
117 | min-height: 38px;
118 | line-height: 30px;
119 | }
120 |
121 | ul li input[value="Delete"] {
122 | margin-top: 0px;
123 | }
124 |
125 | ul li a {
126 | font-weight: bold;
127 | text-decoration: none;
128 | color: #2980b9;
129 | }
130 |
131 | h2 a {
132 | font-weight: bold;
133 | text-decoration: none;
134 | color: #333;
135 | }
136 |
137 | #follow input, #unfollow input {
138 | width: 100%;
139 | margin-bottom: 20px;
140 | font-size: 16px;
141 | }
142 |
--------------------------------------------------------------------------------