├── .gitignore
├── .vscode
└── settings.json
├── README.md
├── index.html
├── package.json
├── screenshot.png
├── src
├── all-the-things.css
├── app
│ ├── app.component.html
│ ├── app.component.ts
│ ├── subscription.component.html
│ └── subscription.component.ts
├── img
│ ├── pusher-logo.png
│ ├── pusher.png
│ └── twitter.png
└── style.css
├── tsconfig.json
└── typings.json
/.gitignore:
--------------------------------------------------------------------------------
1 | src/app/*.js
2 | src/app/*.js.map
3 | node_modules
4 | typings
5 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | "files.exclude": {
4 | "**/.git": true,
5 | "**/.svn": true,
6 | "**/.DS_Store": true,
7 | "**/*.js": true
8 | }
9 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Angular 2 and Pusher
2 |
3 | A client of the [Pusher Datasource API](https://github.com/pusher-community/pusher-datasource-api) that lets you search for tweets and view the results in realtime.
4 |
5 | 
6 |
7 | ## Running
8 |
9 | ```
10 | $ npm install
11 | ```
12 |
13 | You need to run two processes separately. The first will compile your TypeScript:
14 |
15 | ```
16 | $ npm run tsc
17 | ```
18 |
19 | To run the app locally with live reload enabled, use `npm start`:
20 |
21 | ```
22 | $ npm start
23 | ```
24 |
25 | This will run the app on port 8080 and open a new browser tab.
26 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Angular 2 QuickStart
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
55 |
56 |
57 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-pusher-datasource",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "tsc": "tsc",
8 | "start": "npm run tsc && live-server --open=/",
9 | "postinstall": "typings install"
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "dependencies": {
15 | "@angular/common": "2.0.0-rc.1",
16 | "@angular/compiler": "2.0.0-rc.1",
17 | "@angular/core": "2.0.0-rc.1",
18 | "@angular/http": "2.0.0-rc.1",
19 | "@angular/platform-browser": "2.0.0-rc.1",
20 | "@angular/platform-browser-dynamic": "2.0.0-rc.1",
21 | "@angular/router": "2.0.0-rc.1",
22 | "es6-shim": "0.35.0",
23 | "reflect-metadata": "0.1.2",
24 | "rxjs": "5.0.0-beta.6",
25 | "systemjs": "0.19.26",
26 | "zone.js": "^0.6.12"
27 | },
28 | "devDependencies": {
29 | "live-server": "^0.8.2",
30 | "typescript": "^1.6.2",
31 | "typings": "^0.8.1"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher-community/realtime-twitter-search-angular2/330b7e07e171a07517ca98d7938095b48983e79c/screenshot.png
--------------------------------------------------------------------------------
/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Pusher Angular Realtime Demo
6 |
7 |
8 |
9 | Displaying live tweets using Pusher and Angular 2.
10 |
11 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | declare var Pusher: any;
2 |
3 | import {bootstrap} from '@angular/platform-browser-dynamic';
4 | import {Component} from '@angular/core';
5 |
6 | import SubscriptionComponent from './subscription.component';
7 |
8 | @Component({
9 | moduleId: module.id,
10 | selector: 'my-app',
11 | templateUrl: 'app.component.html',
12 | directives: [SubscriptionComponent],
13 | })
14 | class AppComponent {
15 | private newSearchTerm: string;
16 | private pusher;
17 | private channels: any[];
18 |
19 | constructor() {
20 | this.pusher = new Pusher('9fd1b33fcb36d968145f');
21 | this.channels = [];
22 | }
23 |
24 | public newSubscription() {
25 | this.channels.push({term: this.newSearchTerm, active: true});
26 | this.newSearchTerm = '';
27 | }
28 |
29 | public clearSearch(channel) {
30 | this.channels = this.channels.filter((ch) => {
31 | if (ch.term === channel.term) {
32 | this.toggleSearch(channel);
33 | }
34 | return ch.term !== channel.term;
35 | });
36 | }
37 | public toggleSearch(channel) {
38 | for (let ch of this.channels) {
39 | if (ch.term === channel.term) {
40 | ch.active = !ch.active;
41 | break;
42 | }
43 | }
44 | }
45 | }
46 |
47 | bootstrap(AppComponent);
48 |
--------------------------------------------------------------------------------
/src/app/subscription.component.html:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/app/subscription.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Component,
3 | Input,
4 | AfterViewChecked,
5 | OnInit,
6 | OnChanges,
7 | OnDestroy
8 | } from '@angular/core';
9 |
10 | @Component({
11 | moduleId: module.id,
12 | selector: 'subscription',
13 | templateUrl: 'subscription.component.html'
14 | })
15 | export default class SubscriptionComponent implements OnInit, OnChanges, OnDestroy, AfterViewChecked {
16 | @Input() search: any;
17 | @Input() pusher;
18 | public tweets : Object[];
19 | private channel;
20 | private subscribed: boolean = false;
21 | private className: String;
22 |
23 | public ngOnInit() {
24 | this.subscribeToChannel();
25 | this.tweets = [];
26 | this.className = this.search.term.replace(' ', '-');
27 | }
28 |
29 | private subscribeToChannel() {
30 | this.channel = this.pusher.subscribe(btoa(this.search.term));
31 | this.channel.bind('new_tweet', (data) => {
32 | this.newTweet(data);
33 | });
34 | this.subscribed = true;
35 | }
36 |
37 | private newTweet(data: Object) {
38 | this.tweets.push(data);
39 | }
40 |
41 | public ngOnChanges() {
42 | console.log(this.search);
43 | if (!this.search.active && this.subscribed) {
44 | this.ngOnDestroy();
45 | } else if (this.search.active && !this.subscribed) {
46 | this.subscribeToChannel();
47 | }
48 | }
49 |
50 | public ngOnDestroy() {
51 | this.pusher.unsubscribe(btoa(this.search.term));
52 | this.channel && this.channel.unbind();
53 | this.subscribed = false;
54 | }
55 |
56 | public ngAfterViewChecked() {
57 | var listItem = document.querySelector(".channel-" + this.className);
58 | if (listItem) {
59 | listItem.scrollTop = listItem.scrollHeight;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/img/pusher-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher-community/realtime-twitter-search-angular2/330b7e07e171a07517ca98d7938095b48983e79c/src/img/pusher-logo.png
--------------------------------------------------------------------------------
/src/img/pusher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher-community/realtime-twitter-search-angular2/330b7e07e171a07517ca98d7938095b48983e79c/src/img/pusher.png
--------------------------------------------------------------------------------
/src/img/twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher-community/realtime-twitter-search-angular2/330b7e07e171a07517ca98d7938095b48983e79c/src/img/twitter.png
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 | #search-form {
2 | margin-top: 30px;
3 | }
4 |
5 | .channel {
6 | margin-bottom: 50px;
7 | }
8 |
9 | .channel-results {
10 | list-style: none;
11 | padding: 0;
12 | }
13 |
14 | #subscription-controls {
15 | margin-top: 20px;
16 | margin-bottom: 20px;
17 | }
18 |
19 | #subscription-controls button {
20 | padding: 10px 15px;
21 | }
22 |
23 | .twitter-icon {
24 | vertical-align: top;
25 | }
26 |
27 | .tweets-container {
28 | width: 800px;
29 | }
30 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES5",
4 | "module": "commonjs",
5 | "sourceMap": true,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "removeComments": false,
9 | "noImplicitAny": false
10 | },
11 | "exclude": [
12 | "node_modules",
13 | "typings/browser.d.ts",
14 | "typings/browser"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/typings.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "xhr2": "github:gdi2290/typed-xhr2#69f2b8d40d0cd407c1b2a2f2f41fecc6852cabbb"
4 | },
5 | "devDependencies": {},
6 | "ambientDependencies": {
7 | "async": "github:DefinitelyTyped/DefinitelyTyped/async/async.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f",
8 | "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#6697d6f7dadbf5773cb40ecda35a76027e0783b2",
9 | "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#26c98c8a9530c44f8c801ccc3b2057e2101187ee",
10 | "ng2": "github:gdi2290/typings-ng2/ng2.d.ts#32998ff5584c0eab0cd9dc7704abb1c5c450701c",
11 | "node": "github:DefinitelyTyped/DefinitelyTyped/node/node.d.ts#138ad74b9e8e6c08af7633964962835add4c91e2",
12 | "systemjs": "github:DefinitelyTyped/DefinitelyTyped/systemjs/systemjs.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f",
13 | "zone.js": "github:DefinitelyTyped/DefinitelyTyped/zone.js/zone.js.d.ts#b923a5aaf013ac84c566f27ba6b5843211981c7a"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------