Skip to content

Commit ad8dc41

Browse files
author
dodortus
committed
* add socket events
1 parent be67602 commit ad8dc41

File tree

4 files changed

+178
-27
lines changed

4 files changed

+178
-27
lines changed

contents/css/style.css

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
* { margin: 0; padding: 0; font-weight: 300; }
44
body {
5-
position: relative; height: 100%;
5+
position: relative; height: 100%; overflow: hidden;
66
margin: 0; padding: 1em; word-break: break-word;
77
font-family: Malgun Gothic, Dotum, AppleGothic, Arial, Sans-serif; font-size: 16px;
88
}
@@ -25,44 +25,107 @@ button:hover { background-color: #cf402f; }
2525
button[disabled] { color: #ccc; cursor: default; }
2626
.btn[disabled]:hover,
2727
button[disabled]:hover { background-color: #d84a38 }
28+
.btn.small { padding: 0.2em 0.4em; font-size: 0.6em; margin-bottom: 0.2em; }
29+
.btn.small.black { background-color: #000; }
30+
31+
2832
h1 {
2933
border-bottom: 1px solid #ccc; height: 50px; line-height: 50px;
3034
font-weight: bold; margin: 0; padding: 0 0 0.2em 0;
3135
}
3236
h1 a { font-weight: 300; margin: 0 10px 0 0; white-space: nowrap; }
3337

3438
#wrap {
35-
position: relative; width: 600px; margin: 200px auto; font-size: 1.2em; text-align: center;
39+
position: relative; width: 340px; margin: 30px auto; font-size: 1.2em;
3640
}
3741
input[type="text"] { padding: 2px 5px; border: solid 1px #bbb; font-size: 1.3em; width: 120px; }
3842
#your-name { width: 250px; }
39-
#wrap button { vertical-align: top; min-width: 80px; }
40-
#wrap p { margin: 10px 0; }
43+
#wrap button { vertical-align: top; min-width: 72px; }
4144

4245
header { position: relative; margin-bottom: 10px; }
46+
#lobby { display: none; }
4347

4448
/* chat */
45-
#chat-wrap { margin: 0 auto; width: 340px; }
49+
#chat-wrap { position: relative; margin: 0 auto; }
4650
#chat-wrap input[type="text"] {
47-
width: 200px; font-size: 14px; padding: 6px; background: rgba(255,255,255,0.8); font-family: inherit;
51+
padding: 10px; width: 238px;
52+
font-size: 14px; background: rgba(255,255,255,0.8);
4853
}
4954
#chat-content {
50-
padding: 10px; margin-bottom: 5px; height: 300px;
55+
padding: 10px; margin-bottom: 5px; height: 380px;
5156
overflow-y: auto; border: solid 1px #ccc; background: rgba(255,255,255,0.8);
5257
}
5358

54-
#chat-content li { clear: both; margin-bottom: 8px; padding-bottom: 1px; height: auto; overflow: hidden; }
55-
#chat-content li * { padding: 2px 5px; font-size: 10px; display: inline-block; }
56-
#chat-content .name { background: #333; color: #fff; border-radius: 3px; vertical-align: top; }
59+
#chat-content li {
60+
clear: both; margin-bottom: 12px; padding-bottom: 1px;
61+
height: auto; overflow: hidden;
62+
}
63+
64+
#chat-content .name,
65+
#chat-content .message { padding: 4px 5px 2px; font-size: 10px; }
66+
#chat-content .name {
67+
max-width: 100px; text-overflow: ellipsis;
68+
background: #333; color: #fff; border-radius: 3px 3px 0 0;
69+
}
5770
#chat-content .message {
58-
max-width: 170px; font-size: 12px; background: #E5F1FB; border-radius: 3px; color: #000;
59-
box-shadow: 1px 1px 0 rgba(80, 80, 80, 0.3);
71+
max-width: 306px; font-size: 12px; background: #E5F1FB;
72+
border-radius: 0 3px 3px 3px; color: #000; box-shadow: 1px 1px 0 rgba(80, 80, 80, 0.3);
6073
}
6174
#chat-content .message .date {
62-
padding: 2px 0; margin-top: 5px; border-top: dotted 1px #fff; color: #666; font-size: 10px;
75+
display: block; padding: 2px 0; margin-top: 5px;
76+
border-top: dotted 1px #fff; color: #666; font-size: 10px;
6377
}
64-
#chat-content .me * { float: right; }
65-
#chat-content .me .name { margin-left: 5px; }
78+
#chat-content .system .message {
79+
padding: 2px 5px; border-radius: 3px; background: #ebebeb;
80+
}
81+
#chat-content .system strong { font-weight: bold; }
82+
#chat-content .me { position: relative; }
6683
#chat-content .me .message { background-color: rgba(243, 178, 176, 0.3); }
67-
#chat-content .notice { margin: 0 0 8px; font-size: 0.8em; }
6884

