Skip to content

Commit 4db4750

Browse files
committed
Merge pull request #1223 from Urigo/feature/meteor-cli-ionic-tutorial
Add the Whatsapp tutorial with Meteor CLI to the docs website
2 parents b20573e + 0afc01a commit 4db4750

33 files changed

+858
-7
lines changed

docs/angular-meteor/both/router/subroutes/tutorial-pages.js

+12
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,17 @@ PAGES = [
3636
subHead: "Angular-Meteor and Ionic",
3737
stepbarHide: true,
3838
pages: WHATSAPP_IONIC
39+
},
40+
{
41+
id: "4",
42+
title: "WhatsApp clone with Meteor CLI",
43+
route: "tutorials.whatsapp.meteor",
44+
path: "/tutorials/whatsapp/meteor",
45+
pathRedirect: "/tutorials/whatsapp/meteor/bootstrapping",
46+
ghRepoName: "https://github.com/DAB0mB/angular-meteor-whatsapp",
47+
seoTitlePrefix: "Angular-Meteor and Ionic with Meteor CLI | ",
48+
subHead: "Angular-Meteor and Ionic with Meteor CLI",
49+
stepbarHide: true,
50+
pages: WHATSAPP_METEOR
3951
}
4052
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
WHATSAPP_METEOR = [
2+
{
3+
id: "0",
4+
title: 'Bootstrapping',
5+
seoTitle: 'Bootstrapping',
6+
route: "tutorials.whatsapp.meteor.bootstrapping",
7+
path: "/tutorials/whatsapp/meteor/bootstrapping",
8+
contentTemplate: 'tutorials.whatsapp.meteor.step_00.md'
9+
},
10+
{
11+
id: "1",
12+
title: 'Layout, coding style & structure',
13+
seoTitle: 'Layout, coding style & structure',
14+
route: "tutorials.whatsapp.meteor.layout",
15+
path: "/tutorials/whatsapp/meteor/layout",
16+
contentTemplate: 'tutorials.whatsapp.meteor.step_01.md'
17+
},
18+
{
19+
id: "2",
20+
title: 'Creating a realtime Meteor server',
21+
seoTitle: 'Creating a realtime Meteor server',
22+
route: "tutorials.whatsapp.meteor.server",
23+
path: "/tutorials/whatsapp/meteor/server",
24+
contentTemplate: 'tutorials.whatsapp.meteor.step_02.md'
25+
},
26+
{
27+
id: "3",
28+
title: 'Chat view and send messages',
29+
seoTitle: 'Server Methods',
30+
route: "tutorials.whatsapp.meteor.methods",
31+
path: "/tutorials/whatsapp/meteor/methods",
32+
contentTemplate: 'tutorials.whatsapp.meteor.step_03.md'
33+
},
34+
{
35+
id: "4",
36+
title: 'Authentication',
37+
seoTitle: 'Authentication',
38+
route: "tutorials.whatsapp.meteor.authentication",
39+
path: "/tutorials/whatsapp/meteor/authentication",
40+
contentTemplate: 'tutorials.whatsapp.meteor.step_04.md'
41+
},
42+
{
43+
id: "5",
44+
title: 'Create and remove chats',
45+
seoTitle: 'Create and remove chats',
46+
route: "tutorials.whatsapp.meteor.chats",
47+
path: "/tutorials/whatsapp/meteor/chats",
48+
contentTemplate: 'tutorials.whatsapp.meteor.step_05.md'
49+
},
50+
{
51+
id: "6",
52+
title: 'Privacy',
53+
seoTitle: 'Privacy',
54+
route: "tutorials.whatsapp.meteor.privacy",
55+
path: "/tutorials/whatsapp/meteor/privacy",
56+
contentTemplate: 'tutorials.whatsapp.meteor.step_06.md'
57+
},
58+
{
59+
id: "7",
60+
title: 'User profile picture',
61+
seoTitle: 'User profile picture',
62+
route: "tutorials.whatsapp.meteor.userprofile",
63+
path: "/tutorials/whatsapp/meteor/userprofile",
64+
contentTemplate: 'tutorials.whatsapp.meteor.step_07.md'
65+
},
66+
{
67+
id: "8",
68+
title: 'Send image messages',
69+
seoTitle: 'Send image messages',
70+
route: "tutorials.whatsapp.meteor.uploadimage",
71+
path: "/tutorials/whatsapp/meteor/uploadimage",
72+
contentTemplate: 'tutorials.whatsapp.meteor.step_08.md'
73+
},
74+
{
75+
id: "9",
76+
title: 'Summary',
77+
seoTitle: 'Summary',
78+
route: "tutorials.whatsapp.meteor.summary",
79+
path: "/tutorials/whatsapp/meteor/summary",
80+
contentTemplate: 'tutorials.whatsapp.meteor.step_09.md'
81+
}
82+
];

