Skip to content
Browse files

socket io is connecting

  • Loading branch information...
1 parent ad929be commit 254740c065a9e7e1ba4e057f55eec1d5c0b1f0a9 @QuincyLarson QuincyLarson committed
View
82 app.js
@@ -42,7 +42,20 @@ var passportConf = require('./config/passport');
* Create Express server.
*/
+var socket = require('socket.io');
+var express = require('express');
+var http = require('http');
+
var app = express();
+var server = http.createServer(app);
+
+server.listen(2999, function() {
+ console.log('server started on %d', 2999);
+});
+
+var io = socket.listen(server);
+
+//console.log('Express server started on port %s', server.address().port);
/**
* Connect to MongoDB.
@@ -205,4 +218,71 @@ app.listen(app.get('port'), function() {
console.log('Express server listening on port %d in %s mode', app.get('port'), app.get('env'));
});
-module.exports = app;
+module.exports = app;
+
+/**
+ * Chat
+ */
+
+var usernames = {};
+var numUsers = 0;
+
+io.on('connection', function (socket) {
+ var addedUser = false;
+
+ // when the client emits 'new message', this listens and executes
+ socket.on('new message', function (data) {
+ // we tell the client to execute 'new message'
+ socket.broadcast.emit('new message', {
+ username: socket.username,
+ message: data
+ });
+ });
+
+ // when the client emits 'add user', this listens and executes
+ socket.on('add user', function (username) {
+ // we store the username in the socket session for this client
+ socket.username = username;
+ // add the client's username to the global list
+ usernames[username] = username;
+ ++numUsers;
+ addedUser = true;
+ socket.emit('login', {
+ numUsers: numUsers
+ });
+ // echo globally (all clients) that a person has connected
+ socket.broadcast.emit('user joined', {
+ username: socket.username,
+ numUsers: numUsers
+ });
+ });
+
+ // when the client emits 'typing', we broadcast it to others
+ socket.on('typing', function () {
+ socket.broadcast.emit('typing', {
+ username: socket.username
+ });
+ });
+
+ // when the client emits 'stop typing', we broadcast it to others
+ socket.on('stop typing', function () {
+ socket.broadcast.emit('stop typing', {
+ username: socket.username
+ });
+ });
+
+ // when the user disconnects.. perform this
+ socket.on('disconnect', function () {
+ // remove the username from global usernames list
+ if (addedUser) {
+ delete usernames[socket.username];
+ --numUsers;
+
+ // echo globally that this client has left
+ socket.broadcast.emit('user left', {
+ username: socket.username,
+ numUsers: numUsers
+ });
+ }
+ });
+});
View
1 config/passport.js
@@ -64,6 +64,7 @@ passport.use(new TwitterStrategy(secrets.twitter, function(req, accessToken, tok
user.profile.name = user.profile.name || profile.displayName;
user.profile.location = user.profile.location || profile._json.location;
user.profile.picture = user.profile.picture || profile._json.profile_image_url_https;
+ user.profile.username = profile.displayName;
user.save(function(err) {
req.flash('info', { msg: 'Twitter account has been linked.' });
done(err, user);
View
2 controllers/curriculum.js
@@ -6,7 +6,5 @@
exports.index = function(req, res) {
res.render('curriculum/curriculum', {
title: 'Curriculum',
- test: 'hi',
- courses: Course.all
});
};
View
3 models/User.js
@@ -15,7 +15,8 @@ var userSchema = new mongoose.Schema({
gender: { type: String, default: '' },
location: { type: String, default: '' },
website: { type: String, default: '' },
- picture: { type: String, default: '' }
+ picture: { type: String, default: '' },
+ username: { type: String, default: '' }
},
resetPasswordToken: String,
View
1 package.json
@@ -49,6 +49,7 @@
"passport-oauth": "^1.0.0",
"passport-twitter": "^1.0.2",
"request": "^2.44.0",
+ "socket.io": "^1.1.0",
"stripe": "^2.8.0",
"tumblr.js": "^0.0.4",
"twilio": "^1.7.0",
View
944 public/css/firechat-default.css
@@ -1,944 +0,0 @@
-@charset "UTF-8";
-/* Boilerplate: Reset
-============================================================ */
-#firechat div,
-#firechat span,
-#firechat applet,
-#firechat object,
-#firechat iframe,
-#firechat h1,
-#firechat h2,
-#firechat h3,
-#firechat h4,
-#firechat h5,
-#firechat h6,
-#firechat p,
-#firechat blockquote,
-#firechat pre,
-#firechat a,
-#firechat abbr,
-#firechat acronym,
-#firechat address,
-#firechat big,
-#firechat cite,
-#firechat code,
-#firechat del,
-#firechat dfn,
-#firechat em,
-#firechat img,
-#firechat ins,
-#firechat kbd,
-#firechat q,
-#firechat s,
-#firechat samp,
-#firechat small,
-#firechat strike,
-#firechat strong,
-#firechat sub,
-#firechat sup,
-#firechat tt,
-#firechat var,
-#firechat b,
-#firechat u,
-#firechat i,
-#firechat center,
-#firechat dl,
-#firechat dt,
-#firechat dd,
-#firechat ol,
-#firechat ul,
-#firechat li,
-#firechat fieldset,
-#firechat form,
-#firechat label,
-#firechat legend,
-#firechat table,
-#firechat caption,
-#firechat tbody,
-#firechat tfoot,
-#firechat thead,
-#firechat tr,
-#firechat th,
-#firechat td,
-#firechat article,
-#firechat aside,
-#firechat canvas,
-#firechat details,
-#firechat embed,
-#firechat figure,
-#firechat figcaption,
-#firechat footer,
-#firechat header,
-#firechat hgroup,
-#firechat menu,
-#firechat nav,
-#firechat output,
-#firechat ruby,
-#firechat section,
-#firechat summary,
-#firechat time,
-#firechat mark,
-#firechat audio,
-#firechat video {
- border: 0;
- font-size: 12px;
- font-family: arial, helvetica, sans-serif;
- vertical-align: baseline;
- margin: 0;
- padding: 0;
-}
-#firechat article,
-#firechat aside,
-#firechat details,
-#firechat figcaption,
-#firechat figure,
-#firechat footer,
-#firechat header,
-#firechat hgroup,
-#firechat menu,
-#firechat nav,
-#firechat section {
- display: block;
-}
-#firechat body {
- line-height: 1;
-}
-#firechat ol,
-#firechat ul {
- list-style: none;
-}
-#firechat blockquote,
-#firechat q {
- quotes: none;
-}
-#firechat blockquote:before,
-#firechat blockquote:after,
-#firechat q:before,
-#firechat q:after {
- content: none;
-}
-#firechat table {
- border-collapse: collapse;
- border-spacing: 0;
-}
-/* Boilerplate: Mixins
-============================================================ */
-.clearfix {
- *zoom: 1;
-}
-.clearfix:before,
-.clearfix:after {
- display: table;
- content: "";
- line-height: 0;
-}
-.clearfix:after {
- clear: both;
-}
-/* Boilerplate: Responsive Layout
-============================================================ */
-#firechat {
- color: #333;
- text-align: left;
-}
-#firechat .center {
- float: none !important;
- margin-left: auto !important;
- margin-right: auto !important;
-}
-#firechat .left {
- float: left !important;
-}
-#firechat .right {
- float: right !important;
-}
-#firechat .alignleft {
- text-align: left !important;
-}
-#firechat .alignright {
- text-align: right !important;
-}
-#firechat .aligncenter {
- text-align: center !important;
-}
-#firechat .hidden {
- display: none !important;
-}
-#firechat .row {
- clear: both;
-}
-#firechat .fifth,
-#firechat .fivesixth,
-#firechat .fourfifth,
-#firechat .half,
-#firechat .ninetenth,
-#firechat .quarter,
-#firechat .sevententh,
-#firechat .sixth,
-#firechat .tenth,
-#firechat .third,
-#firechat .threefifth,
-#firechat .threequarter,
-#firechat .threetenth,
-#firechat .twofifth,
-#firechat .twothird,
-#firechat .full {
- margin-left: 2.127659574468085%;
- float: left;
- min-height: 1px;
-}
-#firechat .fifth:first-child,
-#firechat .fivesixth:first-child,
-#firechat .fourfifth:first-child,
-#firechat .half:first-child,
-#firechat .ninetenth:first-child,
-#firechat .quarter:first-child,
-#firechat .sevententh:first-child,
-#firechat .sixth:first-child,
-#firechat .tenth:first-child,
-#firechat .third:first-child,
-#firechat .threefifth:first-child,
-#firechat .threequarter:first-child,
-#firechat .threetenth:first-child,
-#firechat .twofifth:first-child,
-#firechat .twothird:first-child,
-#firechat .full:first-child {
- margin-left: 0;
-}
-#firechat .tenth {
- width: 8.08510638297872%;
-}
-#firechat .sixth {
- width: 14.893617021276595%;
-}
-#firechat .fifth {
- width: 18.297872340425535%;
-}
-#firechat .quarter {
- width: 23.404255319148938%;
-}
-#firechat .threetenth {
- width: 26.3829787235%;
-}
-#firechat .third {
- width: 31.914893617021278%;
-}
-#firechat .twofifth {
- width: 38.72340425531915%;
-}
-#firechat .half {
- width: 48.93617021276596%;
-}
-#firechat .sevententh {
- width: 58.7234042555%;
-}
-#firechat .threefifth {
- width: 59.14893617021278%;
-}
-#firechat .twothird {
- width: 65.95744680851064%;
-}
-#firechat .threequarter {
- width: 74.46808510638297%;
-}
-#firechat .ninetenth {
- width: 74.8936170215%;
-}
-#firechat .fourfifth {
- width: 79.57446808510639%;
-}
-#firechat .fivesixth {
- width: 82.9787234042553%;
-}
-#firechat .full {
- width: 100%;
-}
-#firechat .clipped {
- overflow: hidden;
-}
-#firechat strong {
- font-weight: bold;
-}
-#firechat em {
- font-style: italic;
-}
-#firechat label {
- display: block;
-}
-#firechat a {
- color: #005580;
-}
-#firechat a:visited,
-#firechat a:hover,
-#firechat a:active {
- color: #005580;
-}
-#firechat p {
- margin: 10px 0;
-}
-#firechat h1,
-#firechat h2,
-#firechat h3,
-#firechat h4,
-#firechat h5,
-#firechat h6 {
- margin: 10px 0;
- font-family: inherit;
- font-weight: bold;
- line-height: 20px;
- color: inherit;
-}
-#firechat h1,
-#firechat h2,
-#firechat h3 {
- line-height: 40px;
-}
-#firechat h1 {
- font-size: 38.5px;
-}
-#firechat h2 {
- font-size: 31.5px;
-}
-#firechat h3 {
- font-size: 24.5px;
-}
-#firechat h4 {
- font-size: 17.5px;
-}
-#firechat h5 {
- font-size: 14px;
-}
-#firechat h6 {
- font-size: 11.9px;
-}
-#firechat small {
- font-size: 90%;
-}
-/* Component: Tabs
-============================================================ */
-#firechat .nav {
- list-style: none;
-}
-#firechat .nav > li > a {
- display: block;
- background-color: #eeeeee;
- text-decoration: none;
- overflow: hidden;
- white-space: nowrap;
-}
-#firechat .nav > li > a:hover,
-#firechat .nav > li > a:focus {
- background-color: #ffffff;
-}
-#firechat .nav-tabs {
- border-bottom: 1px solid #ddd;
- clear: both;
-}
-#firechat .nav-tabs > li {
- float: left;
- margin-bottom: -1px;
- max-width: 45%;
-}
-#firechat .nav-tabs > li > a {
- -webkit-border-top-right-radius: 4px;
- -webkit-border-bottom-right-radius: 0;
- -webkit-border-bottom-left-radius: 0;
- -webkit-border-top-left-radius: 4px;
- -moz-border-radius-topright: 4px;
- -moz-border-radius-bottomright: 0;
- -moz-border-radius-bottomleft: 0;
- -moz-border-radius-topleft: 4px;
- border-top-right-radius: 4px;
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;
- border-top-left-radius: 4px;
- padding: 4px 8px;
- margin-right: 2px;
- line-height: 20px;
- border: 1px solid transparent;
- border-color: #cccccc;
-}
-#firechat .nav-tabs > .active > a,
-#firechat .nav-tabs > .active > a:hover,
-#firechat .nav-tabs > .active > a:focus {
- border-bottom-color: transparent;
- background-color: #ffffff;
- cursor: default;
-}
-#firechat .tab-content {
- overflow: auto;
-}
-#firechat .tab-content > .tab-pane {
- display: none;
-}
-#firechat .tab-content > .active {
- display: block;
- background-color: #ffffff;
-}
-/* Component: dropdowns
-============================================================ */
-#firechat .caret {
- display: inline-block;
- width: 0;
- height: 0;
- vertical-align: top;
- border-top: 4px solid #000000;
- border-right: 4px solid transparent;
- border-left: 4px solid transparent;
- content: "";
- margin-top: 8px;
- margin-left: 2px;
-}
-#firechat .firechat-dropdown {
- position: relative;
-}
-#firechat .firechat-dropdown-toggle {
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -khtml-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- text-decoration: none;
-}
-#firechat .firechat-dropdown-toggle:focus,
-#firechat .firechat-dropdown-toggle:active {
- outline: none;
- text-decoration: none;
-}
-#firechat .firechat-dropdown-toggle.btn {
- padding: 4px 0 0;
- height: 22px;
-}
-#firechat .firechat-dropdown-menu {
- *zoom: 1;
- -webkit-border-top-right-radius: 0;
- -webkit-border-bottom-right-radius: 4px;
- -webkit-border-bottom-left-radius: 4px;
- -webkit-border-top-left-radius: 0;
- -moz-border-radius-topright: 0;
- -moz-border-radius-bottomright: 4px;
- -moz-border-radius-bottomleft: 4px;
- -moz-border-radius-topleft: 0;
- border-top-right-radius: 0;
- border-bottom-right-radius: 4px;
- border-bottom-left-radius: 4px;
- border-top-left-radius: 0;
- z-index: 1000;
- display: none;
- float: left;
- position: absolute;
- top: 100%;
- left: 0;
- width: 100%;
- background-color: #ffffff;
- -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
- -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
- box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
- -webkit-background-clip: padding-box;
- -moz-background-clip: padding;
- background-clip: padding-box;
- border: 1px solid #ccc;
- min-width: 98%;
- padding: 0;
- margin: -1px 0 0;
-}
-#firechat .firechat-dropdown-menu:before,
-#firechat .firechat-dropdown-menu:after {
- display: table;
- content: "";
- line-height: 0;
-}
-#firechat .firechat-dropdown-menu:after {
- clear: both;
-}
-#firechat .firechat-dropdown-menu ul {
- background-color: #ffffff;
- list-style: none;
- overflow-y: scroll;
- max-height: 300px;
-}
-#firechat .firechat-dropdown-menu ul > li > a {
- display: block;
- padding: 1px 1px 1px 3px;
- clear: both;
- font-weight: normal;
- line-height: 20px;
- color: #333333;
- white-space: nowrap;
-}
-#firechat .firechat-dropdown-menu ul > li > a.highlight {
- background-color: #d9edf7;
-}
-#firechat .firechat-dropdown-menu ul > li > a:hover,
-#firechat .firechat-dropdown-menu ul > li > a:focus,
-#firechat .firechat-dropdown-menu ul > .active > a,
-#firechat .firechat-dropdown-menu ul > .active > a:hover,
-#firechat .firechat-dropdown-menu ul > .active > a:focus {
- text-decoration: none;
- color: #000000;
- background-color: #d9edf7;
- outline: 0;
-}
-#firechat .firechat-dropdown-menu ul > .disabled > a,
-#firechat .firechat-dropdown-menu ul > .disabled > a:hover,
-#firechat .firechat-dropdown-menu ul > .disabled > a:focus {
- color: #999999;
- text-decoration: none;
- background-color: transparent;
- background-image: none;
- cursor: default;
-}
-#firechat .firechat-dropdown-header {
- position: relative;
- width: 100%;
- padding: 10px 0;
- background-color: #eeeeee;
- border-bottom: 1px solid #cccccc;
-}
-#firechat .firechat-dropdown-footer {
- position: relative;
- width: 100%;
- padding: 10px 0px;
- background-color: #eeeeee;
- border-top: 1px solid #cccccc;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
-}
-#firechat .open {
- *z-index: 1000;
-}
-#firechat .open > .firechat-dropdown-menu {
- display: block;
- border: 1px solid #cccccc;
- -webkit-border-top-right-radius: 0;
- -webkit-border-bottom-right-radius: 4px;
- -webkit-border-bottom-left-radius: 4px;
- -webkit-border-top-left-radius: 0;
- -moz-border-radius-topright: 0;
- -moz-border-radius-bottomright: 4px;
- -moz-border-radius-bottomleft: 4px;
- -moz-border-radius-topleft: 0;
- border-top-right-radius: 0;
- border-bottom-right-radius: 4px;
- border-bottom-left-radius: 4px;
- border-top-left-radius: 0;
-}
-#firechat .open > .firechat-dropdown-toggle {
- outline: none;
- text-decoration: none;
- -webkit-border-top-right-radius: 4px;
- -webkit-border-bottom-right-radius: 0;
- -webkit-border-bottom-left-radius: 0;
- -webkit-border-top-left-radius: 4px;
- -moz-border-radius-topright: 4px;
- -moz-border-radius-bottomright: 0;
- -moz-border-radius-bottomleft: 0;
- -moz-border-radius-topleft: 4px;
- border-top-right-radius: 4px;
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;
- border-top-left-radius: 4px;
-}
-/* Component: Prompts
-============================================================ */
-#firechat .prompt-wrapper {
- position: absolute;
- z-index: 1000;
-}
-#firechat .prompt {
- position: absolute;
- z-index: 1001;
- background-color: #ffffff;
- -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.45);
- -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.45);
- box-shadow: 0 5px 10px rgba(0, 0, 0, 0.45);
-}
-#firechat .prompt-header {
- padding: 4px 8px;
- font-weight: bold;
- background-color: #eeeeee;
- border: 1px solid #cccccc;
- -webkit-border-top-right-radius: 4px;
- -webkit-border-bottom-right-radius: 0;
- -webkit-border-bottom-left-radius: 0;
- -webkit-border-top-left-radius: 4px;
- -moz-border-radius-topright: 4px;
- -moz-border-radius-bottomright: 0;
- -moz-border-radius-bottomleft: 0;
- -moz-border-radius-topleft: 4px;
- border-top-right-radius: 4px;
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;
- border-top-left-radius: 4px;
-}
-#firechat .prompt-header a.close {
- opacity: 0.6;
- font-size: 13px;
- margin-top: 2px;
-}
-#firechat .prompt-header a.close:hover {
- opacity: 0.9;
-}
-#firechat .prompt-body {
- background-color: #ffffff;
- padding: 4px 8px;
- border-left: 1px solid #cccccc;
- border-right: 1px solid #cccccc;
-}
-#firechat .prompt-footer {
- padding: 4px 8px;
- background-color: #eeeeee;
- border: 1px solid #cccccc;
- -webkit-border-top-right-radius: 0;
- -webkit-border-bottom-right-radius: 4px;
- -webkit-border-bottom-left-radius: 4px;
- -webkit-border-top-left-radius: 0;
- -moz-border-radius-topright: 0;
- -moz-border-radius-bottomright: 4px;
- -moz-border-radius-bottomleft: 4px;
- -moz-border-radius-topleft: 0;
- border-top-right-radius: 0;
- border-bottom-right-radius: 4px;
- border-bottom-left-radius: 4px;
- border-top-left-radius: 0;
-}
-#firechat .prompt-background {
- background-color: #333333;
- border: 1px solid #333333;
- opacity: 0.8;
- z-index: 1000;
- height: 100%;
- width: 100%;
-}
-/* Component: Buttons
-============================================================ */
-#firechat .btn {
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -khtml-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
- height: 24px;
- display: inline-block;
- *display: inline;
- *zoom: 1;
- padding: 2px 5px;
- margin-bottom: 0;
- text-align: center;
- vertical-align: middle;
- cursor: pointer;
- color: #333333;
- font-size: 12px;
- text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
- background-color: #f5f5f5;
- background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
- background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
- background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
- background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);
- border-color: #e6e6e6 #e6e6e6 #bfbfbf;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- *background-color: #e6e6e6;
- filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
- border: 1px solid #cccccc;
- *border: 0;
- border-bottom-color: #b3b3b3;
- *margin-left: .3em;
- -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-#firechat .btn:hover,
-#firechat .btn:focus,
-#firechat .btn:active,
-#firechat .btn.active,
-#firechat .btn.disabled,
-#firechat .btn[disabled] {
- color: #333333;
- background-color: #e6e6e6;
- *background-color: #d9d9d9;
- outline: 0;
-}
-#firechat .btn:active,
-#firechat .btn.active {
- background-color: #cccccc;
-}
-#firechat .btn:first-child {
- *margin-left: 0;
-}
-#firechat .btn:hover,
-#firechat .btn:focus {
- color: #333333;
- text-decoration: none;
- background-position: 0 -15px;
- -webkit-transition: background-position 0.1s linear;
- -moz-transition: background-position 0.1s linear;
- -o-transition: background-position 0.1s linear;
- transition: background-position 0.1s linear;
-}
-#firechat .btn.active,
-#firechat .btn:active {
- background-image: none;
- outline: 0;
- -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
- -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
- box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-#firechat .btn.disabled,
-#firechat .btn[disabled] {
- cursor: default;
- background-image: none;
- opacity: 0.65;
- filter: alpha(opacity=65);
-}
-#firechat .btn.disabled:active,
-#firechat .btn[disabled]:active {
- -webkit-box-shadow: inherit;
- -moz-box-shadow: inherit;
- box-shadow: inherit;
- background-color: #e6e6e6;
-}
-/* Component: Context Menu
-============================================================ */
-#firechat .contextmenu {
- position: fixed;
- z-index: 1001;
- min-width: 150px;
- border: 1px solid #cccccc;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
-}
-#firechat .contextmenu ul {
- background-color: #ffffff;
- list-style: none;
-}
-#firechat .contextmenu ul > li > a {
- display: block;
- padding: 3px 10px;
- clear: both;
- font-weight: normal;
- line-height: 20px;
- color: #333333;
- white-space: nowrap;
-}
-#firechat .contextmenu ul > li > a.highlight {
- background-color: #d9edf7;
-}
-#firechat .contextmenu ul > li > a:hover,
-#firechat .contextmenu ul > li > a:focus {
- text-decoration: none;
- color: #ffffff;
- background-color: #0081c2;
- outline: 0;
-}
-/* Custom Styles
-============================================================ */
-#firechat {
- padding: 0;
- font-family: sans-serif;
- font-size: 12px;
- line-height: 18px;
-}
-#firechat input,
-#firechat textarea {
- width: 100%;
- font-family: sans-serif;
- font-size: 12px;
- line-height: 18px;
- padding: 2px 5px;
- border: 1px solid #cccccc;
- -webkit-border-radius: 1px;
- -moz-border-radius: 1px;
- border-radius: 1px;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
-}
-#firechat input:-moz-placeholder,
-#firechat textarea:-moz-placeholder {
- color: #aaaaaa;
-}
-#firechat input:-ms-input-placeholder,
-#firechat textarea:-ms-input-placeholder {
- color: #aaaaaa;
-}
-#firechat input::-webkit-input-placeholder,
-#firechat textarea::-webkit-input-placeholder {
- color: #aaaaaa;
-}
-#firechat input[disabled],
-#firechat textarea[disabled] {
- background-color: #eeeeee;
-}
-#firechat input {
- height: 24px;
-}
-#firechat textarea {
- resize: none;
- height: 40px;
-}
-#firechat .search-wrapper {
- -webkit-border-radius: 15px;
- -moz-border-radius: 15px;
- border-radius: 15px;
- border: 1px solid #cccccc;
- margin: 0 5px;
- padding: 2px 5px;
- background: #ffffff;
-}
-#firechat .search-wrapper > input[type=text] {
- padding-left: 0px;
- border: none;
-}
-#firechat .search-wrapper > input[type=text]:focus,
-#firechat .search-wrapper > input[type=text]:active {
- outline: 0;
-}
-#firechat .chat {
- overflow: auto;
- -ms-overflow-x: hidden;
- overflow-x: hidden;
- height: 290px;
- position: relative;
- margin-bottom: 5px;
- border: 1px solid #cccccc;
- border-top: none;
- overflow-y: scroll;
-}
-#firechat .chat textarea {
- overflow: auto;
- vertical-align: top;
-}
-#firechat .message {
- color: #333;
- padding: 3px 5px;
- border-bottom: 1px solid #ccc;
-}
-#firechat .message.highlighted {
- background-color: #d9edf7;
-}
-#firechat .message .name {
- font-weight: bold;
- overflow-x: hidden;
-}
-#firechat .message.message-self {
- color: #2675ab;
-}
-#firechat .message:nth-child(odd) {
- background-color: #f9f9f9;
-}
-#firechat .message:nth-child(odd).highlighted {
- background-color: #d9edf7;
-}
-#firechat .message:nth-child(odd).message-local {
- background-color: #effafc;
-}
-#firechat .message-content {
- word-wrap: break-word;
- padding-right: 45px;
-}
-#firechat .message-content.red {
- color: red;
-}
-#firechat .message.message-notification .message-content {
- font-style: italic;
-}
-#firechat ul::-webkit-scrollbar {
- -webkit-appearance: none;
- width: 7px;
-}
-#firechat ul::-webkit-scrollbar-thumb {
- border-radius: 4px;
- -webkit-box-shadow: 0 0 1px rgba(255, 255, 255, 0.5);
-}
-#firechat #firechat-header {
- padding: 6px 0 0 0;
- height: 40px;
-}
-#firechat #firechat-tabs {
- height: 435px;
-}
-#firechat #firechat-tab-list {
- background-color: #ffffff;
-}
-#firechat #firechat-tab-content {
- width: 100%;
- background-color: #ffffff;
-}
-#firechat .tab-pane-menu {
- border: 1px solid #ccc;
- border-top: none;
- vertical-align: middle;
- padding-bottom: 5px;
-}
-#firechat .tab-pane-menu .firechat-dropdown {
- margin: 5px 0 0 5px;
-}
-#firechat .tab-pane-menu > .icon {
- margin: 5px 2px 0;
-}
-#firechat .icon {
- display: inline-block;
- *margin-right: .3em;
- line-height: 20px;
- vertical-align: middle;
- background-repeat: no-repeat;
- padding: 0;
- background: url(data:image/png;base64,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) no-repeat top left;
- opacity: 0.3;
- font-size: 22px;
- font-family: Arial;
- font-weight: bold;
- overflow: hidden;
-}
-#firechat .icon.plus {
- margin-top: 0;
- vertical-align: top;
- background: transparent;
-}
-#firechat .icon.search {
- background-position: 0 0;
- width: 13px;
- height: 13px;
-}
-#firechat .icon.close {
- background-position: -120px 0;
- width: 13px;
- height: 13px;
-}
-#firechat .icon.user-chat {
- background-position: -138px 0;
- width: 17px;
- height: 13px;
-}
-#firechat .icon.user-group {
- background-position: -18px 0;
- width: 17px;
- height: 13px;
-}
-#firechat .icon.user-mute {
- background-position: -84px 0;
- width: 13px;
- height: 13px;
-}
-#firechat .icon.user-mute.red {
- background-position: -102px 0;
- width: 13px;
- height: 13px;
-}
-#firechat .icon:hover,
-#firechat .btn:hover > .icon {
- opacity: 0.6;
-}
-#firechat a > .icon {
- margin: 3px 1px;
-}
View
123 public/css/styles.less
@@ -97,4 +97,127 @@ body { margin: 0; height: 100%; position: relative; }
.btn-nav {
margin-top: 5px;
+}
+
+ul {
+ list-style: none;
+ word-wrap: break-word;
+}
+
+/* Pages */
+
+.pages {
+ height: inherit;
+ margin: 0;
+ padding: 0;
+ width: inherit;
+}
+
+.page {
+ height: 100%;
+ position: absolute;
+ width: 100%;
+}
+
+/* Login Page */
+
+.login.page {
+ background-color: #000;
+}
+
+.login.page .form {
+ height: 100px;
+ margin-top: -100px;
+ position: absolute;
+
+ text-align: center;
+ top: 50%;
+ width: 100%;
+}
+
+.login.page .form .usernameInput {
+ background-color: transparent;
+ border: none;
+ border-bottom: 2px solid #fff;
+ outline: none;
+ padding-bottom: 15px;
+ text-align: center;
+ width: 400px;
+}
+
+.login.page .title {
+ font-size: 200%;
+}
+
+.login.page .usernameInput {
+ font-size: 200%;
+ letter-spacing: 3px;
+}
+
+.login.page .title, .login.page .usernameInput {
+ color: #fff;
+ font-weight: 100;
+}
+
+/* Chat page */
+
+.chat.page {
+ display: none;
+}
+
+/* Font */
+
+.messages {
+ font-size: 150%;
+}
+
+.inputMessage {
+ font-size: 100%;
+}
+
+.log {
+ color: gray;
+ font-size: 70%;
+ margin: 5px;
+ text-align: center;
+}
+
+/* Messages */
+
+.chatArea {
+ height: 100%;
+ padding-bottom: 60px;
+}
+
+.messages {
+ height: 100%;
+ margin: 0;
+ overflow-y: scroll;
+ padding: 10px 20px 10px 20px;
+}
+
+.message.typing .messageBody {
+ color: gray;
+}
+
+.username {
+ float: left;
+ font-weight: 700;
+ overflow: hidden;
+ padding-right: 15px;
+ text-align: right;
+}
+
+/* Input */
+
+.inputMessage {
+ border: 10px solid #000;
+ bottom: 0;
+ height: 60px;
+ left: 0;
+ outline: none;
+ padding-left: 10px;
+ position: absolute;
+ right: 0;
+ width: 100%;
}
View
1,869 public/js/firechat-default.js
0 additions, 1,869 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
283 public/js/main.js
@@ -1,38 +1,269 @@
$(document).ready(function() {
- function init() {
- var firepadRef = getExampleRef();
- var ref = new Firebase('scorching-heat-2873.firebaseIO.com');
- var codeMirror = CodeMirror(document.getElementById('firepad-container'), {
- lineNumbers: true,
- mode: 'javascript'
- });
- var firepad = Firepad.fromCodeMirror(firepadRef, codeMirror, {
- defaultText: '// JavaScript Editing with Firepad!\\nfunction go() {\n var message = "Hello, world.";\n console.log(message);\n}'
+ var FADE_TIME = 150; // ms
+ var TYPING_TIMER_LENGTH = 400; // ms
+ var COLORS = [
+ '#e21400', '#91580f', '#f8a700', '#f78b00',
+ '#58dc00', '#287b00', '#a8f07a', '#4ae8c4',
+ '#3b88eb', '#3824aa', '#a700ff', '#d300e7'
+ ];
+
+ // Initialize varibles
+ var $window = $(window);
+ var $usernameInput = $('.usernameInput'); // Input for username
+ var $messages = $('.messages'); // Messages area
+ var $inputMessage = $('.inputMessage'); // Input message input box
+
+ var $loginPage = $('.login.page'); // The login page
+ var $chatPage = $('.chat.page'); // The chatroom page
+
+ // Prompt for setting a username
+ var username;
+ var connected = false;
+ var typing = false;
+ var lastTypingTime;
+ var $currentInput = $usernameInput.focus();
+
+ var socket = io("http://localhost:2999");
+
+
+ function addParticipantsMessage (data) {
+ var message = '';
+ if (data.numUsers === 1) {
+ message += "there's 1 participant";
+ } else {
+ message += "there are " + data.numUsers + " participants";
+ }
+ log(message);
+ }
+
+ // Sets the client's username
+ function setUsername () {
+ username = cleanInput($usernameInput.val().trim());
+
+ // If the username is valid
+ if (username) {
+ $loginPage.fadeOut();
+ $chatPage.show();
+ $loginPage.off('click');
+ $currentInput = $inputMessage.focus();
+
+ // Tell the server your username
+ socket.emit('add user', username);
+ }
+ }
+
+ // Sends a chat message
+ function sendMessage () {
+ var message = $inputMessage.val();
+ // Prevent markup from being injected into the message
+ message = cleanInput(message);
+ // if there is a non-empty message and a socket connection
+ if (message && connected) {
+ $inputMessage.val('');
+ addChatMessage({
+ username: username,
+ message: message
+ });
+ // tell server to execute 'new message' and send along one parameter
+ socket.emit('new message', message);
+ }
+ }
+
+ // Log a message
+ function log (message, options) {
+ var $el = $('<li>').addClass('log').text(message);
+ addMessageElement($el, options);
+ }
+
+ // Adds the visual chat message to the message list
+ function addChatMessage (data, options) {
+ // Don't fade the message in if there is an 'X was typing'
+ var $typingMessages = getTypingMessages(data);
+ options = options || {};
+ if ($typingMessages.length !== 0) {
+ options.fade = false;
+ $typingMessages.remove();
+ }
+
+ var $usernameDiv = $('<span class="username"/>')
+ .text(data.username)
+ .css('color', getUsernameColor(data.username));
+ var $messageBodyDiv = $('<span class="messageBody">')
+ .text(data.message);
+
+ var typingClass = data.typing ? 'typing' : '';
+ var $messageDiv = $('<li class="message"/>')
+ .data('username', data.username)
+ .addClass(typingClass)
+ .append($usernameDiv, $messageBodyDiv);
+
+ addMessageElement($messageDiv, options);
+ }
+
+ // Adds the visual chat typing message
+ function addChatTyping (data) {
+ data.typing = true;
+ data.message = 'is typing';
+ addChatMessage(data);
+ }
+
+ // Removes the visual chat typing message
+ function removeChatTyping (data) {
+ getTypingMessages(data).fadeOut(function () {
+ $(this).remove();
});
}
- function getExampleRef() {
- var ref = new Firebase('https://firepad.firebaseio-demo.com');
- var hash = window.location.hash.replace(/#/g, '');
- if (hash) {
- ref = ref.child(hash);
+
+ // Adds a message element to the messages and scrolls to the bottom
+ // el - The element to add as a message
+ // options.fade - If the element should fade-in (default = true)
+ // options.prepend - If the element should prepend
+ // all other messages (default = false)
+ function addMessageElement (el, options) {
+ var $el = $(el);
+
+ // Setup default options
+ if (!options) {
+ options = {};
+ }
+ if (typeof options.fade === 'undefined') {
+ options.fade = true;
+ }
+ if (typeof options.prepend === 'undefined') {
+ options.prepend = false;
+ }
+
+ // Apply options
+ if (options.fade) {
+ $el.hide().fadeIn(FADE_TIME);
+ }
+ if (options.prepend) {
+ $messages.prepend($el);
} else {
- ref = ref.push(); // generate unique location.
- window.location = window.location + '#' + ref.name(); // add it as a hash to the URL.
+ $messages.append($el);
}
- if (typeof console !== 'undefined')
- console.log('Firebase data: ', ref.toString());
- return ref;
+ $messages[0].scrollTop = $messages[0].scrollHeight;
}
- init();
- var chatRef = new Firebase('https://scorching-heat-2873.firebaseio.com/chat');
- var auth = new FirebaseSimpleLogin(chatRef, function(err, user) {
- console.log("HEY!")
- if (user) {
- var chat = new FirechatUI(chatRef, document.getElementById('firechat-wrapper'));
- chat.setUser(user.uid, user.displayName);
+
+ // Prevents input from having injected markup
+ function cleanInput (input) {
+ return $('<div/>').text(input).text();
+ }
+
+ // Updates the typing event
+ function updateTyping () {
+ if (connected) {
+ if (!typing) {
+ typing = true;
+ socket.emit('typing');
+ }
+ lastTypingTime = (new Date()).getTime();
+
+ setTimeout(function () {
+ var typingTimer = (new Date()).getTime();
+ var timeDiff = typingTimer - lastTypingTime;
+ if (timeDiff >= TYPING_TIMER_LENGTH && typing) {
+ socket.emit('stop typing');
+ typing = false;
+ }
+ }, TYPING_TIMER_LENGTH);
+ }
+ }
+
+ // Gets the 'X is typing' messages of a user
+ function getTypingMessages (data) {
+ return $('.typing.message').filter(function (i) {
+ return $(this).data('username') === data.username;
+ });
+ }
+
+ // Gets the color of a username through our hash function
+ function getUsernameColor (username) {
+ // Compute hash code
+ var hash = 7;
+ for (var i = 0; i < username.length; i++) {
+ hash = username.charCodeAt(i) + (hash << 5) - hash;
+ }
+ // Calculate color
+ var index = Math.abs(hash % COLORS.length);
+ return COLORS[index];
+ }
+
+ // Keyboard events
+
+ $window.keydown(function (event) {
+ // Auto-focus the current input when a key is typed
+ if (!(event.ctrlKey || event.metaKey || event.altKey)) {
+ $currentInput.focus();
}
+ // When the client hits ENTER on their keyboard
+ if (event.which === 13) {
+ if (username) {
+ sendMessage();
+ socket.emit('stop typing');
+ typing = false;
+ } else {
+ setUsername();
+ }
+ }
+ });
+
+ $inputMessage.on('input', function() {
+ updateTyping();
});
+ // Click events
+
+ // Focus input when clicking anywhere on login page
+ $loginPage.click(function () {
+ $currentInput.focus();
+ });
+
+ // Focus input when clicking on the message input's border
+ $inputMessage.click(function () {
+ $inputMessage.focus();
+ });
+
+ // Socket events
+
+ // Whenever the server emits 'login', log the login message
+ socket.on('login', function (data) {
+ connected = true;
+ // Display the welcome message
+ var message = "Welcome to Socket.IO Chat – ";
+ log(message, {
+ prepend: true
+ });
+ addParticipantsMessage(data);
+ });
+
+ // Whenever the server emits 'new message', update the chat body
+ socket.on('new message', function (data) {
+ addChatMessage(data);
+ });
+
+ // Whenever the server emits 'user joined', log it in the chat body
+ socket.on('user joined', function (data) {
+ log(data.username + ' joined');
+ addParticipantsMessage(data);
+ });
+
+ // Whenever the server emits 'user left', log it in the chat body
+ socket.on('user left', function (data) {
+ log(data.username + ' left');
+ addParticipantsMessage(data);
+ removeChatTyping(data);
+ });
+
+ // Whenever the server emits 'typing', show the typing message
+ socket.on('typing', function (data) {
+ addChatTyping(data);
+ });
+
+ // Whenever the server emits 'stop typing', kill the typing message
+ socket.on('stop typing', function (data) {
+ removeChatTyping(data);
+ });
});
View
12 views/curriculum/curriculum.jade
@@ -2,4 +2,14 @@ extends ../layout
block content
.page-header
- h3 Your Curriculum
+ h3 Your Curriculum
+ .col-xs-12.col-sm-12.col-md-12
+ ul.pages
+ li.chat.page
+ div.chatArea
+ ul.messages
+ input.inputMessage(placeholder='Type here...')
+ li.login.page
+ div.form
+ h3.title What's your nickname?
+ input.usernameInput(type='text', maxlength='14')
View
1 views/layout.jade
@@ -7,6 +7,7 @@ html
meta(name='description', content='')
meta(name='csrf-token', content=_csrf)
meta(name='author', content='')
+ script(src='https://cdn.socket.io/socket.io-1.0.0.js')
title #{title} | Free Code Camp
!= css('styles')
body

0 comments on commit 254740c

Please sign in to comment.
Something went wrong with that request. Please try again.