85+
/* typing */
86+
#typing-icon {
87+
position: absolute; bottom: 68px; right: 142px; height: 14px; line-height: 12px;
88+
padding: 2px 10px; background: #ebebeb; border-radius: 6px;
89+
transition: opacity 0.3s ease-out; opacity: 0; border: solid 1px #ccc;
90+
}
91+
.visible { opacity: 1 !important; }
92+
#typing-icon span {
93+
display: inline-block; margin: 0; width: 7px; height: 7px;
94+
background: #000; border-radius: 50%;
95+
96+
animation: bouncedelay 1.4s infinite ease-in-out;
97+
-moz-animation: bouncedelay 1.4s infinite ease-in-out;
98+
-webkit-animation: bouncedelay 1.4s infinite ease-in-out;
99+
100+
/* Prevent first frame from flickering when animation starts */
101+
animation-fill-mode: both;
102+
-moz-animation-fill-mode: both;
103+
-webkit-animation-fill-mode: both;
104+
}
105+
106+
#typing-icon .bounce1 {
107+
animation-delay: -0.32s;
108+
-moz-animation-delay: -0.32s;
109+
-webkit-animation-delay: -0.32s;
110+
}
111+
112+
#typing-icon .bounce2 {
113+
animation-delay: -0.16s;
114+
-moz-animation-delay: -0.16s;
115+
-webkit-animation-delay: -0.16s;
116+
}
117+
118+
@keyframes bouncedelay {
119+
0%, 80%, 100% { transform: scale(0.0); }
120+
40% { transform: scale(1.0); }
121+
}
122+
123+
@-webkit-keyframes bouncedelay {
124+
0%, 80%, 100% { -webkit-transform: scale(0.0); }
125+
40% { -webkit-transform: scale(1.0); }
126+
}
127+
128+
@-moz-keyframes bouncedelay {
129+
0%, 80%, 100% { -moz-transform: scale(0.0); }
130+
40% { -moz-transform: scale(1.0); }
131+
}

