From 8f77adff820c4818b460e7249109d3908dc0479c Mon Sep 17 00:00:00 2001 From: rabGIT Date: Tue, 9 May 2017 08:26:58 -0700 Subject: [PATCH 1/9] initial commit --- .gitignore | 1 + README.md | 2 + app.js | 48 +++++++++++++++++++ bin/www | 90 ++++++++++++++++++++++++++++++++++++ package.json | 20 ++++++++ public/stylesheets/style.css | 8 ++++ routes/index.js | 9 ++++ routes/users.js | 9 ++++ views/error.hbs | 3 ++ views/index.hbs | 2 + views/layout.hbs | 49 ++++++++++++++++++++ 11 files changed, 241 insertions(+) create mode 100644 .gitignore create mode 100644 app.js create mode 100755 bin/www create mode 100644 package.json create mode 100644 public/stylesheets/style.css create mode 100644 routes/index.js create mode 100644 routes/users.js create mode 100644 views/error.hbs create mode 100644 views/index.hbs create mode 100644 views/layout.hbs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2ccbe46 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/node_modules/ diff --git a/README.md b/README.md index 299362a..912f843 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # project_superchat Build a realtime multi-room chat application. Make it super. + +Richard Bell diff --git a/app.js b/app.js new file mode 100644 index 0000000..6033d37 --- /dev/null +++ b/app.js @@ -0,0 +1,48 @@ +var express = require('express'); +var path = require('path'); +var favicon = require('serve-favicon'); +var logger = require('morgan'); +var cookieParser = require('cookie-parser'); +var bodyParser = require('body-parser'); + +var index = require('./routes/index'); +var users = require('./routes/users'); + +var app = express(); +var server = require('http').Server(app); +var io = require('socket.io')(server); + +// view engine setup +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'hbs'); + +// uncomment after placing your favicon in /public +//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); +app.use(logger('dev')); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: false })); +app.use(cookieParser()); +app.use(express.static(path.join(__dirname, 'public'))); + +app.use('/', index); +app.use('/users', users); + +// catch 404 and forward to error handler +app.use(function(req, res, next) { + var err = new Error('Not Found'); + err.status = 404; + next(err); +}); + +// error handler +app.use(function(err, req, res, next) { + // set locals, only providing error in development + res.locals.message = err.message; + res.locals.error = req.app.get('env') === 'development' ? err : {}; + + // render the error page + res.status(err.status || 500); + res.render('error'); +}); + +module.exports = {app: app, server: server}; diff --git a/bin/www b/bin/www new file mode 100755 index 0000000..78f4759 --- /dev/null +++ b/bin/www @@ -0,0 +1,90 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var app = require('../app').app; +var debug = require('debug')('project-superchat:server'); +var http = require('http'); + +/** + * Get port from environment and store in Express. + */ + +var port = normalizePort(process.env.PORT || '3000'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +var server = require('../app').server; + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + debug('Listening on ' + bind); +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..69b8ac8 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "project-superchat", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./bin/www" + }, + "dependencies": { + "body-parser": "~1.17.1", + "cookie-parser": "~1.4.3", + "debug": "~2.6.3", + "express": "^4.15.2", + "hbs": "~4.0.1", + "morgan": "~1.8.1", + "redis": "^2.7.1", + "serve-favicon": "~2.4.2", + "socket.io": "^2.0.1", + "socket.io-client": "^2.0.1" + } +} diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css new file mode 100644 index 0000000..9453385 --- /dev/null +++ b/public/stylesheets/style.css @@ -0,0 +1,8 @@ +body { + padding: 50px; + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; +} + +a { + color: #00B7FF; +} diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..ecca96a --- /dev/null +++ b/routes/index.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET home page. */ +router.get('/', function(req, res, next) { + res.render('index', { title: 'Express' }); +}); + +module.exports = router; diff --git a/routes/users.js b/routes/users.js new file mode 100644 index 0000000..623e430 --- /dev/null +++ b/routes/users.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET users listing. */ +router.get('/', function(req, res, next) { + res.send('respond with a resource'); +}); + +module.exports = router; diff --git a/views/error.hbs b/views/error.hbs new file mode 100644 index 0000000..0659765 --- /dev/null +++ b/views/error.hbs @@ -0,0 +1,3 @@ +

