diff --git a/frontend/src/Metamaps/Views/ChatView.js b/frontend/src/Metamaps/Views/ChatView.js
index 9bd8b563..6b63cd70 100644
--- a/frontend/src/Metamaps/Views/ChatView.js
+++ b/frontend/src/Metamaps/Views/ChatView.js
@@ -9,326 +9,346 @@ import Backbone from 'backbone'
import Autolinker from 'autolinker'
import _ from 'lodash'
import underscore from 'underscore'
+import outdent from 'outdent'
// TODO is this line good or bad
// Backbone.$ = window.$
-const linker = new Autolinker({ newWindow: true, truncate: 50, email: false, phone: false, twitter: false });
+const linker = new Autolinker({ newWindow: true, truncate: 50, email: false, phone: false, twitter: false })
var Private = {
- messageHTML: "
" +
- "
" +
- "
{{ message }}
" +
- "
{{ timestamp }}
" +
- "
" +
- "
",
- participantHTML: "" +
- "
" +
- "
{{ username }} {{ selfName }}
" +
- "
" +
- "
" +
- "
" +
- "
" +
- "
",
- templates: function() {
- underscore.templateSettings = {
- interpolate: /\{\{(.+?)\}\}/g
- };
- this.messageTemplate = underscore.template(Private.messageHTML);
-
- this.participantTemplate = underscore.template(Private.participantHTML);
- },
- createElements: function() {
- this.$unread = $('');
- this.$button = $('');
- this.$messageInput = $('');
- this.$juntoHeader = $('');
- this.$videoToggle = $('');
- this.$cursorToggle = $('');
- this.$participants = $('');
- this.$conversationInProgress = $('LIVE LEAVEJOIN
');
- this.$chatHeader = $('');
- this.$soundToggle = $('');
- this.$messages = $('');
- this.$container = $('');
- },
- attachElements: function() {
- this.$button.append(this.$unread);
-
- this.$juntoHeader.append(this.$videoToggle);
- this.$juntoHeader.append(this.$cursorToggle);
-
- this.$chatHeader.append(this.$soundToggle);
-
- this.$participants.append(this.$conversationInProgress);
-
- this.$container.append(this.$juntoHeader);
- this.$container.append(this.$participants);
- this.$container.append(this.$chatHeader);
- this.$container.append(this.$button);
- this.$container.append(this.$messages);
- this.$container.append(this.$messageInput);
- },
- addEventListeners: function() {
- var self = this;
-
- this.participants.on('add', function (participant) {
- Private.addParticipant.call(self, participant);
- });
-
- this.participants.on('remove', function (participant) {
- Private.removeParticipant.call(self, participant);
- });
-
- this.$button.on('click', function () {
- Handlers.buttonClick.call(self);
- });
- this.$videoToggle.on('click', function () {
- Handlers.videoToggleClick.call(self);
- });
- this.$cursorToggle.on('click', function () {
- Handlers.cursorToggleClick.call(self);
- });
- this.$soundToggle.on('click', function () {
- Handlers.soundToggleClick.call(self);
- });
- this.$messageInput.on('keyup', function (event) {
- Handlers.keyUp.call(self, event);
- });
- this.$messageInput.on('focus', function () {
- Handlers.inputFocus.call(self);
- });
- this.$messageInput.on('blur', function () {
- Handlers.inputBlur.call(self);
- });
- },
- initializeSounds: function() {
- this.sound = new Howl({
- urls: [Metamaps.Erb['sounds/MM_sounds.mp3'], Metamaps.Erb['sounds/MM_sounds.ogg']],
- sprite: {
- joinmap: [0, 561],
- leavemap: [1000, 592],
- receivechat: [2000, 318],
- sendchat: [3000, 296],
- sessioninvite: [4000, 5393, true]
- }
- });
- },
- incrementUnread: function() {
- this.unreadMessages++;
- this.$unread.html(this.unreadMessages);
- this.$unread.show();
- },
- addMessage: function(message, isInitial, wasMe) {
-
- if (!this.isOpen && !isInitial) Private.incrementUnread.call(this);
-
- function addZero(i) {
- if (i < 10) {
- i = "0" + i;
- }
- return i;
- }
- var m = _.clone(message.attributes);
-
- var today = new Date();
- m.timestamp = new Date(m.created_at);
-
- var date = (m.timestamp.getMonth() + 1) + '/' + m.timestamp.getDate();
- date += " " + addZero(m.timestamp.getHours()) + ":" + addZero(m.timestamp.getMinutes());
- m.timestamp = date;
- m.image = m.user_image || 'http://www.hotpepper.ca/wp-content/uploads/2014/11/default_profile_1_200x200.png'; // TODO: remove
- m.message = linker.link(m.message);
- var $html = $(this.messageTemplate(m));
- this.$messages.append($html);
- if (!isInitial) this.scrollMessages(200);
-
- if (!wasMe && !isInitial && this.alertSound) this.sound.play('receivechat');
- },
- initialMessages: function() {
- var messages = this.messages.models;
- for (var i = 0; i < messages.length; i++) {
- Private.addMessage.call(this, messages[i], true);
- }
- },
- handleInputMessage: function() {
- var message = {
- message: this.$messageInput.val(),
- };
- this.$messageInput.val('');
- $(document).trigger(ChatView.events.message + '-' + this.room, [message]);
- },
- addParticipant: function(participant) {
- var p = _.clone(participant.attributes);
- if (p.self) {
- p.selfClass = 'is-self';
- p.selfName = '(me)';
- } else {
- p.selfClass = '';
- p.selfName = '';
- }
- var html = this.participantTemplate(p);
- this.$participants.append(html);
- },
- removeParticipant: function(participant) {
- this.$container.find('.participant-' + participant.get('id')).remove();
+ messageHTML: outdent`
+
+
+
{{ message }}
+
{{ timestamp }}
+
+
`,
+ participantHTML: outdent`
+
+
+

+
+
+ {{ username }} {{ selfName }}
+
+
+
+
+
+
+
+
`,
+ templates: function () {
+ underscore.templateSettings = {
+ interpolate: /\{\{(.+?)\}\}/g
}
-};
+ this.messageTemplate = underscore.template(Private.messageHTML)
+
+ this.participantTemplate = underscore.template(Private.participantHTML)
+ },
+ createElements: function () {
+ this.$unread = $('')
+ this.$button = $('')
+ this.$messageInput = $('')
+ this.$juntoHeader = $('')
+ this.$videoToggle = $('')
+ this.$cursorToggle = $('')
+ this.$participants = $('')
+ this.$conversationInProgress = $(outdent`
+
+ LIVE
+
+ LEAVE
+
+
+ JOIN
+
+
`)
+ this.$chatHeader = $('')
+ this.$soundToggle = $('')
+ this.$messages = $('')
+ this.$container = $('')
+ },
+ attachElements: function () {
+ this.$button.append(this.$unread)
+
+ this.$juntoHeader.append(this.$videoToggle)
+ this.$juntoHeader.append(this.$cursorToggle)
+
+ this.$chatHeader.append(this.$soundToggle)
+
+ this.$participants.append(this.$conversationInProgress)
+
+ this.$container.append(this.$juntoHeader)
+ this.$container.append(this.$participants)
+ this.$container.append(this.$chatHeader)
+ this.$container.append(this.$button)
+ this.$container.append(this.$messages)
+ this.$container.append(this.$messageInput)
+ },
+ addEventListeners: function () {
+ var self = this
+
+ this.participants.on('add', function (participant) {
+ Private.addParticipant.call(self, participant)
+ })
+
+ this.participants.on('remove', function (participant) {
+ Private.removeParticipant.call(self, participant)
+ })
+
+ this.$button.on('click', function () {
+ Handlers.buttonClick.call(self)
+ })
+ this.$videoToggle.on('click', function () {
+ Handlers.videoToggleClick.call(self)
+ })
+ this.$cursorToggle.on('click', function () {
+ Handlers.cursorToggleClick.call(self)
+ })
+ this.$soundToggle.on('click', function () {
+ Handlers.soundToggleClick.call(self)
+ })
+ this.$messageInput.on('keyup', function (event) {
+ Handlers.keyUp.call(self, event)
+ })
+ this.$messageInput.on('focus', function () {
+ Handlers.inputFocus.call(self)
+ })
+ this.$messageInput.on('blur', function () {
+ Handlers.inputBlur.call(self)
+ })
+ },
+ initializeSounds: function () {
+ this.sound = new Howl({
+ urls: [Metamaps.Erb['sounds/MM_sounds.mp3'], Metamaps.Erb['sounds/MM_sounds.ogg']],
+ sprite: {
+ joinmap: [0, 561],
+ leavemap: [1000, 592],
+ receivechat: [2000, 318],
+ sendchat: [3000, 296],
+ sessioninvite: [4000, 5393, true]
+ }
+ })
+ },
+ incrementUnread: function () {
+ this.unreadMessages++
+ this.$unread.html(this.unreadMessages)
+ this.$unread.show()
+ },
+ addMessage: function (message, isInitial, wasMe) {
+ if (!this.isOpen && !isInitial) Private.incrementUnread.call(this)
+
+ function addZero (i) {
+ if (i < 10) {
+ i = '0' + i
+ }
+ return i
+ }
+ var m = _.clone(message.attributes)
+
+ m.timestamp = new Date(m.created_at)
+
+ var date = (m.timestamp.getMonth() + 1) + '/' + m.timestamp.getDate()
+ date += ' ' + addZero(m.timestamp.getHours()) + ':' + addZero(m.timestamp.getMinutes())
+ m.timestamp = date
+ m.image = m.user_image || 'http://www.hotpepper.ca/wp-content/uploads/2014/11/default_profile_1_200x200.png' // TODO: remove
+ m.message = linker.link(m.message)
+ var $html = $(this.messageTemplate(m))
+ this.$messages.append($html)
+ if (!isInitial) this.scrollMessages(200)
+
+ if (!wasMe && !isInitial && this.alertSound) this.sound.play('receivechat')
+ },
+ initialMessages: function () {
+ var messages = this.messages.models
+ for (var i = 0; i < messages.length; i++) {
+ Private.addMessage.call(this, messages[i], true)
+ }
+ },
+ handleInputMessage: function () {
+ var message = {
+ message: this.$messageInput.val()
+ }
+ this.$messageInput.val('')
+ $(document).trigger(ChatView.events.message + '-' + this.room, [message])
+ },
+ addParticipant: function (participant) {
+ var p = _.clone(participant.attributes)
+ if (p.self) {
+ p.selfClass = 'is-self'
+ p.selfName = '(me)'
+ } else {
+ p.selfClass = ''
+ p.selfName = ''
+ }
+ var html = this.participantTemplate(p)
+ this.$participants.append(html)
+ },
+ removeParticipant: function (participant) {
+ this.$container.find('.participant-' + participant.get('id')).remove()
+ }
+}
var Handlers = {
- buttonClick: function() {
- if (this.isOpen) this.close();
- else if (!this.isOpen) this.open();
- },
- videoToggleClick: function() {
- this.$videoToggle.toggleClass('active');
- this.videosShowing = !this.videosShowing;
- $(document).trigger(this.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff);
- },
- cursorToggleClick: function() {
- this.$cursorToggle.toggleClass('active');
- this.cursorsShowing = !this.cursorsShowing;
- $(document).trigger(this.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff);
- },
- soundToggleClick: function() {
- this.alertSound = !this.alertSound;
- this.$soundToggle.toggleClass('active');
- },
- keyUp: function(event) {
- switch(event.which) {
- case 13: // enter
- Private.handleInputMessage.call(this);
- break;
- }
- },
- inputFocus: function() {
- $(document).trigger(ChatView.events.inputFocus);
- },
- inputBlur: function() {
- $(document).trigger(ChatView.events.inputBlur);
+ buttonClick: function () {
+ if (this.isOpen) this.close()
+ else if (!this.isOpen) this.open()
+ },
+ videoToggleClick: function () {
+ this.$videoToggle.toggleClass('active')
+ this.videosShowing = !this.videosShowing
+ $(document).trigger(this.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff)
+ },
+ cursorToggleClick: function () {
+ this.$cursorToggle.toggleClass('active')
+ this.cursorsShowing = !this.cursorsShowing
+ $(document).trigger(this.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff)
+ },
+ soundToggleClick: function () {
+ this.alertSound = !this.alertSound
+ this.$soundToggle.toggleClass('active')
+ },
+ keyUp: function (event) {
+ switch (event.which) {
+ case 13: // enter
+ Private.handleInputMessage.call(this)
+ break
}
-};
+ },
+ inputFocus: function () {
+ $(document).trigger(ChatView.events.inputFocus)
+ },
+ inputBlur: function () {
+ $(document).trigger(ChatView.events.inputBlur)
+ }
+}
-const ChatView = function(messages, mapper, room) {
- var self = this;
+const ChatView = function (messages, mapper, room) {
+ this.room = room
+ this.mapper = mapper
+ this.messages = messages // backbone collection
- this.room = room;
- this.mapper = mapper;
- this.messages = messages; // backbone collection
+ this.isOpen = false
+ this.alertSound = true // whether to play sounds on arrival of new messages or not
+ this.cursorsShowing = true
+ this.videosShowing = true
+ this.unreadMessages = 0
+ this.participants = new Backbone.Collection()
- this.isOpen = false;
- this.alertSound = true; // whether to play sounds on arrival of new messages or not
- this.cursorsShowing = true;
- this.videosShowing = true;
- this.unreadMessages = 0;
- this.participants = new Backbone.Collection();
-
- Private.templates.call(this);
- Private.createElements.call(this);
- Private.attachElements.call(this);
- Private.addEventListeners.call(this);
- Private.initialMessages.call(this);
- Private.initializeSounds.call(this);
- this.$container.css({
- right: '-300px'
- });
-};
+ Private.templates.call(this)
+ Private.createElements.call(this)
+ Private.attachElements.call(this)
+ Private.addEventListeners.call(this)
+ Private.initialMessages.call(this)
+ Private.initializeSounds.call(this)
+ this.$container.css({
+ right: '-300px'
+ })
+}
ChatView.prototype.conversationInProgress = function (participating) {
- this.$conversationInProgress.show();
- this.$participants.addClass('is-live');
- if (participating) this.$participants.addClass('is-participating');
- this.$button.addClass('active');
+ this.$conversationInProgress.show()
+ this.$participants.addClass('is-live')
+ if (participating) this.$participants.addClass('is-participating')
+ this.$button.addClass('active')
- // hide invite to call buttons
+// hide invite to call buttons
}
ChatView.prototype.conversationEnded = function () {
- this.$conversationInProgress.hide();
- this.$participants.removeClass('is-live');
- this.$participants.removeClass('is-participating');
- this.$button.removeClass('active');
- this.$participants.find('.participant').removeClass('active');
- this.$participants.find('.participant').removeClass('pending');
+ this.$conversationInProgress.hide()
+ this.$participants.removeClass('is-live')
+ this.$participants.removeClass('is-participating')
+ this.$button.removeClass('active')
+ this.$participants.find('.participant').removeClass('active')
+ this.$participants.find('.participant').removeClass('pending')
}
ChatView.prototype.leaveConversation = function () {
- this.$participants.removeClass('is-participating');
+ this.$participants.removeClass('is-participating')
}
ChatView.prototype.mapperJoinedCall = function (id) {
- this.$participants.find('.participant-' + id).addClass('active');
+ this.$participants.find('.participant-' + id).addClass('active')
}
ChatView.prototype.mapperLeftCall = function (id) {
- this.$participants.find('.participant-' + id).removeClass('active');
+ this.$participants.find('.participant-' + id).removeClass('active')
}
ChatView.prototype.invitationPending = function (id) {
- this.$participants.find('.participant-' + id).addClass('pending');
+ this.$participants.find('.participant-' + id).addClass('pending')
}
ChatView.prototype.invitationAnswered = function (id) {
- this.$participants.find('.participant-' + id).removeClass('pending');
+ this.$participants.find('.participant-' + id).removeClass('pending')
}
ChatView.prototype.addParticipant = function (participant) {
- this.participants.add(participant);
+ this.participants.add(participant)
}
ChatView.prototype.removeParticipant = function (username) {
- var p = this.participants.find(function (p) { return p.get('username') === username; });
- if (p) {
- this.participants.remove(p);
- }
+ var p = this.participants.find(p => p.get('username') === username)
+ if (p) {
+ this.participants.remove(p)
+ }
}
ChatView.prototype.removeParticipants = function () {
- this.participants.remove(this.participants.models);
+ this.participants.remove(this.participants.models)
}
ChatView.prototype.open = function () {
- this.$container.css({
- right: '0'
- });
- this.$messageInput.focus();
- this.isOpen = true;
- this.unreadMessages = 0;
- this.$unread.hide();
- this.scrollMessages(0);
- $(document).trigger(ChatView.events.openTray);
+ this.$container.css({
+ right: '0'
+ })
+ this.$messageInput.focus()
+ this.isOpen = true
+ this.unreadMessages = 0
+ this.$unread.hide()
+ this.scrollMessages(0)
+ $(document).trigger(ChatView.events.openTray)
}
-ChatView.prototype.addMessage = function(message, isInitial, wasMe) {
- this.messages.add(message);
- Private.addMessage.call(this, message, isInitial, wasMe);
+ChatView.prototype.addMessage = function (message, isInitial, wasMe) {
+ this.messages.add(message)
+ Private.addMessage.call(this, message, isInitial, wasMe)
}
-ChatView.prototype.scrollMessages = function(duration) {
- duration = duration || 0;
+ChatView.prototype.scrollMessages = function (duration) {
+ duration = duration || 0
- this.$messages.animate({
- scrollTop: this.$messages[0].scrollHeight
- }, duration);
+ this.$messages.animate({
+ scrollTop: this.$messages[0].scrollHeight
+ }, duration)
}
ChatView.prototype.clearMessages = function () {
- this.unreadMessages = 0;
- this.$unread.hide();
- this.$messages.empty();
+ this.unreadMessages = 0
+ this.$unread.hide()
+ this.$messages.empty()
}
ChatView.prototype.close = function () {
- this.$container.css({
- right: '-300px'
- });
- this.$messageInput.blur();
- this.isOpen = false;
- $(document).trigger(ChatView.events.closeTray);
+ this.$container.css({
+ right: '-300px'
+ })
+ this.$messageInput.blur()
+ this.isOpen = false
+ $(document).trigger(ChatView.events.closeTray)
}
ChatView.prototype.remove = function () {
- this.$button.off();
- this.$container.remove();
+ this.$button.off()
+ this.$container.remove()
}
/**
@@ -336,15 +356,15 @@ ChatView.prototype.remove = function () {
* @static
*/
ChatView.events = {
- message: 'ChatView:message',
- openTray: 'ChatView:openTray',
- closeTray: 'ChatView:closeTray',
- inputFocus: 'ChatView:inputFocus',
- inputBlur: 'ChatView:inputBlur',
- cursorsOff: 'ChatView:cursorsOff',
- cursorsOn: 'ChatView:cursorsOn',
- videosOff: 'ChatView:videosOff',
- videosOn: 'ChatView:videosOn'
-};
+ message: 'ChatView:message',
+ openTray: 'ChatView:openTray',
+ closeTray: 'ChatView:closeTray',
+ inputFocus: 'ChatView:inputFocus',
+ inputBlur: 'ChatView:inputBlur',
+ cursorsOff: 'ChatView:cursorsOff',
+ cursorsOn: 'ChatView:cursorsOn',
+ videosOff: 'ChatView:videosOff',
+ videosOn: 'ChatView:videosOn'
+}
export default ChatView