├── .gitignore
├── .idea
├── .name
├── encodings.xml
├── jsLibraryMappings.xml
├── libraries
│ └── redditClient_node_modules.xml
├── misc.xml
├── modules.xml
├── redditClient.iml
├── scopes
│ └── scope_settings.xml
├── vcs.xml
└── workspace.xml
├── .travis.yml
├── CONTRIBUTING
├── Gruntfile.js
├── LICENSE
├── README.md
├── comment.js
├── link.js
├── package.json
├── public
├── app.js
├── client.css
├── controllers
│ ├── newRedditButtonController.js
│ ├── newRedditController.js
│ ├── redditListController.js
│ └── userController.js
├── directives
│ └── reddit
│ │ ├── controller.js
│ │ └── template.html
├── i18n
│ └── ng-translate.js
├── images
│ ├── 404.png
│ ├── 404_mobile.png
│ ├── caret-bottom.svg
│ ├── caret-top.svg
│ ├── favicon.ico
│ └── reddit.png
├── index.html
├── old
│ ├── NewReddit.xhtml
│ ├── RedditTable.xhtml
│ ├── RedditView.xhtml
│ ├── base.xhtml
│ ├── commentEntry.xhtml
│ ├── css
│ │ ├── base.css
│ │ ├── layout.css
│ │ └── modules.css
│ └── redditEntry.xhtml
├── services
│ ├── loginService.js
│ └── socketService.js
└── view
│ ├── 404.html
│ ├── newReddit.html
│ └── table.html
├── rating.js
├── screenshot.png
├── server.js
└── user.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.swp
3 | *.log
4 | .idea/
5 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | redditClient
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/jsLibraryMappings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/libraries/redditClient_node_modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/redditClient.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
114 |
115 |
116 |
117 |
118 | $PROJECT_DIR$/Gruntfile.js
119 |
120 |
121 | false
122 |
123 |
124 | true
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 | true
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 | 1415286432284
336 |
337 | 1415286432284
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 0.10
4 | - 0.11
5 |
--------------------------------------------------------------------------------
/CONTRIBUTING:
--------------------------------------------------------------------------------
1 | Samuel Kurath @Murthy10
2 | Severin Bühler @Sebubu
3 | Lukas Martinelli @lukasmartinelli
4 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 |
3 | grunt.initConfig({
4 | pkg: grunt.file.readJSON('package.json'),
5 | qunit: {
6 | files: ['test/**/*.html']
7 | },
8 | jshint: {
9 | files: ['Gruntfile.js', 'public/**/*.js', 'test/**/*.js'],
10 | options: {
11 | // options here to override JSHint defaults
12 | globals: {
13 | jQuery: true,
14 | console: true,
15 | module: true,
16 | document: true
17 | }
18 | }
19 | },
20 | watch: {
21 | files: ['<%= jshint.files %>'],
22 | tasks: ['jshint', 'qunit']
23 | }
24 | });
25 |
26 | grunt.loadNpmTasks('grunt-contrib-jshint');
27 | grunt.loadNpmTasks('grunt-contrib-qunit');
28 | grunt.loadNpmTasks('grunt-contrib-watch');
29 |
30 | grunt.registerTask('test', ['jshint', 'qunit']);
31 | grunt.registerTask('default', ['jshint', 'qunit']);
32 |
33 | };
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Lukas Martinelli
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Reddit Clone  [](https://travis-ci.org/lukasmartinelli/reddit-clone-js)
2 |
3 | > :warning: This repository is no longer maintained by Lukas Martinelli.
4 |
5 | This is a Single Page App built with AngularJs on the client side
6 | and Node on the server side.
7 | The same Project has been [realized in JSF](https://github.com/lukasmartinelli/reddit-clone).
8 | It is a mini project created after the specifications given
9 | in the [Internet Technologies](http://studien.hsr.ch/allModules/23331_M_IntTe.html) lecture.
10 |
11 | 
12 |
13 | ## Requirements
14 |
15 | You should have NodeJS and npm installed.
16 | For testing and linting the project you need Grunt.
17 |
18 | ## Run Project
19 |
20 | ```
21 | npm install
22 | node server.js
23 | ```
24 |
25 | Now visit `http://localhost:4730/index.html`.
26 |
27 | # Test Project
28 |
29 | ```
30 | grunt test
31 | ```
32 |
--------------------------------------------------------------------------------
/comment.js:
--------------------------------------------------------------------------------
1 | var Rating = require('./rating.js');
2 |
3 | module.exports = function Comment(id, text, author) {
4 | this.id = id;
5 | this.text = text;
6 | this.author = author;
7 | this.createTime = new Date();
8 | this.createTimeDisplay = this.createTime.toLocaleDateString() + " : " + this.createTime.toLocaleTimeString();
9 | this.rating = new Rating();
10 | this.comments = [];
11 | };
12 |
13 |
--------------------------------------------------------------------------------
/link.js:
--------------------------------------------------------------------------------
1 | var Rating = require('./rating.js');
2 |
3 | module.exports = function Link(id, title, author, url) {
4 | this.id = id;
5 | this.title = title;
6 | this.author = author;
7 | this.url = url;
8 | this.createTime = new Date();
9 | this.createTimeDisplay = this.createTime.toLocaleDateString() + " : " + this.createTime.toLocaleTimeString();
10 | this.rating = new Rating();
11 | this.comments = [];
12 | this.voters = [];
13 | };
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "IntTeTestat",
3 | "description": "Testat Server",
4 | "version": "0.0.1",
5 | "private": true,
6 | "dependencies": {
7 | "express": "3.4.1",
8 | "socket.io": "latest"
9 | },
10 | "devDependencies": {
11 | "grunt": "^0.4.5",
12 | "grunt-contrib-jshint": "^0.10.0",
13 | "grunt-contrib-qunit": "^0.5.2",
14 | "grunt-contrib-watch": "^0.6.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/public/app.js:
--------------------------------------------------------------------------------
1 | var redditclone = angular.module('redditclone', ['ngRoute','pascalprecht.translate']);
2 |
3 | redditclone.config(['$routeProvider', function($routeProvider) {
4 | $routeProvider.
5 | when('/', {
6 | templateUrl: 'view/table.html',
7 | controller: 'redditListController',
8 | }).
9 | when('/new', {
10 | templateUrl: 'view/new.html'
11 | // controller: 'AddOrderController'
12 | }).
13 | when('/entry', {
14 | templateUrl: 'view/entry.html'
15 | // controller: 'ShowOrdersController'
16 | }).
17 | when('/newReddit', {
18 | templateUrl: 'view/newReddit.html'
19 | // controller: 'ShowOrdersController'
20 | }).
21 | when('/404', {
22 | templateUrl: 'view/404.html'
23 | // controller: 'ShowOrdersController'
24 | }).
25 | otherwise({
26 | redirectTo: '/404'
27 | });
28 | }]);
29 |
--------------------------------------------------------------------------------
/public/client.css:
--------------------------------------------------------------------------------
1 | /* ===NAVBAR=== */
2 | .navbar h1 {
3 | display: inline;
4 | }
5 |
6 | .navbar-brand {
7 | padding-top: 8px;
8 | }
9 |
10 | .navbar-brand > img {
11 | margin-top: -10px;
12 | display: inline;
13 | height: 40px;
14 | }
15 |
16 | /* ===REDDITS=== */
17 | .reddit {
18 | position: relative;
19 | display:block;
20 | min-height: 5rem;
21 | margin-bottom: 2rem;
22 | }
23 |
24 | form.comment-form {
25 | max-width:56rem;
26 | }
27 |
28 | .reddit .reddit-wrapper {
29 | padding-left: 6rem;
30 | }
31 |
32 | .reddit .votebuttons {
33 | position: absolute;
34 | z-index: 2;
35 | }
36 |
37 | .redditComments .votebuttons {
38 | }
39 |
40 | .commentText {
41 | min-height: 5rem;
42 | padding-left: 5rem;
43 | margin-bottom: 3em;
44 | }
45 |
46 | /* ===VOTE BUTTONS=== */
47 | .votebuttons {
48 | text-align: center;
49 | width: 5rem;
50 | }
51 |
52 | .votebuttons img {
53 | width: 2rem;
54 | height: 2rem;
55 | fill: #4F4A4A;
56 | }
57 |
58 | .votebuttons img:hover {
59 | cursor: pointer;
60 | cursor: hand;
61 | }
62 |
63 | .votebuttons .upvote:hover, .votebuttons .upvote.active {
64 | fill: #4BC35F;
65 | }
66 |
67 | .votebuttons .downvote:hover, .votebuttons .downvote.active {
68 | fill: #C15044;
69 | }
70 |
71 | .votebuttons .vote_sum {
72 | font-size: 3.6rem;
73 | font-family: "Droid Sans", sans-serif;
74 | }
75 |
--------------------------------------------------------------------------------
/public/controllers/newRedditButtonController.js:
--------------------------------------------------------------------------------
1 |
2 | redditclone.controller('newRedditButtonController', ['$scope', '$translate', 'loginService', function($scope, $translate, loginService) {
3 | $scope.isLoggedIn = function() {
4 | return loginService.loggedIn;
5 | };
6 | }]);
7 |
8 |
--------------------------------------------------------------------------------
/public/controllers/newRedditController.js:
--------------------------------------------------------------------------------
1 | redditclone.controller('newRedditController', ['$scope', '$http', '$location', 'loginService', function($scope, $http, $location, loginService) {
2 | $scope.title = "";
3 | $scope.loggedIn = loginService.loggedIn;
4 |
5 | $scope.newReddit = function() {
6 | if(loginService.loggedIn) {
7 | $http.post('/entry', {"title": $scope.title,
8 | "url": $scope.link,
9 | "username": loginService.user.username})
10 | .success(function (data, status, headers, config) {
11 | $location.path('/');
12 | //$scope.loggedIn = true;
13 | })
14 | .error(function (data, status, headers, config) {
15 | //$scope.loggedIn = false;
16 | });
17 | }
18 | };
19 |
20 | }]);
21 |
--------------------------------------------------------------------------------
/public/controllers/redditListController.js:
--------------------------------------------------------------------------------
1 |
2 | redditclone.controller('redditListController', ['$scope', '$http', 'socketService', 'loginService', function($scope, $http, socketService, loginService) {
3 | $scope.reddits = [];
4 | $scope.commentAddedID = -1;
5 | $scope.isLoggedIn = function() {
6 | return loginService.loggedIn;
7 | };
8 | function extendReddit(entry) {
9 | entry.areCommentsVisible = false;
10 | entry.setCommentsVisible = function (){
11 | if(loginService.loggedIn === true) {
12 | this.areCommentsVisible = true;
13 | }
14 | };
15 | entry.newCommentText = "";
16 | entry.submitNewComment = function() {
17 | $scope.commentAddedID = entry.id;
18 | $http.post("/entry/" + entry.id + "/comment",{text:entry.newCommentText}).success(function(data, status, headers, config) {
19 | console.log("comment added successfully: " + entry.newCommentText);
20 | })
21 | };
22 | };
23 | $scope.update = function() {
24 | $http.get('/entries').success(function(data, status, headers, config) {
25 | data.forEach(function(entry) {
26 | extendReddit(entry);
27 | if(entry.id === $scope.commentAddedID) {
28 | entry.setCommentsVisible();
29 | $scope.commentAddedID = -1;
30 | }
31 | });
32 | $scope.reddits = data;
33 | console.log("Loaded " + data.length + " reddits");
34 | });
35 |
36 | };
37 |
38 | $scope.upEntry = function(entryId) {
39 | if(loginService.loggedIn) {
40 | socketService.emit('upEntry', {eId: entryId, uId: loginService.user.username});
41 | }
42 | };
43 |
44 | $scope.downEntry = function(entryId) {
45 | if(loginService.loggedIn) {
46 | socketService.emit('downEntry', {eId: entryId, uId: loginService.user.username});
47 | }
48 | };
49 |
50 | $scope.upComment = function(commentId, redditId) {
51 | if(loginService.loggedIn) {
52 | socketService.emit('upComment', {cId: commentId, eId: redditId, uId: loginService.user.username});
53 | }
54 | };
55 |
56 | $scope.downComment = function(commentId, redditId) {
57 | if(loginService.loggedIn) {
58 | socketService.emit('downComment', {cId: commentId, eId: redditId, uId: loginService.user.username});
59 | }
60 | };
61 |
62 | socketService.on('voteEntryState', function(reddit){
63 | extendReddit(reddit);
64 | reddit.setCommentsVisible();
65 | $scope.reddits[reddit.id] = reddit;
66 | });
67 | $scope.update();
68 | }]);
69 |
70 |
--------------------------------------------------------------------------------
/public/controllers/userController.js:
--------------------------------------------------------------------------------
1 | redditclone.controller('userController', ['$scope', '$http', 'loginService',
2 | function($scope, $http, loginService) {
3 | $scope.loggedIn = false;
4 |
5 | $scope.logout = function() {
6 | loginService.logout();
7 | $scope.loggedIn = false;
8 | };
9 |
10 | $scope.login = function() {
11 | loginService.login($scope.username, $scope.password, function() {
12 | $scope.loggedIn = loginService.loggedIn;
13 | });
14 | };
15 |
16 | $scope.register = function() {
17 | loginService.register($scope.username, $scope.password, function() {
18 | $scope.loggedIn = loginService.loggedIn;
19 | });
20 | };
21 |
22 | if(sessionStorage.username) {
23 | $scope.username = sessionStorage.username;
24 | $scope.password = sessionStorage.password;
25 | $scope.login();
26 | }
27 | }]);
28 |
--------------------------------------------------------------------------------
/public/directives/reddit/controller.js:
--------------------------------------------------------------------------------
1 | redditclone.controller('redditEntryController', ['$scope', function($scope) {
2 | $scope.title = "Dorfmarkt knackt Umsatzrekord";
3 | $scope.votesCount = 103;
4 | $scope.author = "Piter Sommerlat";
5 | $scope.commentsCount = 63;
6 | $scope.timeAgo = "2 days ago";
7 | $scope.url = "http://www.20min.ch";
8 | }])
9 | .directive('redditentry', function() {
10 | return {
11 | templateUrl: 'directives/reddit/template.html'
12 | };
13 | });
14 |
--------------------------------------------------------------------------------
/public/directives/reddit/template.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/i18n/ng-translate.js:
--------------------------------------------------------------------------------
1 |
2 | redditclone.config(function($translateProvider) {
3 | $translateProvider.translations('en', {
4 | newRedditButton: 'New Reddit!'
5 | })
6 | .translations('de', {
7 | newRedditButton: 'Neuer Reddit!'
8 | });
9 | $translateProvider.preferredLanguage('en');
10 | });
11 |
12 |
13 | redditclone.controller('i18nController', ['$scope', '$translate', function($scope, $translate) {
14 | $scope.setLanguageDE = function () {
15 | $translate.use('de');
16 | console.log("Language is set to DE");
17 | };
18 | $scope.setLanguageEN = function () {
19 | $translate.use('en');
20 | console.log("Language is set to EN");
21 | };
22 | }]);
--------------------------------------------------------------------------------
/public/images/404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukasmartinelli-alt/reddit-clone-js/e67d1e44cd25bfec2c7a98b1c7b7861e994bd0c8/public/images/404.png
--------------------------------------------------------------------------------
/public/images/404_mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukasmartinelli-alt/reddit-clone-js/e67d1e44cd25bfec2c7a98b1c7b7861e994bd0c8/public/images/404_mobile.png
--------------------------------------------------------------------------------
/public/images/caret-bottom.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/caret-top.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukasmartinelli-alt/reddit-clone-js/e67d1e44cd25bfec2c7a98b1c7b7861e994bd0c8/public/images/favicon.ico
--------------------------------------------------------------------------------
/public/images/reddit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukasmartinelli-alt/reddit-clone-js/e67d1e44cd25bfec2c7a98b1c7b7861e994bd0c8/public/images/reddit.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | InTeTestat
5 |
6 |
7 |
8 |
9 |
10 |
44 |
45 |
46 |
47 |
48 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/public/old/NewReddit.xhtml:
--------------------------------------------------------------------------------
1 |
7 | Create new Reddit
8 |
9 |
10 |
Submit a new Link
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/public/old/RedditTable.xhtml:
--------------------------------------------------------------------------------
1 |
2 |
11 | Reddit Table
12 |
13 |
14 |
Entries
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/public/old/RedditView.xhtml:
--------------------------------------------------------------------------------
1 |
2 |
11 | Reddit Comments
12 |
13 |
14 |
15 |
16 |
17 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/old/base.xhtml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | Reddit Clone
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/public/old/commentEntry.xhtml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
51 |
52 |
--------------------------------------------------------------------------------
/public/old/css/base.css:
--------------------------------------------------------------------------------
1 | /* ===RESET=== */
2 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p,
3 | blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn,
4 | em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var,
5 | b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend,
6 | table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas,
7 | details, embed, figure, figcaption, footer, header, hgroup, menu, nav,
8 | output, ruby, section, summary, time, mark, audio, video {
9 | margin: 0;
10 | padding: 0;
11 | border: 0;
12 | font: inherit;
13 | font-size: 100%;
14 | vertical-align: baseline;
15 | }
16 |
17 | html {
18 | line-height: 1;
19 | }
20 |
21 | ol, ul {
22 | list-style: none;
23 | }
24 |
25 | table {
26 | border-collapse: collapse;
27 | border-spacing: 0;
28 | }
29 |
30 | caption, th, td {
31 | text-align: left;
32 | font-weight: normal;
33 | vertical-align: middle;
34 | }
35 |
36 | q, blockquote {
37 | quotes: none;
38 | }
39 |
40 | q:before, q:after, blockquote:before, blockquote:after {
41 | content: "";
42 | content: none;
43 | }
44 |
45 | a img {
46 | border: none;
47 | }
48 |
49 | article, aside, details, figcaption, figure, footer, header, hgroup,
50 | main, menu, nav, section, summary {
51 | display: block;
52 | }
53 |
54 | html {
55 | box-sizing: border-box;
56 | }
57 |
58 | *, *:before, *:after {
59 | box-sizing: inherit;
60 | }
61 |
62 | /* ===TYPOGRAPHY=== */
63 | html {
64 | font-size: 62.5%;
65 | }
66 |
67 | body {
68 | background: #fff;
69 | font-size: 1.6rem;
70 | line-height: 1.82rem;
71 | font-family: 'Istok Web', sans-serif;
72 | color: #333;
73 | }
74 |
75 | h1, h2, h3, h4, h5, h6, nav a {
76 | font-family: 'Istok Web', sans-serif;
77 | }
78 |
79 | h1 {
80 | font-size: 4.8rem;
81 | font-weight: 400;
82 | color: #155183;
83 | line-height: 1em;
84 | margin-bottom: 2rem;
85 | }
86 |
87 | h2 {
88 | font-size: 3.6rem;
89 | line-height: 4.6rem;
90 | }
91 |
92 | h3 {
93 | font-size: 2rem;
94 | line-height: 2.6rem;
95 | }
96 |
97 | h4 {
98 | font-size: 1.6rem;
99 | line-height: 2.08rem;
100 | }
101 |
102 | em, strong {
103 | font-weight: 700;
104 | }
105 |
106 | p {
107 | margin: 0 auto 0.5em;
108 | }
109 |
110 | hr {
111 | border: solid #D2DDE5;
112 | border-width: 1px 0 0;
113 | clear: both;
114 | margin: 1rem 0 1.5rem;
115 | height: 0;
116 | }
117 |
118 | /* ===LISTS=== */
119 | ul>li {
120 | list-style: disc inside;
121 | padding-left: 1rem;
122 | }
123 |
124 | /* ===LINKS=== */
125 | a {
126 | color: #155183;
127 | text-decoration: none;
128 | outline: 0;
129 | }
130 |
131 | a:hover, a:focus {
132 | color: #41586e;
133 | }
134 |
135 | /* ===FORMS=== */
136 | form, fieldset {
137 | margin-bottom: 1rem;
138 | }
139 |
140 | button, a.button, input, select, textarea {
141 | font-size: 1.6rem;
142 | padding: 0.8rem 1.2rem;
143 | outline: none;
144 | }
145 |
146 | .control-group {
147 | *zoom: 1;
148 | }
149 |
150 | .control-group:after {
151 | content: "";
152 | display: table;
153 | clear: both;
154 | }
155 |
156 | label {
157 | color: #666;
158 | display: block;
159 | margin-bottom: 0.5rem;
160 | }
161 | .ui-datagrid-content {
162 | border: none;
163 | }
164 |
165 | input, select, textarea {
166 | width: 100%;
167 | -moz-transition: border-color, 0.3s;
168 | -o-transition: border-color, 0.3s;
169 | -webkit-transition: border-color, 0.3s;
170 | transition: border-color, 0.3s;
171 | border: 2px solid #D2DDE5;
172 | margin-top: 1rem;
173 | }
174 |
175 | input:focus, select:focus, textarea:focus {
176 | border-color: #41586e;
177 | }
178 |
179 | .help-block {
180 | font-size: 1.1rem;
181 | }
182 |
183 | ul.errorlist li {
184 | color: #b94a48;
185 | list-style-type: none;
186 | padding-left: 0;
187 | font-size: 1.1rem;
188 | }
189 |
190 | input[type="checkbox"] {
191 | width: auto;
192 | float: left;
193 | }
194 |
195 | input[type="checkbox"]+p.help-block {
196 | font-size: 1.4rem;
197 | }
198 |
199 | .form-horizontal .control-group {
200 | margin-bottom: 1rem;
201 | }
202 |
203 | /* ===RESPONSIVE FORMS=== */
204 | @media ( min-width : 43.75em) {
205 | .form-horizontal label, .form-horizontal p.help-block, .form-horizontal ul.errorlist
206 | {
207 | float: left;
208 | width: 30%;
209 | }
210 | .form-horizontal input, .form-horizontal textarea, .form-horizontal select
211 | {
212 | float: right;
213 | width: 70%;
214 | }
215 | .form-horizontal #id_license+p.help-block {
216 | width: 70%;
217 | float: right;
218 | }
219 | .form-horizontal input[type="checkbox"] {
220 | float: left;
221 | width: auto;
222 | }
223 | .form-horizontal input[type="checkbox"]+p.help-block {
224 | width: 65%;
225 | float: right;
226 | }
227 | }
228 | /* ===BUTTONS=== */
229 | button, .button {
230 | border: 0;
231 | /*display: inline-block;*/
232 | margin: 1rem;
233 | margin-left: 0;
234 | color: #fff;
235 | cursor: pointer;
236 | -moz-transition: background 0.2s;
237 | -o-transition: background 0.2s;
238 | -webkit-transition: background 0.2s;
239 | transition: background 0.2s;
240 | background-color: #91acc0;
241 | }
242 |
243 | button:hover, button:focus, button:active, .button:hover, .button:focus,
244 | .button:active {
245 | background-color: #7194ad;
246 | color: #fff;
247 | }
248 |
249 | button.button-primary, .button.button-primary {
250 | background-color: #155183;
251 | }
252 |
253 | button.button-primary:hover, button.button-primary:active, button.button-primary:focus,
254 | .button.button-primary:hover, .button.button-primary:active, .button.button-primary:focus
255 | {
256 | background: #41586e;
257 | }
258 | /* ===MISC=== */
259 | .hidden {
260 | display: none;
261 | }
--------------------------------------------------------------------------------
/public/old/css/layout.css:
--------------------------------------------------------------------------------
1 | /* ===LAYOUT STRUCTURE=== */
2 | .top {
3 | padding: 0;
4 | min-height: 25rem;
5 | }
6 |
7 | .header {
8 | overflow: hidden;
9 | *zoom: 1;
10 | }
11 |
12 | .main {
13 | margin-top: 1rem;
14 | padding: 1rem;
15 | }
16 |
17 | .header {
18 | padding: 1rem;
19 | background-color: #D2DDE5;
20 | }
21 |
22 | .header img {
23 | max-height: 4.8rem;
24 | margin-bottom: -0.8rem;
25 | }
26 |
27 | .branding {
28 | float: left;
29 | }
--------------------------------------------------------------------------------
/public/old/css/modules.css:
--------------------------------------------------------------------------------
1 | /* ===SUBMIT LINK=== */
2 | .submit {
3 | margin-top: 1.3rem;
4 | margin-left: 1rem;
5 | float: right;
6 | }
7 |
8 | .submit input {
9 | margin: 0;
10 | }
11 |
12 | .submit input[type="text"] {
13 | width: auto;
14 | }
15 |
16 | /* ===LOGOUT=== */
17 |
18 | .logout {
19 | margin-top: 1.3rem;
20 | float: right;
21 | }
22 |
23 | /* ===HEADER LOGIN=== */
24 | .login {
25 | clear: left;
26 | margin-top : 0.5rem;
27 | overflow: hidden;
28 | margin-top: 0.5rem;
29 | }
30 |
31 | .login input {
32 | margin: 0;
33 | margin-right: 1%;
34 | margin-top: 1rem;
35 | float: left;
36 | width: 49%;
37 | }
38 |
39 | @media(min-width: 68em) {
40 | .login {
41 | clear: none;
42 | float: right;
43 | overflow: hidden;
44 | }
45 | .login input {
46 | margin: 0;
47 | margin-left: 1.5rem;
48 | float: left;
49 | width: auto;
50 | }
51 | }
52 |
53 | /* ===REDDITS=== */
54 | .reddit {
55 | position: relative;
56 | display:block;
57 | min-height: 5rem;
58 | margin-bottom: 2rem;
59 | }
60 |
61 | form.comment-form {
62 | max-width:56rem;
63 | }
64 |
65 | .reddit .reddit-wrapper {
66 | padding-left: 6rem;
67 | }
68 |
69 | .reddit .votebuttons {
70 | position: absolute;
71 | z-index: 2;
72 | }
73 |
74 |
75 |
76 | /* ===VOTE BUTTONS=== */
77 | .votebuttons {
78 | text-align: center;
79 | width: 5rem;
80 | }
81 |
82 | .votebuttons .upvote, .votebuttons .downvote {
83 | width: 3.2rem;
84 | height: 3.2rem;
85 | fill: #4F4A4A;
86 | }
87 |
88 | .votebuttons .upvote:hover, .votebuttons .downvote:hover {
89 | cursor: pointer;
90 | cursor: hand;
91 | }
92 |
93 | .votebuttons .upvote:hover, .votebuttons .upvote.active {
94 | fill: #4BC35F;
95 | }
96 |
97 | .votebuttons .downvote:hover, .votebuttons .downvote.active {
98 | fill: #C15044;
99 | }
100 |
101 | .votebuttons .vote_sum {
102 | font-size: 3.6rem;
103 | font-family: "Droid Sans", sans-serif;
104 | }
105 |
106 | /* ===NEW REDDIT=== */
107 |
108 | .new-reddit input {
109 | max-width: 56rem;
110 | display: block;
111 | }
112 |
113 | /* ===LANGUAGE=== */
114 |
115 | .language-chooser {
116 | float: left;
117 | margin-left: 1rem;
118 | margin-top: 2rem;
119 | }
120 |
121 | .language-chooser > a {
122 | font-size: 1rem;
123 | font-weight: bold;
124 | padding: 0.3rem;
125 | }
126 |
127 |
128 | /* ===COMMENTS=== */
129 | .comments {
130 | clear: left;
131 | padding-left: 6rem;
132 | }
133 |
134 | .comment {
135 | margin-bottom: 2rem;
136 | position: relative;
137 | display:block;
138 | min-height: 8.5rem;
139 | max-width:56rem;
140 | display:block;
141 | }
142 |
143 | .comment .votebuttons {
144 | position: absolute;
145 | z-index: 2;
146 | }
147 |
148 | .comment .comment-wrapper {
149 | padding-left: 6rem;
150 | }
151 |
152 | .comment-text {
153 | }
154 |
155 | .comment-create-link img {
156 | width: 3.2rem;
157 | height: 3.2rem;
158 | fill: #4F4A4A;
159 | }
--------------------------------------------------------------------------------
/public/old/redditEntry.xhtml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
16 |
17 |
20 |
21 |
22 | #{cc.reddit.votes.votesCount}
23 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | #{cc.reddit.title}
36 |
37 |
38 |
39 | #{cc.timeAgo} #{cc.reddit.user.name}
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/public/services/loginService.js:
--------------------------------------------------------------------------------
1 | redditclone.factory('loginService', ['$http', function($http) {
2 | return {
3 | loggedIn: false,
4 | user: { username: "", password: "" },
5 | logout: function() {
6 | this.loggedIn = false;
7 | sessionStorage.username = "";
8 | sessionStorage.password = "";
9 | },
10 | login: function(username, password, callback) {
11 | $http.post('/login', { "name": username, "password": password })
12 | .success(function(data, status, headers, config) {
13 | console.log("User " + username + " logged in");
14 | this.loggedIn = true;
15 | this.user = { username: username, password: password };
16 | sessionStorage.username = username;
17 | sessionStorage.password = password;
18 | callback();
19 | }.bind(this))
20 | .error(function(data, status, headers, config) {
21 | this.loggedIn = false;
22 | }.bind(this));
23 | },
24 | register: function(username, password, callback) {
25 | $http.post('/register', { "name": username, "password": password })
26 | .success(function(data, status, headers, config) {
27 | console.log("User " + username + " registered");
28 | this.login(name, password, function() {
29 | callback();
30 | });
31 | }.bind(this))
32 | .error(function(data, status, headers, config) {
33 | this.loggedIn = false;
34 | }.bind(this));
35 | }
36 | };
37 | }]);
38 |
--------------------------------------------------------------------------------
/public/services/socketService.js:
--------------------------------------------------------------------------------
1 | redditclone.factory('socketService', function($rootScope) {
2 | var socket = io.connect();
3 | return {
4 | on: function(eventName, callback) {
5 | socket.on(eventName, function() {
6 | var args = arguments;
7 | console.log(eventName);
8 | $rootScope.$apply(function() {
9 | callback.apply(socket, args);
10 | });
11 | });
12 | },
13 | emit: function(eventName, data, callback) {
14 | if(typeof data == 'function') {
15 | callback = data;
16 | data = {};
17 | }
18 | socket.emit(eventName, data, function() {
19 | var args = arguments;
20 | $rootScope.$apply(function() {
21 | if(callback) {
22 | callback.apply(socket, args);
23 | }
24 | });
25 | });
26 | },
27 | emitAndListen: function(eventName, data, callback) {
28 | this.emit(eventName, data, callback);
29 | this.on(eventName, callback);
30 | }
31 | };
32 | });
33 |
--------------------------------------------------------------------------------
/public/view/404.html:
--------------------------------------------------------------------------------
1 |
2 |

3 |
--------------------------------------------------------------------------------
/public/view/newReddit.html:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/public/view/table.html:
--------------------------------------------------------------------------------
1 |
2 |
60 |
--------------------------------------------------------------------------------
/rating.js:
--------------------------------------------------------------------------------
1 | module.exports = function Rating() {
2 | this.value = 0;
3 | var voters = [];
4 | var self = this;
5 |
6 | this._up = function(userId) {
7 | if (!voters[userId]) {
8 | self.value++;
9 | voters[userId] = true;
10 | }
11 | return self.value;
12 | };
13 |
14 | this._down = function (userId) {
15 | if (!voters[userId]) {
16 | self.value--;
17 | voters[userId] = true;
18 | }
19 | return self.value;
20 | };
21 | };
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukasmartinelli-alt/reddit-clone-js/e67d1e44cd25bfec2c7a98b1c7b7861e994bd0c8/screenshot.png
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var User = require('./user.js');
3 | var Link = require('./link.js');
4 | var Comment = require('./comment.js');
5 | var http = require('http');
6 | var io = require('socket.io');
7 |
8 | var allowCrossDomain = function(req, res, next) {
9 | res.header('Access-Control-Allow-Origin', '*');
10 | res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
11 | res.header('Access-Control-Allow-Headers', 'Content-Type');
12 | next();
13 | };
14 |
15 | var app = express();
16 | app.use(allowCrossDomain);
17 | app.use(express.bodyParser());
18 | app.use(express.cookieParser());
19 | app.use(express.session({secret: '2234567890QWERTY'}));
20 | app.use(app.router);
21 |
22 |
23 | function checkAuth(req, res, next) {
24 | if (typeof(req.session.user_id) == "number") {
25 | next();
26 | } else {
27 | res.send('You are not authorized!');
28 | }
29 | }
30 |
31 | var entries = [];
32 | var users = [];
33 | var comments = [];
34 |
35 | //sample data
36 |
37 | entries.push(new Link(entries.length, "Title", "Author", "http://www.google.ch"));
38 | var comment = new Comment(0, "TestComment", "Author");
39 | comments.push(comment);
40 | entries[0].comments.push(comment);
41 |
42 | var entry1 = new Link(entries.length, "Dorfmarkt knackt Umsatzrekord", "Piter Sommerlat", "http://www.20min.ch");
43 | entry1.rating._up(users[0]);
44 | entries.push(entry1);
45 |
46 | //default user
47 | users.push(new User(users.length, "a", "a") );
48 |
49 | function findUser(name)
50 | {
51 | for (var i in users)
52 | {
53 | var user = users[i];
54 | if( user.name == name)
55 | {
56 | return user;
57 | }
58 | }
59 | return null;
60 | }
61 |
62 | function returnIndex(res, id, array) {
63 | if (array.length <= id || id < 0) {
64 | res.statusCode = 404;
65 | return res.send('Error 404: No entry found');
66 | }
67 | return res.json(array[id]);
68 | }
69 |
70 | app.get('/', function(req, res) {
71 | res.type('text/plain');
72 | res.json(entries);
73 | });
74 |
75 | app.get('/login', function (req, res) {
76 | if (typeof (req.session.user_id) == "number") {
77 | res.json(users[req.session.user_id].name);
78 | return;
79 | }
80 | res.json("");
81 | });
82 |
83 | app.post('/login', function (req, res) {
84 | var post = req.body;
85 | var user = findUser(post.name);
86 | if( !!user && post.password == user.password)
87 | {
88 | req.session.user_id = user.id;
89 | res.json(true);
90 | return;
91 | }
92 | res.json(false);
93 | });
94 |
95 | app.post('/register', function(req, res) {
96 | var post = req.body;
97 |
98 | if (typeof(post.name) != "string" || typeof(post.password) != "string") {
99 | res.json(false);
100 | return;
101 | }
102 |
103 | if (findUser(post.name)) {
104 | res.json(false);
105 | return;
106 | }
107 | users.push(new User(users.length, post.name, post.password));
108 | res.json(true);
109 | });
110 |
111 | app.get('/users', function (req, res) {
112 | res.json(users);
113 | });
114 |
115 |
116 |
117 | app.get('/entries', function (req, res) {
118 | res.json(entries);
119 | });
120 |
121 |
122 | app.post('/entry', function(req, res) {
123 | var newLink = new Link(entries.length, req.body.title, req.body.username, req.body.url);
124 | entries.push(newLink);
125 | res.json(newLink);
126 | io.sockets.emit('message', { action: "AddLink" });
127 | });
128 |
129 | app.get('/entry/:id', function(req, res) {
130 | returnIndex(res, req.params.id, entries);
131 | });
132 |
133 | app.post('/entry/:id/up', checkAuth, function (req, res) {
134 | res.json(entries[req.params.id].rating._up(req.session.user_id));
135 | io.sockets.emit('message', { action: "Rated" });
136 | voteState(entries[req.params.id]);
137 | });
138 |
139 | app.post('/entry/:id/down', checkAuth, function (req, res) {
140 | res.json(entries[req.params.id].rating._down(req.session.user_id));
141 | io.sockets.emit('message', { action: "Rated" });
142 | });
143 |
144 | app.post('/entry/:id/comment', checkAuth, function (req, res) {
145 | var newComment = new Comment(comments.length, req.body.text, users[req.session.user_id].name);
146 | comments.push(newComment);
147 |
148 | var entry = entries[req.params.id];
149 | entry.comments.push(newComment);
150 | res.json(newComment);
151 | io.sockets.emit('message', { action: "AddComment" });
152 | });
153 |
154 | app.post('/comment/:id/', checkAuth, function (req, res) {
155 | var newComment = new Comment(comments.length, req.body.text, users[req.session.user_id].name);
156 | comments.push(newComment);
157 |
158 | var comment = comments[req.params.id];
159 | comment.comments.push(newComment);
160 | res.json(newComment);
161 | io.sockets.emit('message', { action: "AddComment" });
162 | });
163 |
164 | app.post('/comment/:id/up', checkAuth, function (req, res) {
165 | res.json(comments[req.params.id].rating._up(req.session.user_id));
166 | io.sockets.emit('message', { action: "Rated" });
167 | voteState(comments[req.params.id]);
168 | });
169 |
170 | app.post('/comment/:id/down', checkAuth, function (req, res) {
171 | res.json(comments[req.params.id].rating._down(req.session.user_id));
172 | io.sockets.emit('message', { action: "Rated" });
173 | });
174 |
175 | app.post('/logout', function (req, res) {
176 | req.session.user_id = null;
177 | res.json(true);
178 | });
179 |
180 | app.use('/', express.static(__dirname + '/public/'));
181 |
182 | //socket:
183 | io = io.listen(app.listen(process.env.PORT || 4730));
184 |
185 | io.sockets.on('connection', function (socket) {
186 | socket.emit('message', { action: 'connected' });
187 |
188 | socket.on('upEntry', function(ids){
189 | entries[ids.eId].rating._up(getUserIdByName(ids.uId));
190 | console.log("upEntry");
191 | voteEntryState(entries[ids.eId]);
192 | });
193 |
194 | socket.on('downEntry', function(ids){
195 | entries[ids.eId].rating._down(getUserIdByName(ids.uId));
196 | console.log("downEntry");
197 | voteEntryState(entries[ids.eId]);
198 | });
199 |
200 |
201 | socket.on('upComment', function(ids){
202 | var index = getCommentArrayIndex(ids.cId);
203 | comments[index].rating._up(getUserIdByName(ids.uId));
204 | console.log("upComment");
205 | voteEntryState(entries[ids.eId]);
206 | });
207 |
208 | socket.on('downComment', function(ids){
209 | var index = getCommentArrayIndex(ids.cId);
210 | comments[index].rating._down(getUserIdByName(ids.uId));
211 | console.log("downComment");
212 | voteEntryState(entries[ids.eId]);
213 | });
214 |
215 | });
216 |
217 | io.sockets.on('disconnect', function (socket) {
218 | socket.emit('message', { action: 'disconnect' });
219 | });
220 |
221 |
222 | voteEntryState = function(entry){
223 | console.log(entry);
224 | io.sockets.emit('voteEntryState', entry);
225 | };
226 |
227 |
228 | getCommentArrayIndex = function(id){
229 | for(i = 0; i < comments.length; i++){
230 | if(comments[i].id === id) {
231 | console.log("index: " + i);
232 | return i;
233 | }
234 | }
235 | return -1;
236 | };
237 |
238 | getUserIdByName = function(name){
239 | for(i = 0; i < users.length; i++){
240 | if(users[i].name === name){
241 | return i;
242 | }
243 | }
244 | return -1;
245 | }
246 |
247 |
--------------------------------------------------------------------------------
/user.js:
--------------------------------------------------------------------------------
1 | module.exports = function User(id, name, pwd) {
2 | this.id = id;
3 | this.name = name;
4 | this.password = pwd;
5 | }
6 |
7 |
--------------------------------------------------------------------------------
26 |