{{message}}

+

{{error.status}}

+
{{error.stack}}
diff --git a/views/index.hbs b/views/index.hbs new file mode 100644 index 0000000..1f308fd --- /dev/null +++ b/views/index.hbs @@ -0,0 +1,2 @@ +

{{title}}

+

Welcome to {{title}}

diff --git a/views/layout.hbs b/views/layout.hbs new file mode 100644 index 0000000..0f7ad03 --- /dev/null +++ b/views/layout.hbs @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + {{title}} + + + + +
+ {{{body}}} +
+ + + + + + + + + + + + + From 7ccc14900c343782e52fbfb3ef981c885d5ecd63 Mon Sep 17 00:00:00 2001 From: rabGIT Date: Tue, 9 May 2017 10:40:21 -0700 Subject: [PATCH 2/9] data management module --- bin/dataMgr.js | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 bin/dataMgr.js diff --git a/bin/dataMgr.js b/bin/dataMgr.js new file mode 100644 index 0000000..8d673ca --- /dev/null +++ b/bin/dataMgr.js @@ -0,0 +1,152 @@ +const redisClient = require("redis").createClient(); +const debug = require('debug')('dataMgr'); +const ROOMKEY = "rooms"; +const USERKEY = "users"; + +redisClient.flushall(); + +// promise returns 1 for room add 0 for duplicate room +function addRoom(room) { + debug(`requesting add room "${room}"`); + return new Promise(function(resolve, reject) { + redisClient.sadd(ROOMKEY, room, function(err, data) { + if (err) reject(err); + debug(`room added "${room}"`); + resolve(data); + }); + }); +} + +// promise returns array with list of rooms +function listRooms() { + debug(`requesting room list`); + return new Promise(function(resolve, reject) { + redisClient.smembers(ROOMKEY, function(err, data) { + if (err) reject(err); + debug('returning room list'); + resolve(data); + }); + }); +} + +function addUser(userName, userProfile) { + debug(`adding new user "${userName}" with profile ${userProfile}`); + return new Promise(function(resolve, reject) { + redisClient.hset(USERKEY, userName, JSON.stringify(userProfile), function(err, data) { + if (err) reject(err); + debug(`user added "${userName}"`); + resolve(data); + }); + }); +} + +// promise returns object containing the profile associated with userName or Null object if doesn't exist +function getUser(userName) { + debug(`requesting user "${userName}"`); + return new Promise(function(resolve, reject) { + redisClient.hget(USERKEY, userName, function( err, data) { + if (err) reject(err); + debug(`user "${userName}" returned with profile ${data}`); + resolve(JSON.parse(data)); + }); + }); +} + +// promise returns 1 if user exists and 0 otherwise +function isUser(userName) { + debug(`checking user exists "${userName}"`); + return new Promise(function(resolve, reject) { + redisClient.hexists(USERKEY, userName, function (err, data) { + if (err) reject(err); + debug(`user "${userName}" hexist with response ${data}`); + resolve(data); + }) + }); +} + +// promise resolves to number for message added where number is count of messages in room +function sendMessage(roomName, userName, msgText) { + debug(`sending message "${msgText}" to room "${roomName}" from user "${userName}"`); + return new Promise(function(resolve, reject) { + let message = {text: msgText, + sender: userName, + sentTime: Date.now() }; + redisClient.rpush(roomName, JSON.stringify(message), function (err, data) { + if (err) reject(err); + debug(`sent "${msgText}" to "${roomName}" from "${userName}"`); + resolve(data); + }) + }); +} + +// promise resolves to array containing message objects +function getMessages(roomName) { + debug(`requesting messages for "${roomName}"`); + return new Promise(function(resolve, reject) { + redisClient.lrange(roomName, 0, -1, function(err,data) { + if (err) reject(err); + debug(`messages for room "${roomName}" are "${data}"`); + let msgList = []; + data.forEach(function(message) { + msgList.push(JSON.parse(message)); + }); + resolve(msgList); + }) + }); +} + +module.exports = { + addRoom, + listRooms, + addUser, + getUser, + isUser, + sendMessage, + getMessages +}; + + +/* +sendMessage('test room', 'fred', 'hello world').then(function(data){ + console.log(data); +}); +sendMessage('test room', 'george', 'Goodbye cruel world').then(function(data){ + console.log(data); +}); +getMessages('test room').then(function(data){ + console.log(data); +}); + +addUser('fred', {fullname: 'Fred Smith', createDate: Date.now()}).then(function(data){ + console.log(data); +}); + +getUser('fred').then(function(data){ + console.log(data); +}); + +getUser('george').then(function(data){ + console.log(data); +}); + +isUser('fred').then(function(data){ + console.log(data); +}); +isUser('george').then(function(data){ + console.log(data); +}); + +addRoom("test").then(function(data){ + console.log(data); +}); +addRoom("test1").then(function(data){ + console.log(data); +}); +addRoom("test1").then(function(data){ + console.log(data); +}); +listRooms().then(function(data){ + console.log(data); + process.exit(); +}); +*/ diff --git a/package.json b/package.json index 69b8ac8..84924f7 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "dependencies": { "body-parser": "~1.17.1", "cookie-parser": "~1.4.3", - "debug": "~2.6.3", + "debug": "^2.6.6", "express": "^4.15.2", "hbs": "~4.0.1", "morgan": "~1.8.1", From 02b13208c819d093e684af2e194b99e96fa39b14 Mon Sep 17 00:00:00 2001 From: rabGIT Date: Tue, 9 May 2017 15:51:26 -0700 Subject: [PATCH 3/9] user management/profile --- npm-debug.log | 45 ++++++++++++++++++++++++++++ public/stylesheets/style.css | 13 ++++++++ routes/index.js | 26 +++++++++++++++- routes/users.js | 57 ++++++++++++++++++++++++++++++++++-- views/layout.hbs | 31 ++++++++++++++++++++ views/users.hbs | 56 +++++++++++++++++++++++++++++++++++ 6 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 npm-debug.log create mode 100644 views/users.hbs diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 0000000..243c0a4 --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,45 @@ +0 info it worked if it ends with ok +1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'start' ] +2 info using npm@4.1.2 +3 info using node@v7.7.4 +4 verbose run-script [ 'prestart', 'start', 'poststart' ] +5 info lifecycle project-superchat@0.0.0~prestart: project-superchat@0.0.0 +6 silly lifecycle project-superchat@0.0.0~prestart: no script for prestart, continuing +7 info lifecycle project-superchat@0.0.0~start: project-superchat@0.0.0 +8 verbose lifecycle project-superchat@0.0.0~start: unsafe-perm in lifecycle true +9 verbose lifecycle project-superchat@0.0.0~start: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/rabell/Documents/Development/viking/express/project_superchat/node_modules/.bin:~/.npm-packages/bin:/Users/rabell/google-cloud-sdk/bin:/Users/rabell/.rvm/gems/ruby-2.3.3/bin:/Users/rabell/.rvm/gems/ruby-2.3.3@global/bin:/Users/rabell/.rvm/rubies/ruby-2.3.3/bin:/Users/rabell/anaconda/bin:/opt/local/bin:/opt/local/sbin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/ImageMagick/bin:/usr/local/MacGPG2/bin:/Applications/Postgres.app/Contents/Versions/latest/bin:/Users/rabell/.rvm/bin +10 verbose lifecycle project-superchat@0.0.0~start: CWD: /Users/rabell/Documents/Development/viking/express/project_superchat +11 silly lifecycle project-superchat@0.0.0~start: Args: [ '-c', 'node ./bin/www' ] +12 silly lifecycle project-superchat@0.0.0~start: Returned: code: 1 signal: null +13 info lifecycle project-superchat@0.0.0~start: Failed to exec start script +14 verbose stack Error: project-superchat@0.0.0 start: `node ./bin/www` +14 verbose stack Exit status 1 +14 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:279:16) +14 verbose stack at emitTwo (events.js:106:13) +14 verbose stack at EventEmitter.emit (events.js:194:7) +14 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:40:14) +14 verbose stack at emitTwo (events.js:106:13) +14 verbose stack at ChildProcess.emit (events.js:194:7) +14 verbose stack at maybeClose (internal/child_process.js:899:16) +14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5) +15 verbose pkgid project-superchat@0.0.0 +16 verbose cwd /Users/rabell/Documents/Development/viking/express/project_superchat +17 error Darwin 16.5.0 +18 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "start" +19 error node v7.7.4 +20 error npm v4.1.2 +21 error code ELIFECYCLE +22 error project-superchat@0.0.0 start: `node ./bin/www` +22 error Exit status 1 +23 error Failed at the project-superchat@0.0.0 start script 'node ./bin/www'. +23 error Make sure you have the latest version of node.js and npm installed. +23 error If you do, this is most likely a problem with the project-superchat package, +23 error not with npm itself. +23 error Tell the author that this fails on your system: +23 error node ./bin/www +23 error You can get information on how to open an issue for this project with: +23 error npm bugs project-superchat +23 error Or if that isn't available, you can get their info via: +23 error npm owner ls project-superchat +23 error There is likely additional logging output above. +24 verbose exit [ 1, true ] diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 9453385..3ba784c 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -6,3 +6,16 @@ body { a { color: #00B7FF; } + +.navbar-padding { + padding-right: 20px; +} + +.row-spacing { + padding: 20px; +} + +.username { + color: cornflowerblue; + text-decoration: underline; +} diff --git a/routes/index.js b/routes/index.js index ecca96a..ab0b01b 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,9 +1,33 @@ var express = require('express'); var router = express.Router(); +const debug = require('debug')('users'); +const dataMgr = require('../bin/dataMgr'); /* GET home page. */ router.get('/', function(req, res, next) { - res.render('index', { title: 'Express' }); + console.log(req.cookies.username); + if (req.cookies.username !== undefined) { + debug(`logged in with profile`); + dataMgr.getUser(req.cookies.username).then(function(data) { + res.render('index', { + title: 'Super Chat', + username: req.cookies.username, + greeting: data.firstname + ' ' + data.lastname, + firstname: data.firstname, + lastname: data.lastname + }); + }); + } else { + debug(`not logged in`); + res.render('index', { + title: 'Super Chat', + username: null, + greeting: null, + firstname: null, + lastname: null + }); + } + }); module.exports = router; diff --git a/routes/users.js b/routes/users.js index 623e430..809258d 100644 --- a/routes/users.js +++ b/routes/users.js @@ -1,9 +1,60 @@ var express = require('express'); var router = express.Router(); +const debug = require('debug')('users'); +const dataMgr = require('../bin/dataMgr'); -/* GET users listing. */ -router.get('/', function(req, res, next) { - res.send('respond with a resource'); +/* user validation */ +router.post('/', function(req, res, next) { + // check that username in login form exists --> if it does set cookie and redirect to home + // otherwise show profile page to create user + debug(`looking for user`); + dataMgr.isUser(req.body.username).then(function(data){ + if (data === 1) { + debug(`${req.body.username} exists`); + res.cookie("username", req.body.username); + res.redirect("/"); + } else { + debug(`${req.body.username} does not exist`); + res.render('users', { title: 'Super Chat: Create Profile', + update: false, + greeting: 'New User', + username: req.body.username, + firstname: 'First Name', + lastname: 'Last Name', + createdDate: new Date(Date.now()) + }); + }; + }); +}); + +router.get('/profile/:username', function(req, res, next) { + debug(`display profile info for "${req.params.username}"`); + dataMgr.getUser(req.params.username).then(function(data) { + res.render('users', { title: 'Super Chat: User Profile', + update: true, + greeting: data.firstname, + username: req.params.username, + firstname: data.firstname, + lastname: data.lastname, + createdDate: new Date(data.created) }); + }); +}); + +router.post('/profile/:username', function(req, res, next) { + debug(`saving user profile for ${req.params.username}`); + let profile = {firstname: req.body.firstname, + lastname: req.body.lastname, + created: Date.now()}; + dataMgr.addUser(req.params.username, profile).then(function(data) { + res.cookie("username", req.params.username); + res.redirect("/"); + }); +}); + +router.get('/logout', function(req, res, next){ + debug(`loging user "${req.cookies.username}" out`); + res.clearCookie("username"); + res.redirect("/"); }); module.exports = router; diff --git a/views/layout.hbs b/views/layout.hbs index 0f7ad03..fdd2cc7 100644 --- a/views/layout.hbs +++ b/views/layout.hbs @@ -23,7 +23,38 @@ +
+ {{{body}}}
diff --git a/views/users.hbs b/views/users.hbs new file mode 100644 index 0000000..2d9ac69 --- /dev/null +++ b/views/users.hbs @@ -0,0 +1,56 @@ +
+
+

