From d82288c9f287b655135d01c2b4a704c0991a4792 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Wed, 17 Feb 2016 13:27:22 +1300 Subject: [PATCH] fixed up call ending/starting events --- app/assets/javascripts/src/Metamaps.js.erb | 127 ++++++++++++++---- .../javascripts/src/views/chatView.js.erb | 23 +++- app/assets/javascripts/src/views/room.js | 9 +- app/assets/stylesheets/junto.css.erb | 24 +++- realtime/realtime-server.js | 11 +- 5 files changed, 154 insertions(+), 40 deletions(-) diff --git a/app/assets/javascripts/src/Metamaps.js.erb b/app/assets/javascripts/src/Metamaps.js.erb index bef96701..832aeeb9 100644 --- a/app/assets/javascripts/src/Metamaps.js.erb +++ b/app/assets/javascripts/src/Metamaps.js.erb @@ -2061,6 +2061,7 @@ Metamaps.Realtime = { $(document).off('mousemove'); self.socket.removeAllListeners(); + if (self.inConversation) self.leaveCall(); self.socket.emit('endMapperNotify'); $(".collabCompass").remove(); self.status = false; @@ -2100,7 +2101,6 @@ Metamaps.Realtime = { promptToJoin: function (data) { var self = Metamaps.Realtime; - console.log(data); var notifyText = 'There\'s a conversation happening, want to join?'; notifyText += ' '; notifyText += ' '; @@ -2117,10 +2117,68 @@ Metamaps.Realtime = { Metamaps.GlobalUI.notifyUser(notifyText, true); self.room.conversationInProgress(); }, - conversationHasEnded: function () { + countOthersInConversation: function () { + var self = Metamaps.Realtime; + var count = 0; + + for (var key in self.mappersOnMap) { + if (self.mappersOnMap[key].inConversation) count++; + } + return count; + }, + mapperJoinedCall: function (id) { + var self = Metamaps.Realtime; + var mapper = self.mappersOnMap[id]; + + if (mapper) { + if (self.inConversation) { + var username = mapper.name; + var notifyText = username + ' joined the call'; + Metamaps.GlobalUI.notifyUser(notifyText); + } + + mapper.inConversation = true; + self.room.chat.mapperJoinedCall(id); + } + }, + mapperLeftCall: function (id) { + var self = Metamaps.Realtime; + var mapper = self.mappersOnMap[id]; + + if (mapper) { + if (self.inConversation) { + var username = mapper.name; + var notifyText = username + ' left the call'; + Metamaps.GlobalUI.notifyUser(notifyText); + } + + mapper.inConversation = false; + self.room.chat.mapperLeftCall(id); + + if (self.countOthersInConversation() < 2) { + self.callEnded(); + } + } + }, + callEnded: function () { var self = Metamaps.Realtime; self.room.conversationEnding(); + self.room.leaveVideoOnly(); + self.inConversation = false; + self.videosInPosition = 1; + self.localVideo.view.$container.hide().css({ + top: '72px', + left: '30px' + }); + self.localVideo.view.audioOn(); + self.localVideo.view.videoOn(); + self.webrtc.webrtc.localStreams.forEach(function (stream) { + stream.getTracks().forEach(function (track) { + track.stop(); + }); + }); + self.webrtc.webrtc.localStreams = []; }, invitedToCall: function (inviter) { var self = Metamaps.Realtime; @@ -2131,6 +2189,15 @@ Metamaps.Realtime = { notifyText += ' '; Metamaps.GlobalUI.notifyUser(notifyText, true); }, + invitedToJoin: function (inviter) { + var self = Metamaps.Realtime; + + var username = self.mappersOnMap[inviter].name; + var notifyText = username + ' is inviting you to the conversation. Join?'; + notifyText += ' '; + notifyText += ' '; + Metamaps.GlobalUI.notifyUser(notifyText, true); + }, acceptCall: function (userid) { var self = Metamaps.Realtime; self.socket.emit('callAccepted', { @@ -2159,6 +2226,15 @@ Metamaps.Realtime = { }); Metamaps.GlobalUI.notifyUser('Invitation pending...', true); }, + inviteToJoin: function (userid) { + var self = Metamaps.Realtime; + self.socket.emit('inviteToJoin', { + mapid: Metamaps.Active.Map.id, + inviter: Metamaps.Active.Mapper.id, + invited: userid + }); + Metamaps.GlobalUI.notifyUser('Invitation has been sent.'); + }, callAccepted: function (userid) { var self = Metamaps.Realtime; @@ -2170,7 +2246,7 @@ Metamaps.Realtime = { var self = Metamaps.Realtime; var username = self.mappersOnMap[userid].name; - Metamaps.GlobalUI.notifyUser(username + ' isn\'t feeling it right now...'); + Metamaps.GlobalUI.notifyUser(username + ' didn\'t accept your invite.'); }, joinCall: function () { var self = Metamaps.Realtime; @@ -2186,16 +2262,31 @@ Metamaps.Realtime = { self.room.join(); }); self.inConversation = true; + self.socket.emit('mapperJoinedCall', { + mapid: Metamaps.Active.Map.id, + id: Metamaps.Active.Mapper.id + }); self.webrtc.startLocalVideo(); Metamaps.GlobalUI.clearNotify(); }, leaveCall: function () { var self = Metamaps.Realtime; + self.socket.emit('mapperLeftCall', { + mapid: Metamaps.Active.Map.id, + id: Metamaps.Active.Mapper.id + }); + self.room.leaveVideoOnly(); self.inConversation = false; self.videosInPosition = 1; self.localVideo.view.$container.hide(); + + // if there's only two people in the room, and we're leaving + // we should shut down the call locally + if (self.countOthersInConversation() === 1) { + self.callEnded(); + } }, turnOff: function (silent) { var self = Metamaps.Realtime; @@ -2223,14 +2314,17 @@ Metamaps.Realtime = { mapid: Metamaps.Active.Map.id }); - socket.on(myId + '-' + Metamaps.Active.Map.id + '-invitedToCall', self.invitedToCall); + socket.on(myId + '-' + Metamaps.Active.Map.id + '-invitedToCall', self.invitedToCall); // new call + socket.on(myId + '-' + Metamaps.Active.Map.id + '-invitedToJoin', self.invitedToJoin); // call already in progress socket.on(myId + '-' + Metamaps.Active.Map.id + '-callAccepted', self.callAccepted); socket.on(myId + '-' + Metamaps.Active.Map.id + '-callDenied', self.callDenied); // receive word that there's a conversation in progress socket.on('maps-' + Metamaps.Active.Map.id + '-callInProgress', self.promptToJoin); socket.on('maps-' + Metamaps.Active.Map.id + '-callStarting', self.conversationHasBegun); - socket.on('maps-' + Metamaps.Active.Map.id + '-callEnding', self.conversationHasEnded); + + socket.on('maps-' + Metamaps.Active.Map.id + '-mapperJoinedCall', self.mapperJoinedCall); + socket.on('maps-' + Metamaps.Active.Map.id + '-mapperLeftCall', self.mapperLeftCall); // if you're the 'new guy' update your list with who's already online socket.on(myId + '-' + Metamaps.Active.Map.id + '-UpdateMapperList', self.updateMapperList); @@ -2342,25 +2436,6 @@ Metamaps.Realtime = { }; $(document).on(Metamaps.Views.room.events.newMessage, sendNewMessage); - $(document).on(Metamaps.Views.room.events.callEnded, function () { - socket.emit('callEnded', { mapid: Metamaps.Active.Map.id }); // so that anyone who isn't currently in the call gets notified - self.inConversation = false; - self.videosInPosition = 1; - Metamaps.GlobalUI.notifyUser('Conversation has ended.'); - self.localVideo.view.$container.hide().css({ - top: '72px', - left: '30px' - }); - self.localVideo.view.audioOn(); - self.localVideo.view.videoOn(); - self.webrtc.webrtc.localStreams.forEach(function (stream) { - stream.getTracks().forEach(function (track) { - track.stop(); - }); - }); - self.webrtc.webrtc.localStreams = []; - }); - }, attachMapListener: function(){ var self = Metamaps.Realtime; @@ -2521,6 +2596,10 @@ Metamaps.Realtime = { self.room.chat.removeParticipant(data.username); Metamaps.GlobalUI.notifyUser(data.username + ' just left the map'); + + if (self.inConversation && self.countOthersInConversation() < 2) { + self.callEnded(); + } }, newCollaborator: function (data) { var self = Metamaps.Realtime; diff --git a/app/assets/javascripts/src/views/chatView.js.erb b/app/assets/javascripts/src/views/chatView.js.erb index e5eb7c91..b3d02999 100644 --- a/app/assets/javascripts/src/views/chatView.js.erb +++ b/app/assets/javascripts/src/views/chatView.js.erb @@ -15,7 +15,9 @@ Metamaps.Views.chatView = (function () { participantHTML: "
" + "
" + "
{{ username }}
" + - "" + + "" + + "" + + "IN CALL" + "
" + "
", templates: function() { @@ -214,15 +216,30 @@ Metamaps.Views.chatView = (function () { chatView.prototype.conversationInProgress = function (participating) { this.$conversationInProgress.show(); this.$participants.addClass('is-live'); - if (participating) this.$conversationInProgress.addClass('is-participating'); + if (participating) this.$participants.addClass('is-participating'); this.$button.addClass('active'); + + // hide invite to call buttons } chatView.prototype.conversationEnded = function () { this.$conversationInProgress.hide(); this.$participants.removeClass('is-live'); - this.$conversationInProgress.removeClass('is-participating'); + this.$participants.removeClass('is-participating'); this.$button.removeClass('active'); + this.$participants.find('.participant').removeClass('active'); + } + + chatView.prototype.leaveConversation = function () { + this.$participants.removeClass('is-participating'); + } + + chatView.prototype.mapperJoinedCall = function (id) { + this.$participants.find('.participant-' + id).addClass('active'); + } + + chatView.prototype.mapperLeftCall = function (id) { + this.$participants.find('.participant-' + id).removeClass('active'); } chatView.prototype.addParticipant = function (participant) { diff --git a/app/assets/javascripts/src/views/room.js b/app/assets/javascripts/src/views/room.js index 211c3e7a..e54dfb00 100644 --- a/app/assets/javascripts/src/views/room.js +++ b/app/assets/javascripts/src/views/room.js @@ -43,12 +43,12 @@ Metamaps.Views.room = (function () { } room.prototype.leaveVideoOnly = function() { + this.chat.leaveConversation(); // the conversation will carry on without you for (var id in this.videos) { this.removeVideo(id); } this.isActiveRoom = false; this.webrtc.leaveRoom(); - this.chat.conversationEnded(); } room.prototype.leave = function() { @@ -150,10 +150,6 @@ Metamaps.Views.room = (function () { if (this.videos[id]) { this.videos[id].remove(); delete this.videos[id]; - if (Object.keys(this.videos).length === 0) { - this.leaveVideoOnly(); - $(document).trigger(room.events.callEnded); - } } } @@ -191,8 +187,7 @@ Metamaps.Views.room = (function () { * @static */ room.events = { - newMessage: "Room:newMessage", - callEnded: "Room:callEnded" + newMessage: "Room:newMessage" }; return room; diff --git a/app/assets/stylesheets/junto.css.erb b/app/assets/stylesheets/junto.css.erb index 73b7077d..a583affc 100644 --- a/app/assets/stylesheets/junto.css.erb +++ b/app/assets/stylesheets/junto.css.erb @@ -190,10 +190,10 @@ .chat-box .participants .conversation-live .leave { display: none; } -.chat-box .participants .conversation-live.is-participating .leave { +.chat-box .participants.is-participating .conversation-live .leave { display: block; } -.chat-box .participants .conversation-live.is-participating .join { +.chat-box .participants.is-participating .conversation-live .join { display: none; } .chat-box .participants .participant { @@ -226,13 +226,29 @@ padding: 2px 8px 0; text-align: left; } -.chat-box .participants.is-live .participant .chat-participant-invite { +.chat-box .participants.is-live .participant .chat-participant-invite-call { display: none; } -.chat-box .participants .participant .chat-participant-invite { +.chat-box .participants .participant .chat-participant-invite-join { + display: none; +} +.chat-box .participants.is-live .participant:not(.active) .chat-participant-invite-join { + display: block; +} +.chat-box .participants .participant .chat-participant-invite-call, +.chat-box .participants .participant .chat-participant-invite-join + { float: right; background: #4FC059 url(<%= asset_path 'invitepeer16.png' %>) no-repeat center center; } +.chat-box .participants .participant .chat-participant-participating { + float: right; + display: none; + margin-top: 14px; +} +.chat-box .participants .participant.active .chat-participant-participating { + display: block; +} .chat-box .chat-header { width: 100%; padding: 16px 8px 16px 16px; diff --git a/realtime/realtime-server.js b/realtime/realtime-server.js index cd386aa6..9326dd4d 100644 --- a/realtime/realtime-server.js +++ b/realtime/realtime-server.js @@ -31,6 +31,10 @@ function start() { socket.on('inviteACall', function (data) { socket.broadcast.emit(data.invited + '-' + data.mapid + '-invitedToCall', data.inviter); }); + // send an invitation to join a call in progress + socket.on('inviteToJoin', function (data) { + socket.broadcast.emit(data.invited + '-' + data.mapid + '-invitedToJoin', data.inviter); + }); // send response back to the inviter socket.on('callAccepted', function (data) { socket.broadcast.emit(data.inviter + '-' + data.mapid + '-callAccepted', data.invited); @@ -39,8 +43,11 @@ function start() { socket.on('callDenied', function (data) { socket.broadcast.emit(data.inviter + '-' + data.mapid + '-callDenied', data.invited); }); - socket.on('callEnded', function (data) { - socket.broadcast.emit('maps-' + data.mapid + '-callEnding'); + socket.on('mapperJoinedCall', function (data) { + socket.broadcast.emit('maps-' + data.mapid + '-mapperJoinedCall', data.id); + }); + socket.on('mapperLeftCall', function (data) { + socket.broadcast.emit('maps-' + data.mapid + '-mapperLeftCall', data.id); }); // this will ping everyone on a map that there's a person just joined the map