Skip to content

Commit 302583e

Browse files
committed
typing users signalization and message sound
1 parent 95fb03c commit 302583e

File tree

6 files changed

+100
-27
lines changed

6 files changed

+100
-27
lines changed

chat/css/style.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,4 +201,17 @@ form.message-form button{
201201
border:1px solid #c5c5c9;
202202
border-radius:4px;
203203
font-size:130%;
204+
}
205+
206+
audio#msg-sound {
207+
display:none;
208+
}
209+
div.typing-users-cont{
210+
position: absolute;
211+
color: white;
212+
bottom: 10px;
213+
right: 10px;
214+
white-space: nowrap;
215+
font-size: 70%;
216+
display: none;
204217
}

chat/data/index.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ App.prototype = {
1616
_onlineUsers: {},
1717
_onlineUsersCount: 0,
1818
_data: [],
19+
_typingUsers: {},
1920
_users: { length: 0 },
2021
_init: function (httpServer, expressServer, sessionParser, request, response) {
2122
this._httpServer = httpServer;
@@ -99,9 +100,27 @@ App.prototype = {
99100
} else {
100101
var targetSessionId = typeof(this._onlineUsers[recepient]) != 'undefined' ? this._onlineUsers[recepient].sessionId : '';
101102
this._sendToSingle('message', data, targetSessionId);
102-
this._sendToSingle('message', data, sessionId); // missing
103+
this._sendToSingle('message', data, sessionId);
103104
}
104105
console.log(data.user + ': ' + data.content);
106+
} else if (eventName == 'typing') {
107+
108+
var recepient = typeof(data.recepient) != 'undefined' && data.recepient
109+
? data.recepient
110+
: 'all';
111+
var typing = typeof(data.typing) != 'undefined'
112+
? data.typing
113+
: false;
114+
115+
this._typingUsers[user] = typing;
116+
117+
if (recepient == 'all') {
118+
this._sendToAll('typing', this._typingUsers);
119+
} else {
120+
var targetSessionId = typeof(this._onlineUsers[recepient]) != 'undefined' ? this._onlineUsers[recepient].sessionId : '';
121+
this._sendToSingle('typing', this._typingUsers, targetSessionId);
122+
}
123+
console.log(data.user + ' is typing.');
105124
}
106125
},
107126
_webSocketOnClose: function (sessionId) {

chat/index.html

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
<!DOCTYPE html>
22
<html lang="en-US">
3-
<head>
4-
<meta charset="utf-8" />
5-
<title>Websocket Chat</title>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Websocket Chat</title>
66
<link rel="stylesheet" type="text/css" href="css/style.css" />
77
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8-
</head>
9-
<body>
8+
</head>
9+
<body>
1010

1111

1212
<form id="login-form" class="login-form">
1313
<label for="login-user">Please enter chat nick name</label>
1414
<input name="user" type="text" placeholder="Nickname" />
1515
<input name="pass" type="password" placeholder="Password" />
1616
<input type="submit" value="Login" />
17-
</form>
18-
17+
</form>
18+
1919

2020
<div id="chat-room" class="chat-room">
21-
21+
2222
<div class="header">
2323
<b>Websocket Chat</b>
2424
<span id="current-user"></span>
2525
<a id="logout-btn" href="javascript:void(0);">logout</a>
26-
</div>
26+
</div>
2727

2828
<div class="chat-content">
2929
<div id="online-users" class="online-users"></div>
@@ -51,15 +51,17 @@
5151
</div>
5252
</div>
5353
<button type="submit">Send</button>
54+
<div id="typing-users-cont" class="typing-users-cont">Typing user(s): <span id="typing-users"><span><div>
5455
</form>
5556

56-
</div>
57+
</div>
5758

59+
<audio id="msg-sound" src="js/message.mp3" />
5860

59-
<script type="text/javascript" src="js/class.dev.js"></script>
61+
<script type="text/javascript" src="js/class.dev.js"></script>
6062
<script type="text/javascript" src="js/ajax.dev.js"></script>
61-
<script type="text/javascript" src="js/socket-wrapper.js"></script>
62-
<script type="text/javascript" src="js/client.js"></script>
63+
<script type="text/javascript" src="js/socket-wrapper.js"></script>
64+
<script type="text/javascript" src="js/client.js"></script>
6365

64-
</body>
66+
</body>
6567
</html>

chat/js/client.js

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Class.Define('Chat', {
2020
this._messages = $elm("messages");
2121
this._messageForm = $elm("message-form");
2222
this._recepients = $elm("recepients");
23+
this._audioElm = $elm("msg-sound");
24+
this._typingUsersCont = $elm("typing-users-cont");
25+
this._typingUsers = $elm("typing-users");
2326
},
2427
_initEvents: function () {
2528
var scope = this;
@@ -40,6 +43,16 @@ Class.Define('Chat', {
4043
return scope._messageFormSubmitHandler(e || window.event);
4144
}
4245
};
46+
this._messageForm.message.onkeyup = function (e) {
47+
e = e || window.event;
48+
if (!(e.keyCode == 13 && e.ctrlKey)) {
49+
var messageText = scope._messageForm.message.value;
50+
return scope._messageFormTypingHandler(
51+
String(messageText).trim().length > 0,
52+
e || window.event
53+
);
54+
}
55+
};
4356
window.addEventListener("unload", function(e) {
4457
if (this._socket)
4558
this._socket.close();
@@ -138,31 +151,45 @@ Class.Define('Chat', {
138151
data.content,
139152
data.user
140153
);
154+
scope._audioElm.play();
155+
});
156+
this._socket.bind('typing', function (data) {
157+
scope._typingUsersHandler(data);
141158
});
142159
},
143160
_messageFormSubmitHandler: function (e) {
144-
var messageText = this._messageForm.message.value,
145-
recepientRadio = null,
146-
recepient = '';
147-
for (var i = 0, l = this._messageForm.rcp.length; i < l; i += 1) {
148-
recepientRadio = this._messageForm.rcp[i];
149-
if (recepientRadio.checked) {
150-
recepient = recepientRadio.value;
151-
break;
152-
}
153-
}
161+
var messageText = this._messageForm.message.value;
154162
if (messageText != '') {
155163
this._socket.send('message', {
156164
id: this._id,
157165
user: this._user,
158-
recepient: recepient,
166+
recepient: this._getRecepient(),
159167
content: messageText
160168
});
161169
this._messageForm.message.value = '';
162170
}
163171
e.preventDefault();
164172
return false;
165173
},
174+
_messageFormTypingHandler: function (typing, e) {
175+
this._socket.send('typing', {
176+
id: this._id,
177+
user: this._user,
178+
recepient: this._getRecepient(),
179+
typing: typing
180+
});
181+
},
182+
_getRecepient: function () {
183+
var recepientRadio = null, recepient = '';
184+
for (var i = 0, l = this._messageForm.rcp.length; i < l; i += 1) {
185+
recepientRadio = this._messageForm.rcp[i];
186+
if (recepientRadio.checked) {
187+
recepient = recepientRadio.value;
188+
break;
189+
}
190+
}
191+
return recepient;
192+
},
166193
_anyUserLogInHandler: function (data) {
167194
this._updateOnlineUsersHandler(data);
168195
this._addMessage(
@@ -197,6 +224,18 @@ Class.Define('Chat', {
197224
this._onlineUsers.innerHTML = 'Currently online ('
198225
+ data.onlineUsersCount + '): ' + html;
199226
},
227+
_typingUsersHandler: function (data) {
228+
var typingUsers = [];
229+
for (var userName in data)
230+
if (userName !== this._user && data[userName])
231+
typingUsers.push(userName);
232+
if (typingUsers.length === 0) {
233+
this._typingUsersCont.style.display = 'none';
234+
} else {
235+
this._typingUsers.innerHTML = typingUsers.join(', ');
236+
this._typingUsersCont.style.display = 'block';
237+
}
238+
},
200239
_updateRecepients: function (onlineUsers) {
201240
var html = '';
202241
console.log(onlineUsers);

chat/js/message.mp3

20.1 KB
Binary file not shown.

chat/js/socket-wrapper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ SocketWrapper.prototype = {
1717
_callbacks: {},
1818
send: function (eventName, data) {
1919
var str = JSON.stringify({eventName: eventName, data: data});
20-
console.log(this._opened, str);
20+
//console.log(this._opened, str);
2121
if (this._opened) {
2222
this._socket.send(str);
2323
} else {

0 commit comments

Comments
 (0)