Welcome, {{greeting}}!

+ {{#unless update}} +

Please create a profile below!

+ {{else}} +

Please update your info below!

+ {{/unless}} +
+
+
+
+ +
+
+
+
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ + +
+
+
+ +
+ +
+
+
+ +
+ + + + +
+
+ +
From df84399f3cab17760659323eb533c16794ce6fc1 Mon Sep 17 00:00:00 2001 From: rabGIT Date: Tue, 9 May 2017 18:28:41 -0700 Subject: [PATCH 4/9] working multi-room chat --- app.js | 29 +++++++++++++ bin/dataMgr.js | 2 +- public/javascripts/client_sockets.js | 53 +++++++++++++++++++++++ public/stylesheets/style.css | 16 +++++++ routes/index.js | 14 +++--- views/index.hbs | 65 +++++++++++++++++++++++++++- views/layout.hbs | 10 +---- 7 files changed, 172 insertions(+), 17 deletions(-) create mode 100644 public/javascripts/client_sockets.js diff --git a/app.js b/app.js index 6033d37..a3ae481 100644 --- a/app.js +++ b/app.js @@ -12,12 +12,41 @@ var app = express(); var server = require('http').Server(app); var io = require('socket.io')(server); +const dataMgr = require('./bin/dataMgr'); +// dispatcher for IO requests from client_sockets +io.on('connection', client => { + console.log("New connection!") + + client.on('addRoom', (roomName) => { + dataMgr.addRoom(roomName).then(function(){ + io.emit('newRoom', roomName); + }); + }); + + client.on('getMessages', (roomName) => { + dataMgr.getMessages(roomName).then(function(data){ + client.emit('messageList', data); + }) + }); + + client.on('sendMessage', (message) => { + dataMgr.sendMessage(message.room, message.user, message.text).then(function(data){ + io.emit('newMessage', {room: message.room, user: message.user, text: message.text}); + }) + }); +}); + // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'hbs'); // uncomment after placing your favicon in /public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); +app.use(function(req, res, next){ + res.io = io; + req.io = io; + next(); +}); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); diff --git a/bin/dataMgr.js b/bin/dataMgr.js index 8d673ca..fafc7fe 100644 --- a/bin/dataMgr.js +++ b/bin/dataMgr.js @@ -3,7 +3,7 @@ const debug = require('debug')('dataMgr'); const ROOMKEY = "rooms"; const USERKEY = "users"; -redisClient.flushall(); +// redisClient.flushall(); // promise returns 1 for room add 0 for duplicate room function addRoom(room) { diff --git a/public/javascripts/client_sockets.js b/public/javascripts/client_sockets.js new file mode 100644 index 0000000..384af74 --- /dev/null +++ b/public/javascripts/client_sockets.js @@ -0,0 +1,53 @@ +var socket = io.connect('http://localhost:3000') +var activeRoom = null; +var activeUser = $('.username').html(); + +console.log(activeUser); + +socket.on('updateCount', function(data) { + $('#' + data.shortURL + '-count').html(data.count) +}); + +socket.on('newRoom', function(data) { + $('#roomList li:last').after('
  • ' + data + '
  • '); +}); + +socket.on('messageList', function(data) { + console.log(data); + if (data.length !== 0) { + data.forEach(function(entry) { + $('#messageList').append('
  • ' + entry.sender + ': ' + entry.text + '
  • '); + }); + }; +}); + +socket.on('newMessage', function(data) { + if (activeRoom === data.room) { + $('#messageList').append('
  • ' + data.user + ': ' + data.text + '
  • '); + } +}); + + +$('#addRoom').click(function() { + let roomName = $('#roomValue').val(); + socket.emit('addRoom', roomName); +}); + +$('#sendMessage').click(function() { + let messageTxt = $('#messageToSend').val(); + if (activeRoom === null) { + alert("Select a room first!") + } else { + socket.emit('sendMessage', {user: activeUser, room: activeRoom, text: messageTxt}); + $('#messageToSend').val(''); + } + +}); + +$(document).on("click", '.room-button', function() { + let roomName = $(this).attr("name"); + activeRoom = roomName; + $('.message-detail').remove(); + socket.emit('getMessages', roomName); + $('#messageRoomName').html(': ' + roomName); +}); diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 3ba784c..8d79175 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -19,3 +19,19 @@ a { color: cornflowerblue; text-decoration: underline; } + +.boxed { + border: 1px; + border-style: solid; + border-radius: 5px; + border-color: black; +} + +.padded { + padding: 5px; +} + +.button-format{ + float: right; + +} diff --git a/routes/index.js b/routes/index.js index ab0b01b..0117998 100644 --- a/routes/index.js +++ b/routes/index.js @@ -5,17 +5,21 @@ const dataMgr = require('../bin/dataMgr'); /* GET home page. */ router.get('/', function(req, res, next) { - console.log(req.cookies.username); if (req.cookies.username !== undefined) { debug(`logged in with profile`); - dataMgr.getUser(req.cookies.username).then(function(data) { + let pList = []; + pList.push(dataMgr.getUser(req.cookies.username)); + pList.push(dataMgr.listRooms()); + Promise.all(pList).then(function(data) { res.render('index', { title: 'Super Chat', username: req.cookies.username, - greeting: data.firstname + ' ' + data.lastname, - firstname: data.firstname, - lastname: data.lastname + greeting: data[0].firstname + ' ' + data[0].lastname, + firstname: data[0].firstname, + lastname: data[0].lastname, + rooms: data[1] }); + }); } else { debug(`not logged in`); diff --git a/views/index.hbs b/views/index.hbs index 1f308fd..44dd54c 100644 --- a/views/index.hbs +++ b/views/index.hbs @@ -1,2 +1,63 @@ -

    {{title}}

    -

    Welcome to {{title}}

    +
    + +
    +{{#if username}} +
    +
    +
    +
    +

    Chat Rooms

    +
    +
    +
    + + +
    +
    +
      + {{#each rooms}} +
    • {{this}}
    • + {{/each}} +
    +
    +
    +
    + + +
    +
    +
    +
    +

    Messages

    +
    +
    +
      + +
    +
    + + +
    +
    +
    +
    +
    +

    Chat

    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + + + +{{else}} +

    Please sign in first!

    +{{/if}} diff --git a/views/layout.hbs b/views/layout.hbs index fdd2cc7..c2afd1e 100644 --- a/views/layout.hbs +++ b/views/layout.hbs @@ -65,15 +65,7 @@ - + From 39cebbe06f2eceb101ae25d09865fa8d39544f33 Mon Sep 17 00:00:00 2001 From: rabGIT Date: Tue, 9 May 2017 18:38:52 -0700 Subject: [PATCH 5/9] new message indicator --- public/javascripts/client_sockets.js | 7 +++++++ views/index.hbs | 1 + 2 files changed, 8 insertions(+) diff --git a/public/javascripts/client_sockets.js b/public/javascripts/client_sockets.js index 384af74..242105a 100644 --- a/public/javascripts/client_sockets.js +++ b/public/javascripts/client_sockets.js @@ -24,6 +24,10 @@ socket.on('messageList', function(data) { socket.on('newMessage', function(data) { if (activeRoom === data.room) { $('#messageList').append('
  • ' + data.user + ': ' + data.text + '
  • '); + } else { + let selector = '[name="' + data.room + '"]'; + $(selector).removeClass('btn-info'); + $(selector).addClass('btn-warning'); } }); @@ -47,6 +51,9 @@ $('#sendMessage').click(function() { $(document).on("click", '.room-button', function() { let roomName = $(this).attr("name"); activeRoom = roomName; + let selector = '[name="' + roomName + '"]'; + $(selector).removeClass('btn-warning'); + $(selector).addClass('btn-info'); $('.message-detail').remove(); socket.emit('getMessages', roomName); $('#messageRoomName').html(': ' + roomName); diff --git a/views/index.hbs b/views/index.hbs index 44dd54c..9ce2cce 100644 --- a/views/index.hbs +++ b/views/index.hbs @@ -13,6 +13,7 @@ +
      {{#each rooms}} From 44ac8c699e5c8a005a896e7583f4e3b395cd7131 Mon Sep 17 00:00:00 2001 From: rabGIT Date: Tue, 9 May 2017 18:40:02 -0700 Subject: [PATCH 6/9] update readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 912f843..d8b3d66 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,7 @@ Build a realtime multi-room chat application. Make it super. Richard Bell + +To run, clone repo +Install Redis +npm start From 508100aa4a182be2176b613a8c9ef3d5aeb75264 Mon Sep 17 00:00:00 2001 From: rabGIT Date: Tue, 9 May 2017 18:52:01 -0700 Subject: [PATCH 7/9] bug fix --- bin/dataMgr.js | 1 + public/javascripts/client_sockets.js | 2 +- routes/index.js | 44 +++++++++++++++++++--------- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/bin/dataMgr.js b/bin/dataMgr.js index fafc7fe..f7a6979 100644 --- a/bin/dataMgr.js +++ b/bin/dataMgr.js @@ -3,6 +3,7 @@ const debug = require('debug')('dataMgr'); const ROOMKEY = "rooms"; const USERKEY = "users"; +// uncomment for clean-up // redisClient.flushall(); // promise returns 1 for room add 0 for duplicate room diff --git a/public/javascripts/client_sockets.js b/public/javascripts/client_sockets.js index 242105a..a248cb9 100644 --- a/public/javascripts/client_sockets.js +++ b/public/javascripts/client_sockets.js @@ -9,7 +9,7 @@ socket.on('updateCount', function(data) { }); socket.on('newRoom', function(data) { - $('#roomList li:last').after('
    • ' + data + '
    • '); + $('#roomList').append('
    • ' + data + '
    • '); }); socket.on('messageList', function(data) { diff --git a/routes/index.js b/routes/index.js index 0117998..be45a26 100644 --- a/routes/index.js +++ b/routes/index.js @@ -5,22 +5,38 @@ const dataMgr = require('../bin/dataMgr'); /* GET home page. */ router.get('/', function(req, res, next) { - if (req.cookies.username !== undefined) { - debug(`logged in with profile`); - let pList = []; - pList.push(dataMgr.getUser(req.cookies.username)); - pList.push(dataMgr.listRooms()); - Promise.all(pList).then(function(data) { - res.render('index', { - title: 'Super Chat', - username: req.cookies.username, - greeting: data[0].firstname + ' ' + data[0].lastname, - firstname: data[0].firstname, - lastname: data[0].lastname, - rooms: data[1] - }); + if (req.cookies.username !== undefined) { + dataMgr.isUser(req.cookies.username).then(function(data) { + if (data) { + debug(`logged in with profile`); + let pList = []; + pList.push(dataMgr.getUser(req.cookies.username)); + pList.push(dataMgr.listRooms()); + Promise.all(pList).then(function(data) { + res.render('index', { + title: 'Super Chat', + username: req.cookies.username, + greeting: data[0].firstname + ' ' + data[0].lastname, + firstname: data[0].firstname, + lastname: data[0].lastname, + rooms: data[1] + }); + }) + } else { + res.clearCookie("username"); + res.render('index', { + title: 'Super Chat', + username: null, + greeting: null, + firstname: null, + lastname: null + }); + } }); + + + } else { debug(`not logged in`); res.render('index', { From 85d30e993750ead4db30f302e4a3234818c219b1 Mon Sep 17 00:00:00 2001 From: rabGIT Date: Tue, 9 May 2017 18:56:18 -0700 Subject: [PATCH 8/9] bug fix --- public/javascripts/client_sockets.js | 1 + 1 file changed, 1 insertion(+) diff --git a/public/javascripts/client_sockets.js b/public/javascripts/client_sockets.js index a248cb9..0aec87f 100644 --- a/public/javascripts/client_sockets.js +++ b/public/javascripts/client_sockets.js @@ -35,6 +35,7 @@ socket.on('newMessage', function(data) { $('#addRoom').click(function() { let roomName = $('#roomValue').val(); socket.emit('addRoom', roomName); + $('#roomValue').val(''); }); $('#sendMessage').click(function() { From c515712211dfc3eb770e570dd5ef9d6c5e5d5f17 Mon Sep 17 00:00:00 2001 From: rabGIT Date: Wed, 10 May 2017 14:03:32 -0700 Subject: [PATCH 9/9] refactoring --- npm-debug.log | 45 --------------------------------------------- routes/index.js | 13 ------------- 2 files changed, 58 deletions(-) delete mode 100644 npm-debug.log diff --git a/npm-debug.log b/npm-debug.log deleted file mode 100644 index 243c0a4..0000000 --- a/npm-debug.log +++ /dev/null @@ -1,45 +0,0 @@ -0 info it worked if it ends with ok -1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'start' ] -2 info using npm@4.1.2 -3 info using node@v7.7.4 -4 verbose run-script [ 'prestart', 'start', 'poststart' ] -5 info lifecycle project-superchat@0.0.0~prestart: project-superchat@0.0.0 -6 silly lifecycle project-superchat@0.0.0~prestart: no script for prestart, continuing -7 info lifecycle project-superchat@0.0.0~start: project-superchat@0.0.0 -8 verbose lifecycle project-superchat@0.0.0~start: unsafe-perm in lifecycle true -9 verbose lifecycle project-superchat@0.0.0~start: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/rabell/Documents/Development/viking/express/project_superchat/node_modules/.bin:~/.npm-packages/bin:/Users/rabell/google-cloud-sdk/bin:/Users/rabell/.rvm/gems/ruby-2.3.3/bin:/Users/rabell/.rvm/gems/ruby-2.3.3@global/bin:/Users/rabell/.rvm/rubies/ruby-2.3.3/bin:/Users/rabell/anaconda/bin:/opt/local/bin:/opt/local/sbin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/ImageMagick/bin:/usr/local/MacGPG2/bin:/Applications/Postgres.app/Contents/Versions/latest/bin:/Users/rabell/.rvm/bin -10 verbose lifecycle project-superchat@0.0.0~start: CWD: /Users/rabell/Documents/Development/viking/express/project_superchat -11 silly lifecycle project-superchat@0.0.0~start: Args: [ '-c', 'node ./bin/www' ] -12 silly lifecycle project-superchat@0.0.0~start: Returned: code: 1 signal: null -13 info lifecycle project-superchat@0.0.0~start: Failed to exec start script -14 verbose stack Error: project-superchat@0.0.0 start: `node ./bin/www` -14 verbose stack Exit status 1 -14 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:279:16) -14 verbose stack at emitTwo (events.js:106:13) -14 verbose stack at EventEmitter.emit (events.js:194:7) -14 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:40:14) -14 verbose stack at emitTwo (events.js:106:13) -14 verbose stack at ChildProcess.emit (events.js:194:7) -14 verbose stack at maybeClose (internal/child_process.js:899:16) -14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5) -15 verbose pkgid project-superchat@0.0.0 -16 verbose cwd /Users/rabell/Documents/Development/viking/express/project_superchat -17 error Darwin 16.5.0 -18 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "start" -19 error node v7.7.4 -20 error npm v4.1.2 -21 error code ELIFECYCLE -22 error project-superchat@0.0.0 start: `node ./bin/www` -22 error Exit status 1 -23 error Failed at the project-superchat@0.0.0 start script 'node ./bin/www'. -23 error Make sure you have the latest version of node.js and npm installed. -23 error If you do, this is most likely a problem with the project-superchat package, -23 error not with npm itself. -23 error Tell the author that this fails on your system: -23 error node ./bin/www -23 error You can get information on how to open an issue for this project with: -23 error npm bugs project-superchat -23 error Or if that isn't available, you can get their info via: -23 error npm owner ls project-superchat -23 error There is likely additional logging output above. -24 verbose exit [ 1, true ] diff --git a/routes/index.js b/routes/index.js index be45a26..43365d9 100644 --- a/routes/index.js +++ b/routes/index.js @@ -6,7 +6,6 @@ const dataMgr = require('../bin/dataMgr'); /* GET home page. */ router.get('/', function(req, res, next) { - if (req.cookies.username !== undefined) { dataMgr.isUser(req.cookies.username).then(function(data) { if (data) { debug(`logged in with profile`); @@ -36,18 +35,6 @@ router.get('/', function(req, res, next) { }); - - } else { - debug(`not logged in`); - res.render('index', { - title: 'Super Chat', - username: null, - greeting: null, - firstname: null, - lastname: null - }); - } - }); module.exports = router;