docs/angular-meteor/client/content/tutorials/stepbar.js

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ Template.stepbarLiveDemo.helpers({
5353
if (route.indexOf('tutorials/whatsapp/ionic') !== -1) {
5454
return 'http://dotansimha.github.io/ionic-meteor-whatsapp-clone-step-' + zeroToStep + self.id;
5555
}
56+
else if (route.indexOf('tutorials/whatsapp/meteor') !== -1) {
57+
return '';
58+
}
5659
else {
5760
return 'http://socially-step' + zeroToStep + self.id + '.meteor.com/';
5861
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{{#template name="tutorials.whatsapp.meteor.step_00.md"}}
2+
Start by installing the Meteor platform if you haven't already.
3+
4+
Create a new project by running this commands in your Terminal:
5+
6+
$ meteor create whatsapp
7+
$ cd whatsapp
8+
9+
Your app now contains a live and ready example app. let’s delete those files:
10+
11+
$ rm whatsapp.*
12+
13+
To run our app simple type `meteor` on the command line:
14+
15+
$ meteor
16+
17+
We can also run our app inside the iOS Simulator or Android Emulator - we just need to add the platform so Meteor will build the project for the new platform.
18+
19+
$ meteor add-platform ios
20+
21+
Or
22+
23+
$ meteor add-platform android
24+
25+
26+
And now to run our project in a mobile environment, we just need to tell Meteor which platform we want to run (running the mobile is an addition to the server and client run):
27+
28+
$ meteor run ios
29+
30+
Or
31+
32+
$ meteor run android
33+
34+
35+
You can find more information about Meteor CLI and build tool here:
36+
37+
[https://www.meteor.com/tool](https://www.meteor.com/tool)
38+
39+
40+
Our next step is to remove Blaze (Meteor default templating engine) and add the Angular and Ionic packages to the project:
41+
42+
$ meteor remove blaze-html-templates
43+
44+
We also need to remove Meteor's default ECMAScript2015 package named `ecmascript` because Angular-Meteor uses a package named `angular-babel` in order to get both ECMAScript2015 and AngularJS DI annotations:
45+
46+
$ meteor remove ecmascript
47+
48+
and now let's add Angular and Ionic:
49+
50+
$ meteor add angular
51+
$ meteor add driftyco:ionic
52+
53+
If you’re familiar with the Meteor folder structure and AngularJS module initialization, you can go ahead and skip to the end of this step and just download the ZIP file.
54+
55+
{{/template}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
{{#template name="tutorials.whatsapp.meteor.step_01.md"}}
2+
We will start by creating the project’s folder structure, Meteor has a special behavior for certain folders:
3+
4+
* client - these files will be available only in the client side.
5+
* server - these files will be available only in the server side.
6+
* public - these files will be available in the client, uses for assets, images, fonts, etc.
7+
* lib - any folder named lib (in any hierarchy) will be loaded first!
8+
* any other folder name will be included in both client and server and uses for code-sharing.
9+
10+
So this will be our folder structure to the project:
11+
12+
* client (client side with AngularJS and Ionic code)
13+
* - scripts
14+
* - templates
15+
* - styles
16+
* - index.html
17+
* server (server side code only)
18+
* public (assets, images)
19+
* lib (define methods and collections in order to make them available in both client and server)
20+
21+
So let’s start by creating our first file - the `index.html` file - we will place in under the `client` folder:
22+
23+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.2"}}
24+
25+
We used some ionic tags to achieve mobile style:
26+
27+
* ion-nav-bar - Create a navigation bar in the page header.
28+
* ion-nav-view - This is a placeholder to the real content - AngularJS and ionic will put your content inside this tag automatically.
29+
30+
Note that we only provide the `head` and `body` tags because Meteor takes care of the full contents of the HTML file, and any tag we will use here will be added to the Meteor’s main index.html file.
31+
32+
This feature is really useful because we do not need to take care of including our files in `index.html` and keep it updated ourselves.
33+
34+
Our next step is to create the AngularJS module and bootstrap it according to our platform.
35+
We will create a new file called `app.js`.
36+
37+
This bootstrap file should be loaded first, because any other AngularJS code will depend on the module, so we need to put this file inside a folder called `lib`, so we will create a file in this path: `client/scripts/lib/app.js`.
38+
39+
This file will contain an AngularJS module initialization with dependencies for `angular-meteor` and `ionic`.
40+
41+
We will also check for the current platform (browser or mobile) and initialize the module according to the result:
42+
43+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.3"}}
44+
45+
Our next step is to create the states and routes for the views.
46+
47+
Our app uses Ionic to create 5 tabs: Favorites, Recents, Contacts, Chats, and Settings.
48+
49+
We will define our routes and states with [angular-ui-router](https://atmospherejs.com/angularui/angular-ui-router) (which is included by ionic), and for the moment we will add the main page which is the `chats` tab:
50+
51+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.4"}}
52+
53+
And this is the HTML template for the footer that included with the tabs view:
54+
55+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.5"}}
56+
57+
Create the stub for the main page - the chats file:
58+
59+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.6"}}
60+
61+
And this is what it looks at the moment, inside a browser:
62+
63+
{{tutorialImage 'whatsapp-meteor' '1.png' 500}}
64+
65+
If you want to view your app in a better way, with mobile layout, you can add a mobile platform as we described in the beginning of the step. I’ve added the iOS platform, and when we can run it inside a mobile emulator, and it looks like this:
66+
67+
{{tutorialImage 'whatsapp-meteor' '2.png' 500}}
68+
69+
Our next step includes creating basic views with some static data using `ionic` and `SASS`.
70+
71+
First, let’s create an AngularJS controller that we will later connect to the chats view, we will call it `ChatsCtrl` and create a new file:
72+
73+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.8"}}
74+
75+
We will use the controller with `conrollerAs` syntax, which means we won't put our variables on the `$scope` - we will use `this` context instead.
76+
77+
78+
Also, we injected the `$reactive` service, which is part of Angular-Meteor, and we used our `this` context and attached in to our `$scope`.
79+
80+
81+
`$reactive` will extend our controller with new functionality like creating Meteor helpers, subscription and use Autorun - all of these from our AngularJS controller context.
82+
83+
84+
Now we want to add some static data to this controller, we will use `moment` package to easily create time object, so let’s add it to the project using this command:
85+
86+
$ meteor add momentjs:moment
87+
88+
Now let’s add the static data, we will create a stub schema for chats and messages:
89+
90+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.10"}}
91+
92+
Connect the chats view to the `ChatsCtrl`:
93+
94+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.11"}}
95+
96+
Note that we used `controllerAs` syntax, so from now on, we will keep our controller variables on the `this` context, and we will used them with the `chats` prefix on the view.
97+
98+
Modify the chats list view to use the stub data.
99+
100+
We will use ionic’s tags to create a container with a list view (`ion-list` and `ion-item`), and add `ng-repeat` to iterate over the chats:
101+
102+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.12"}}
103+
104+
And this is how is looks like:
105+
106+
{{tutorialImage 'whatsapp-meteor' '3.png' 500}}
107+
108+
You might notice that the dates are not formatted, so let’s create a simple AngularJS filter that use `moment` package to convert the date into formatted text, we will place it in a file named `client/scripts/filters/calendar.filter.js`:
109+
110+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.13"}}
111+
112+
And let’s use it in our view:
113+
114+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.14"}}
115+
116+
And this how it looks like now:
117+
118+
{{tutorialImage 'whatsapp-meteor' '4.png' 500}}
119+
120+
To add a delete button to our view, we will use `ion-option-button` which is a button that’s visible when we swipe over the list item!
121+
122+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.15"}}
123+
124+
Implement the `remove(chat)` method inside our `ChatsCtrl`:
125+
126+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.16"}}
127+
128+
And this is the result:
129+
130+
{{tutorialImage 'whatsapp-meteor' '5.png' 500}}
131+
132+
Now we want to add some styles and make some small CSS modifications to make it look more like WhatsApp.
133+
134+
We want to use SASS in our project, so we need to add the sass package to our project:
135+
136+
$ meteor add fourseven:scss
137+
138+
And now we will create our first SASS file, we will place it under `client/styles/chats.scss`, and add some CSS rules:
139+
140+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="1.18"}}
141+
142+
And we are done with this view! It look just like WhatsApp!
143+
144+
{{tutorialImage 'whatsapp-meteor' '6.png' 500}}
145+
146+
{{/template}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{{#template name="tutorials.whatsapp.meteor.step_02.md"}}
2+
3+
In this step we are going to add several features to our project:
4+
5+
* Create and server and move the static data to the server.
6+
* Connect the client to the server.
7+
8+
So let’s start by creating the Meteor collection that will later store all of our data.
9+
10+
Meteor collection need to be available in both client and server in order to share data - so we will create the collections definition in a folder named `lib` under the project’s root (`lib/collections.js`).
11+
12+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="2.1"}}
13+
14+
Now we need to create our server’s first file, so let’s create a directory named `server` and create the server startup file named `bootstrap.js` (`server/bootstrap.js`).
15+
16+
This file should be run first because we want to run some initialization code there, so we can use `Meteor.startup` to define our logic:
17+
18+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="2.2"}}
19+
20+
Our next step is to move the static data to the server, so let’s add it in the `bootstrap.js` file we just created, we also want this code to run only once - when there is no data at all inside the collections.
21+
22+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="2.3"}}
23+
24+
Now we need to remove the static data from the client and get it from the server.
25+
26+
So let’s use angular-meteor’s API for this - we just need to use Angular-Meteor API and define a helper named `data`, and we will return the MongoDB collection cursor.
27+
28+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="2.4"}}
29+
30+
Now that the data comes from the server, we need to modify the `remove` method in order to use MongoDB Collection API that removes the object from both client and server:
31+
32+
{{> DiffBox tutorialName="whatsapp-meteor-tutorial" step="2.5"}}
33+
34+
35+
{{/template}}

0 commit comments

Comments
 (0)