contents/js/base.js

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,87 @@
66
*/
77
$(function() {
88
var socket = io();
9-
var nickName = 'user-' + new Date().getTime();
9+
var nickName = /* prompt('닉네임을 입력해 주세요') || */ 'Guest-' + new Date().getTime();
1010
var $msgInput = $('#message');
11+
var $typing = $('#typing-icon');
1112

13+
function getTime() {
14+
var time = new Date();
15+
// return time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds();
16+
return time.getHours() + ":" + time.getMinutes();
17+
}
18+
19+
function addUserMessage(nickName, msg, isMe) {
20+
$('#chat-content').append([
21+
"<li class='" + (isMe ? 'me' : '') + "'>",
22+
"<strong class='name'>" + (isMe ? 'Me' : nickName) + "</strong>",
23+
"<p class='message'>" + msg +
24+
"<span class='date'>" + getTime() + "</span>",
25+
"</p>",
26+
"</li>"
27+
].join('\n'));
28+
}
29+
30+
function addSystemMessage(msg) {
31+
$('#chat-content').append([
32+
"<li class='system'>",
33+
"<p class='message'>" + msg + "</p>",
34+
"</li>"
35+
].join('\n'));
36+
}
37+
38+
// 참여 이벤트
39+
socket.emit('join', nickName);
40+
socket.on('join', function(nickName) {
41+
addSystemMessage("<strong>" + nickName + "</strong> 님이 참여하였습니다.");
42+
});
43+
44+
// 종료 이벤트
45+
$('#leave-room').click(function() {
46+
socket.emit('leave', nickName);
47+
});
48+
49+
socket.on('leave', function(nickName) {
50+
addSystemMessage("<strong>" + nickName + "</strong> 님이 나갔습니다.");
51+
});
52+
53+
// 메시지 이벤트
1254
$('form').submit(function() {
55+
var msg = $msgInput.val();
1356
socket.emit('message', {
1457
nickName: nickName,
15-
body: $msgInput.val()
58+
body: msg
1659
});
1760
$msgInput.val('');
61+
addUserMessage(nickName, msg, true);
62+
1863
return false;
1964
});
2065

21-
socket.on('message', function(msg) {
22-
console.log('message', msg);
66+
socket.on('message', function(data) {
67+
console.log('message', data);
68+
addUserMessage(data.nickName, data.body);
2369

24-
$('#chat-content').append([
25-
"<li>",
26-
"<h3 class='name'>" + msg.nickName + "</h3>",
27-
"<p class='message'>" + msg.body + "</p>",
28-
"</li>"
29-
]);
70+
$typing.removeClass('visible');
71+
});
72+
73+
// 타이핑 이벤트
74+
$msgInput.keydown(function() {
75+
socket.emit('typing', nickName);
76+
});
77+
78+
var typingTime = null;
79+
socket.on('typing', function(nickName) {
80+
console.log('typing', nickName);
81+
82+
$typing.addClass('visible');
83+
84+
// 아이콘 자동 숨김
85+
/*
86+
clearTimeout(typingTime);
87+
var typingTime = setTimeout(function() {
88+
$typing.removeClass('visible');
89+
}, 3000);
90+
*/
3091
});
3192
});

server.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,25 @@ io.on('connection', function(socket){
2323
socket.broadcast.emit('message', msg);
2424
//io.emit('message', msg);
2525
});
26+
27+
socket.on('disconnect', function() {
28+
console.log('a user disconnected');
29+
});
30+
31+
// 참여
32+
socket.on('join', function(nickName) {
33+
socket.broadcast.emit('join', nickName);
34+
});
35+
36+
// 나가기
37+
socket.on('leave', function(nickName) {
38+
socket.broadcast.emit('leave', nickName);
39+
});
40+
41+
// 타이핑
42+
socket.on('typing', function(nickName) {
43+
socket.broadcast.emit('typing', nickName);
44+
});
2645
});
2746

2847
// static 은 view 선언 다음에 사용

views/index.html

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,18 @@ <h1>Simple Chatting</h1>
2222
</section>
2323

2424
<section id="room">
25+
<button id="leave-room" class="btn small black">&lt; 로비로 이동</button>
2526
<div id="chat-wrap">
2627
<ul id="chat-content">
27-
<li class="notice">※ Welcome! ※ </li>
28+
<li class="system">
29+
<p class="message">채팅방에 오신걸 환영합니다.</p>
30+
</li>
2831
</ul>
32+
<div id="typing-icon">
33+
<span class="bounce1"></span>
34+
<span class="bounce2"></span>
35+
<span class="bounce3"></span>
36+
</div>
2937

3038
<form method="post" action="#">
3139
<input type="hidden" name="name" id="name" value="정식">

0 commit comments

Comments
 (0)