├── .babelrc
├── .gitignore
├── README.md
├── dist
└── .gitkeep
├── index.html
├── package.json
├── server.js
└── src
├── components
├── Chat.vue
├── ChatBox.vue
└── ChatMessage.vue
└── main.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-2"],
3 | "plugins": ["transform-runtime"]
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/build.js
4 | npm-debug.log
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # chat
2 |
3 | > A simple chat app using Vue, socket, and Node.
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm run dev
13 |
14 | # build for production with minification
15 | npm run build
16 | ```
17 |
18 | For more information see the [docs for vueify](https://github.com/vuejs/vueify).
19 |
--------------------------------------------------------------------------------
/dist/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrterryh/vuejs-chat/c82d9adc00310c2a7b5ac7c2704f495fb1136174/dist/.gitkeep
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Chat Application
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chat",
3 | "description": "A simple chat app using Vue, socket, and Node.",
4 | "author": "Terry Harvey",
5 | "scripts": {
6 | "watchify": "watchify -vd -p browserify-hmr -e src/main.js -o dist/build.js",
7 | "serve": "http-server -c 1 -a localhost",
8 | "dev": "npm-run-all --parallel watchify",
9 | "build": "cross-env NODE_ENV=production browserify src/main.js | uglifyjs -c warnings=false -m > dist/build.js"
10 | },
11 | "dependencies": {
12 | "express": "^4.13.4",
13 | "jquery": "^2.2.3",
14 | "socket.io": "^1.4.6",
15 | "vue": "^1.0.0"
16 | },
17 | "devDependencies": {
18 | "babel-core": "^6.0.0",
19 | "babel-plugin-transform-runtime": "^6.0.0",
20 | "babel-preset-es2015": "^6.0.0",
21 | "babel-preset-stage-2": "^6.0.0",
22 | "babel-runtime": "^6.0.0",
23 | "cross-env": "^1.0.6",
24 | "babelify": "^7.2.0",
25 | "browserify": "^12.0.1",
26 | "browserify-hmr": "^0.3.1",
27 | "http-server": "^0.9.0",
28 | "npm-run-all": "^1.6.0",
29 | "uglify-js": "^2.5.0",
30 | "vue-hot-reload-api": "^1.2.2",
31 | "vueify": "^8.0.0",
32 | "vueify-insert-css": "^1.0.0",
33 | "watchify": "^3.4.0"
34 | },
35 | "browserify": {
36 | "transform": [
37 | "vueify",
38 | "babelify"
39 | ]
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var http = require('http');
3 | var app = express();
4 | var server = http.createServer(app);
5 | var io = require('socket.io').listen(server);
6 |
7 | /**
8 | * Set up a basic Express server.
9 | */
10 | app.set('port', 3000);
11 | app.use(express.static(__dirname + '/'));
12 |
13 | app.get('/', function(request, response) {
14 | response.render('index.html');
15 | });
16 |
17 | server.listen(app.get('port'), function() {
18 | console.log('Express server listening.');
19 | });
20 |
21 | /**
22 | * Declare some variables for later use.
23 | */
24 | var onlineUsers = {};
25 | var sentMessages = [];
26 |
27 | /**
28 | * Listen for a new connection on the server.
29 | */
30 | io.on('connection', function(socket) {
31 | console.log('Socket connected with ID of ' + socket.id);
32 |
33 | /**
34 | * This will be fired when a user enters a username. The server will
35 | * associate the username with the socket ID and store it in,
36 | * $onlineUsers then emit a message to the client which
37 | * will in turn output a "XYZ has joined" message to
38 | * all connected users.
39 | */
40 | socket.on('user logged in', function(username) {
41 | console.log('%s has joined the chat!', username);
42 |
43 | onlineUsers[socket.id] = username;
44 |
45 | io.emit('user joined', {
46 | socketId: socket.id,
47 | username: username,
48 | timestamp: new Date,
49 | type: 'alert',
50 | message: username + ' has joined the chat!'
51 | });
52 | });
53 |
54 | /**
55 | * This will get fired whenever a user submits a message to the chat. The
56 | * server will create a message object to store all of the various
57 | * metadata and store it in $sentMessages. It will then emit a
58 | * message to the client to tell it to output the message
59 | * in the chat to all users.
60 | */
61 | socket.on('send message', function(message) {
62 | var senderUsername = onlineUsers[socket.id];
63 |
64 | var messageObject = {
65 | socketId: socket.id,
66 | username: senderUsername,
67 | timestamp: new Date,
68 | type: 'message',
69 | message: message
70 | };
71 |
72 | console.log('%s: %s', senderUsername, message);
73 |
74 | sentMessages.push(messageObject);
75 |
76 | io.emit('message received', messageObject);
77 | });
78 |
79 | /**
80 | * Listens for when an admin clicks the "kick" link on the online users list.
81 | * The server will try to find the socket associated with the given username
82 | * and disconnect it if it exists.
83 | */
84 | socket.on('kick user', function(username) {
85 | var socketId = Object.keys(onlineUsers).filter(function(key) {
86 | return onlineUsers[key] == username;
87 | })[0];
88 |
89 | if (io.sockets.sockets[socketId]) {
90 | io.sockets.sockets[socketId].disconnect();
91 | }
92 |
93 | console.log('%s has been kicked from the chat.', username);
94 | });
95 |
96 | /**
97 | * Gets fired when a user leaves the page. It will remove their session
98 | * from $onlineUsers and broadcast a message to the client to alert
99 | * everyone in the chat that the user has disconnected.
100 | */
101 | socket.on('disconnect', function() {
102 | var username = onlineUsers[socket.id];
103 |
104 | delete onlineUsers[socket.id];
105 |
106 | console.log('%s has disconnected from the chat.', username);
107 |
108 | io.emit('user left', {
109 | socketId: socket.id,
110 | username: username,
111 | timestamp: new Date,
112 | type: 'alert',
113 | message: username + ' has disconnected from the chat!'
114 | });
115 | });
116 | });
--------------------------------------------------------------------------------
/src/components/Chat.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
48 |
49 |
--------------------------------------------------------------------------------
/src/components/ChatBox.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
Online Users
17 |
18 |
19 | -
20 | {{ user }}
21 |
22 | [ kick ]
23 |
24 |
25 |
26 |
27 |
28 |
29 |
89 |
90 |
--------------------------------------------------------------------------------
/src/components/ChatMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ data.message }}
5 |
6 |
7 |
8 |
9 | {{ data.username }} said,
10 | {{ data.timestamp }}
11 |
12 |
13 |
14 | {{ data.message }}
15 |
16 |
17 |
18 |
19 |
20 |
31 |
32 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import jQuery from 'jquery'
3 | import Chat from './components/Chat.vue'
4 |
5 | window.app = new Vue({
6 | el: 'body',
7 | components: { Chat }
8 | })
--------------------------------------------------------------------------------