diff --git a/src/js/chat.js b/src/js/chat.js index 9f8d814..ed2657d 100644 --- a/src/js/chat.js +++ b/src/js/chat.js @@ -1,6 +1,7 @@ import _ from 'underscore'; import sanitizeHtml from 'sanitize-html'; import he from 'he'; +import moment from 'moment'; // TODO: Remove in v2.0 let warned = false; @@ -17,6 +18,7 @@ export default class Chat { this.messages = $('.messages'); // Messages area this.inputMessage = $('.inputMessage'); // Input message input box this.chatPage = $('.chat.page'); + this.lastMessageTime = null; this.bindEvents(); } @@ -335,11 +337,13 @@ export default class Chat { .css('color', this.getUsernameColor(data.username)); let $messageBodyDiv = $(''); + let timestamp = this.getTimestamp(data.typing); if (messageType === 'text' || messageType === 'action') { if (messageType === 'action') { $usernameDiv.css('color','').prepend('*'); } + let unescapedMessage = unescape(data.message); let lineBreaks = /<br \/>/g; unescapedMessage = unescapedMessage.replace(lineBreaks, '
'); @@ -355,11 +359,28 @@ export default class Chat { .data('username', data.username) .addClass(typingClass) .addClass(actionClass) - .append($usernameDiv, $messageBodyDiv); + .append(timestamp, $usernameDiv, $messageBodyDiv); this.addMessageElement($messageDiv, options); } + getTimestamp(isTyping) { + if (isTyping) { + return false; + } + + let now = moment(new Date()).format('LT'); + + if (this.lastMessageTime === now) { + return false; + } + + this.lastMessageTime = now; + + return '' + now + ''; + + } + addMessageElement(el, options) { let $el = $(el); diff --git a/src/js/darkwire.js b/src/js/darkwire.js index 58014d0..e48af4e 100644 --- a/src/js/darkwire.js +++ b/src/js/darkwire.js @@ -319,7 +319,6 @@ export default class Darkwire { username: username, message: decryptedMessage, messageType: data.messageType, - timestamp: data.timestamp }); } }); diff --git a/src/public/style.css b/src/public/style.css index 7745f9e..d0bcd2e 100644 --- a/src/public/style.css +++ b/src/public/style.css @@ -350,3 +350,11 @@ html.no-touchevents .chat #input-icons { font-style: italic; color: #00FF7F; } + +.timestamp { + font-size: 13px; + color: #CCC; + font-weight: bold; + font-style: italic; + display: block; +} diff --git a/src/room.js b/src/room.js index b2659ad..0547092 100644 --- a/src/room.js +++ b/src/room.js @@ -27,7 +27,6 @@ class Room { vector: data.vector, secretKeys: data.secretKeys, signature: data.signature, - timestamp: new Date() }); }); @@ -48,7 +47,6 @@ class Room { username: socket.username, numUsers: this.numUsers, users: this.users, - timestamp: new Date() }); }); @@ -78,7 +76,6 @@ class Room { numUsers: this.numUsers, users: this.users, id: socket.user.id, - timestamp: new Date() }); // remove room from rooms array @@ -105,7 +102,6 @@ class Room { thisIO.emit('user update', { username: socket.username, id: socket.user.id, - timestamp: new Date() }); } diff --git a/test/acceptance/app.js b/test/acceptance/app.js index 66c3375..72185ca 100644 --- a/test/acceptance/app.js +++ b/test/acceptance/app.js @@ -1,5 +1,6 @@ /*jshint -W030 */ import App from '../../package.json'; +import moment from 'moment'; describe('Darkwire', () => { @@ -62,12 +63,14 @@ describe('Darkwire', () => { }); describe('Sending chat message', () => { + let timestamp = null; before((client, done) => { browser .waitForElementPresent('ul.users li:nth-child(2)', 5000) .waitForElementPresent('textarea.inputMessage', 5000) .setValue('textarea.inputMessage', ['Hello world!', browser.Keys.RETURN], () => { + timestamp = moment(new Date()).format('LT'); done(); }); }); @@ -82,6 +85,16 @@ describe('Darkwire', () => { }); }); + it('Should show correct timestamp', () => { + browser.windowHandles((result) => { + browser.switchWindow(result.value[0], () => { + browser + .waitForElementVisible('span.timestamp', 5000) + .assert.containsText('span.timestamp', timestamp); + }); + }); + }); + }); describe('Slash Commands', () => {