inviting, joining, and leaving conversations
This commit is contained in:
parent
8b090be0b3
commit
a905094d4d
6 changed files with 151 additions and 74 deletions
|
@ -1915,8 +1915,10 @@ Metamaps.Realtime = {
|
|||
webrtc: null,
|
||||
readyToCall: false,
|
||||
mappersOnMap: {},
|
||||
chatOpen: false,
|
||||
status: true, // stores whether realtime is True/On or False/Off,
|
||||
broadcastingStatus: false,
|
||||
inConversation: false,
|
||||
localVideo: null,
|
||||
init: function () {
|
||||
var self = Metamaps.Realtime;
|
||||
|
@ -1927,19 +1929,10 @@ Metamaps.Realtime = {
|
|||
var turnOff = function () {
|
||||
self.turnOff();
|
||||
};
|
||||
var toggleVideo = function () {
|
||||
self.toggleVideo();
|
||||
};
|
||||
$(".rtOn").click(reenableRealtime);
|
||||
$(".rtOff").click(turnOff);
|
||||
$(".startVideo").click(toggleVideo);
|
||||
|
||||
$(document).on(Metamaps.Views.chatView.events.openTray, function () {
|
||||
$('.main').addClass('compressed');
|
||||
});
|
||||
$(document).on(Metamaps.Views.chatView.events.closeTray, function () {
|
||||
$('.main').removeClass('compressed');
|
||||
});
|
||||
self.addJuntoListeners();
|
||||
|
||||
var railsEnv = $('body').data('env');
|
||||
var whichToConnect = railsEnv === 'development' ? self.stringForLocalhost : self.stringForHeroku;
|
||||
|
@ -1995,7 +1988,34 @@ Metamaps.Realtime = {
|
|||
self.createChat();
|
||||
} // if Metamaps.Active.Mapper
|
||||
},
|
||||
handleVideoAdded: function (v) {
|
||||
addJuntoListeners: function () {
|
||||
var self = Metamaps.Realtime;
|
||||
|
||||
$(document).on(Metamaps.Views.chatView.events.openTray, function () {
|
||||
$('.main').addClass('compressed');
|
||||
self.chatOpen = true;
|
||||
self.positionPeerIcons();
|
||||
});
|
||||
$(document).on(Metamaps.Views.chatView.events.closeTray, function () {
|
||||
$('.main').removeClass('compressed');
|
||||
self.chatOpen = false;
|
||||
self.positionPeerIcons();
|
||||
});
|
||||
$(document).on(Metamaps.Views.chatView.events.videosOn, function () {
|
||||
$('#wrapper').removeClass('hideVideos');
|
||||
});
|
||||
$(document).on(Metamaps.Views.chatView.events.videosOff, function () {
|
||||
$('#wrapper').addClass('hideVideos');
|
||||
});
|
||||
$(document).on(Metamaps.Views.chatView.events.cursorsOn, function () {
|
||||
$('#wrapper').removeClass('hideCursors');
|
||||
});
|
||||
$(document).on(Metamaps.Views.chatView.events.cursorsOff, function () {
|
||||
$('#wrapper').addClass('hideCursors');
|
||||
});
|
||||
},
|
||||
handleVideoAdded: function (v, id) {
|
||||
var self = Metamaps.Realtime;
|
||||
// random position for now
|
||||
var top = Math.floor((Math.random() * ($('#wrapper').height() - 100)) + 1);
|
||||
var left = Math.floor((Math.random() * ($('#wrapper').width() - 100)) + 1);
|
||||
|
@ -2006,6 +2026,9 @@ Metamaps.Realtime = {
|
|||
top: top + 'px',
|
||||
left: left + 'px'
|
||||
});
|
||||
v.$container.find('.video-cutoff').css({
|
||||
border: '2px solid ' + self.mappersOnMap[id].color
|
||||
});
|
||||
},
|
||||
startActiveMap: function () {
|
||||
var self = Metamaps.Realtime;
|
||||
|
@ -2069,7 +2092,23 @@ Metamaps.Realtime = {
|
|||
var notifyText = 'There\'s a conversation happening, want to join?';
|
||||
notifyText += ' <button type="button" class="toast-button button" onclick="Metamaps.Realtime.joinCall()">Yes</button>';
|
||||
notifyText += ' <button type="button" class="toast-button button btn-no" onclick="Metamaps.GlobalUI.clearNotify()">No</button>';
|
||||
Metamaps.GlobalUI.notifyUser(notifyText);
|
||||
Metamaps.GlobalUI.notifyUser(notifyText, true);
|
||||
self.room.conversationInProgress();
|
||||
},
|
||||
conversationHasBegun: function () {
|
||||
var self = Metamaps.Realtime;
|
||||
|
||||
if (self.inConversation) return;
|
||||
var notifyText = 'There\'s a conversation starting, want to join?';
|
||||
notifyText += ' <button type="button" class="toast-button button" onclick="Metamaps.Realtime.joinCall()">Yes</button>';
|
||||
notifyText += ' <button type="button" class="toast-button button btn-no" onclick="Metamaps.GlobalUI.clearNotify()">No</button>';
|
||||
Metamaps.GlobalUI.notifyUser(notifyText, true);
|
||||
self.room.conversationInProgress();
|
||||
},
|
||||
conversationHasEnded: function () {
|
||||
var self = Metamaps.Realtime;
|
||||
|
||||
self.room.conversationEnding();
|
||||
},
|
||||
invitedToCall: function (inviter) {
|
||||
var self = Metamaps.Realtime;
|
||||
|
@ -2078,7 +2117,7 @@ Metamaps.Realtime = {
|
|||
var notifyText = username + ' is suggesting a video call. What do you think?';
|
||||
notifyText += ' <button type="button" class="toast-button button" onclick="Metamaps.Realtime.acceptCall(' + inviter + ')">Yes</button>';
|
||||
notifyText += ' <button type="button" class="toast-button button btn-no" onclick="Metamaps.Realtime.denyCall(' + inviter + ')">No</button>';
|
||||
Metamaps.GlobalUI.notifyUser(notifyText);
|
||||
Metamaps.GlobalUI.notifyUser(notifyText, true);
|
||||
},
|
||||
acceptCall: function (userid) {
|
||||
var self = Metamaps.Realtime;
|
||||
|
@ -2133,38 +2172,16 @@ Metamaps.Realtime = {
|
|||
}
|
||||
self.room.join();
|
||||
});
|
||||
self.inConversation = true;
|
||||
self.webrtc.startLocalVideo();
|
||||
Metamaps.GlobalUI.clearNotify();
|
||||
},
|
||||
startVideo: function() {
|
||||
var
|
||||
self = Metamaps.Realtime;
|
||||
leaveCall: function () {
|
||||
var self = Metamaps.Realtime;
|
||||
|
||||
if (!self.videoInitialized) {
|
||||
self.webrtc.startLocalVideo();
|
||||
}
|
||||
else {
|
||||
self.webrtc.resume();
|
||||
}
|
||||
self.broadcastingStatus = true;
|
||||
self.localVideo.view.$container.show();
|
||||
$(".startVideo").html("stop broadcasting");
|
||||
},
|
||||
stopVideo: function () {
|
||||
var
|
||||
self = Metamaps.Realtime;
|
||||
|
||||
self.webrtc.pause();
|
||||
self.broadcastingStatus = false;
|
||||
self.localVideo.view.$container.hide();
|
||||
$(".startVideo").html("start my video");
|
||||
},
|
||||
toggleVideo: function () {
|
||||
var
|
||||
self = Metamaps.Realtime;
|
||||
|
||||
if (!self.broadcastingStatus) self.startVideo();
|
||||
else self.stopVideo();
|
||||
self.room.leaveVideoOnly();
|
||||
self.inConversation = false;
|
||||
self.localVideo.view.$container.hide();
|
||||
},
|
||||
turnOff: function (silent) {
|
||||
var self = Metamaps.Realtime;
|
||||
|
@ -2198,6 +2215,8 @@ Metamaps.Realtime = {
|
|||
|
||||
// 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);
|
||||
|
||||
// if you're the 'new guy' update your list with who's already online
|
||||
socket.on(myId + '-' + Metamaps.Active.Map.id + '-UpdateMapperList', self.updateMapperList);
|
||||
|
@ -2310,6 +2329,8 @@ 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;
|
||||
Metamaps.GlobalUI.notifyUser('Conversation has ended.');
|
||||
self.localVideo.view.$container.hide();
|
||||
self.webrtc.webrtc.localStreams.forEach(function (stream) {
|
||||
|
@ -2538,9 +2559,10 @@ Metamaps.Realtime = {
|
|||
var self = Metamaps.Realtime;
|
||||
var socket = Metamaps.Realtime.socket;
|
||||
|
||||
var boundary = self.chatOpen ? '#wrapper' : document;
|
||||
var mapper = self.mappersOnMap[id];
|
||||
var xMax=$(document).width();
|
||||
var yMax=$(document).height();
|
||||
var xMax=$(boundary).width();
|
||||
var yMax=$(boundary).height();
|
||||
var compassDiameter=56;
|
||||
var compassArrowSize=24;
|
||||
|
||||
|
@ -2575,9 +2597,10 @@ Metamaps.Realtime = {
|
|||
var self = Metamaps.Realtime;
|
||||
var socket = Metamaps.Realtime.socket;
|
||||
|
||||
var boundary = self.chatOpen ? '#wrapper' : document;
|
||||
var xLimit, yLimit;
|
||||
var xMax=$(document).width();
|
||||
var yMax=$(document).height();
|
||||
var xMax=$(boundary).width();
|
||||
var yMax=$(boundary).height();
|
||||
var compassDiameter=56;
|
||||
var compassArrowSize=24;
|
||||
|
||||
|
|
|
@ -13,8 +13,9 @@ Metamaps.Views.chatView = (function () {
|
|||
"<div class='clearfloat'></div>" +
|
||||
"</div>",
|
||||
participantHTML: "<div class='participant participant-{{ id }}'>" +
|
||||
"<div class='chat-participant-image'><img src='{{ image }}' /></div>" +
|
||||
"<div class='chat-participant-image'><img src='{{ image }}' style='border: 2px solid {{ color }};' /></div>" +
|
||||
"<div class='chat-participant-name'>{{ username }}</div>" +
|
||||
"<button type='button' class='button chat-participant-invite' onclick='Metamaps.Realtime.inviteACall({{ id}});'>I</button>" +
|
||||
"<div class='clearfloat'></div>" +
|
||||
"</div>",
|
||||
templates: function() {
|
||||
|
@ -33,6 +34,7 @@ Metamaps.Views.chatView = (function () {
|
|||
this.$videoToggle = $('<div class="video-toggle"></div>');
|
||||
this.$cursorToggle = $('<div class="cursor-toggle"></div>');
|
||||
this.$participants = $('<div class="participants"></div>');
|
||||
this.$conversationInProgress = $('<div class="conversation-live">LIVE <span class="call-action leave" onclick="Metamaps.Realtime.leaveCall();">LEAVE</span><span class="call-action join" onclick="Metamaps.Realtime.joinCall();">JOIN</span></div>');
|
||||
this.$chatHeader = $('<div class="chat-header">CHAT</div>');
|
||||
this.$soundToggle = $('<div class="sound-toggle active"></div>');
|
||||
this.$messages = $('<div class="chat-messages"></div>');
|
||||
|
@ -46,6 +48,8 @@ Metamaps.Views.chatView = (function () {
|
|||
|
||||
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);
|
||||
|
@ -162,9 +166,13 @@ Metamaps.Views.chatView = (function () {
|
|||
},
|
||||
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;
|
||||
|
@ -194,6 +202,8 @@ Metamaps.Views.chatView = (function () {
|
|||
|
||||
this.isOpen = false;
|
||||
this.alertSound = false; // 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();
|
||||
|
||||
|
@ -208,6 +218,18 @@ Metamaps.Views.chatView = (function () {
|
|||
});
|
||||
};
|
||||
|
||||
chatView.prototype.conversationInProgress = function (participating) {
|
||||
this.$conversationInProgress.show();
|
||||
this.$participants.addClass('is-live');
|
||||
if (participating) this.$conversationInProgress.addClass('is-participating');
|
||||
}
|
||||
|
||||
chatView.prototype.conversationEnded = function () {
|
||||
this.$conversationInProgress.hide();
|
||||
this.$participants.removeClass('is-live');
|
||||
this.$conversationInProgress.removeClass('is-participating');
|
||||
}
|
||||
|
||||
chatView.prototype.addParticipant = function (participant) {
|
||||
this.participants.add(participant);
|
||||
}
|
||||
|
@ -276,7 +298,11 @@ Metamaps.Views.chatView = (function () {
|
|||
openTray: 'ChatView:openTray',
|
||||
closeTray: 'ChatView:closeTray',
|
||||
inputFocus: 'ChatView:inputFocus',
|
||||
inputBlur: 'ChatView:inputBlur'
|
||||
inputBlur: 'ChatView:inputBlur',
|
||||
cursorsOff: 'ChatView:cursorsOff',
|
||||
cursorsOn: 'ChatView:cursorsOn',
|
||||
videosOff: 'ChatView:videosOff',
|
||||
videosOn: 'ChatView:videosOn'
|
||||
};
|
||||
|
||||
return chatView;
|
||||
|
|
|
@ -31,11 +31,24 @@ Metamaps.Views.room = (function () {
|
|||
room.prototype.join = function(cb) {
|
||||
this.isActiveRoom = true;
|
||||
this.webrtc.joinRoom(this.room, cb);
|
||||
this.chat.conversationInProgress(true); // true indicates participation
|
||||
}
|
||||
|
||||
room.prototype.conversationInProgress = function() {
|
||||
this.chat.conversationInProgress(false); // false indicates not participating
|
||||
}
|
||||
|
||||
room.prototype.conversationEnding = function() {
|
||||
this.chat.conversationEnded();
|
||||
}
|
||||
|
||||
room.prototype.leaveVideoOnly = function() {
|
||||
for (var id in this.videos) {
|
||||
this.removeVideo(id);
|
||||
}
|
||||
this.isActiveRoom = false;
|
||||
this.webrtc.leaveRoom();
|
||||
this.chat.conversationEnded();
|
||||
}
|
||||
|
||||
room.prototype.leave = function() {
|
||||
|
@ -44,6 +57,7 @@ Metamaps.Views.room = (function () {
|
|||
}
|
||||
this.isActiveRoom = false;
|
||||
this.webrtc.leaveRoom();
|
||||
this.chat.conversationEnded();
|
||||
this.chat.removeParticipants();
|
||||
this.chat.clearMessages();
|
||||
this.messages.reset();
|
||||
|
@ -109,30 +123,6 @@ Metamaps.Views.room = (function () {
|
|||
v.$container.show();
|
||||
});
|
||||
|
||||
this.socket.on('addVideo', function (data) {
|
||||
var existingPeer = self.webrtc.webrtc.peers.find(function(p) { return p.id === data.id; });
|
||||
if (!existingPeer) {
|
||||
var peer = self.webrtc.webrtc.createPeer({
|
||||
id: data.id,
|
||||
type: 'video',
|
||||
enableDataChannels: true,
|
||||
receiveMedia: {
|
||||
mandatory: {
|
||||
OfferToReceiveAudio: true,
|
||||
OfferToReceiveVideo: true
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log(data);
|
||||
peer.avatar = data.avatar;
|
||||
peer.username = data.username;
|
||||
self.webrtc.emit('createdPeer', peer);
|
||||
peer.start();
|
||||
|
||||
// the rest will happen automatically through the 'peerStreamAdded' event and associated event handlers
|
||||
}
|
||||
});
|
||||
|
||||
var sendChatMessage = function (event, data) {
|
||||
self.sendChatMessage(data);
|
||||
};
|
||||
|
@ -151,7 +141,7 @@ Metamaps.Views.room = (function () {
|
|||
var
|
||||
v = new VideoView(video, null, id, false, { DOUBLE_CLICK_TOLERANCE: 200, avatar: peer.avatar, username: peer.username });
|
||||
|
||||
if (this._videoAdded) this._videoAdded(v);
|
||||
if (this._videoAdded) this._videoAdded(v, peer.nick);
|
||||
this.videos[peer.id] = v;
|
||||
}
|
||||
|
||||
|
|
|
@ -739,3 +739,11 @@ box-shadow: 0px 1px 1.5px rgba(0,0,0,0.12), 0 1px 1px rgba(0,0,0,0.24);
|
|||
body a#barometer_tab:hover {
|
||||
background-position: 0 -110px;
|
||||
}
|
||||
|
||||
.hideVideos .collaborator-video {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.hideCursors .collabCompass {
|
||||
display: none !important;
|
||||
}
|
||||
|
|
|
@ -172,6 +172,27 @@
|
|||
color: #f5f5f5;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.chat-box .participants .conversation-live {
|
||||
display: none;
|
||||
padding: 5px 10px 5px 10px;
|
||||
background: #c04f4f;
|
||||
margin: 5px 10px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.chat-box .participants .conversation-live .call-action {
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
color: #EBFF00;
|
||||
}
|
||||
.chat-box .participants .conversation-live .leave {
|
||||
display: none;
|
||||
}
|
||||
.chat-box .participants .conversation-live.is-participating .leave {
|
||||
display: block;
|
||||
}
|
||||
.chat-box .participants .conversation-live.is-participating .join {
|
||||
display: none;
|
||||
}
|
||||
.chat-box .participants .participant {
|
||||
width: 89%;
|
||||
padding: 8px 8px 2px 8px;
|
||||
|
@ -188,14 +209,13 @@
|
|||
padding-top: 2px;
|
||||
}
|
||||
.chat-box .participants .participant .chat-participant-image img {
|
||||
border: 2px solid #424242;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.chat-box .participants .participant .chat-participant-name {
|
||||
width: 73%;
|
||||
width: 53%;
|
||||
float: left;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
|
@ -203,6 +223,12 @@
|
|||
padding: 2px 8px 0;
|
||||
text-align: left;
|
||||
}
|
||||
.chat-box .participants.is-live .participant .chat-participant-invite {
|
||||
display: none;
|
||||
}
|
||||
.chat-box .participants .participant .chat-participant-invite {
|
||||
float: right;
|
||||
}
|
||||
.chat-box .chat-header {
|
||||
width: 100%;
|
||||
padding: 16px 8px 16px 16px;
|
||||
|
|
|
@ -34,10 +34,14 @@ function start() {
|
|||
// send response back to the inviter
|
||||
socket.on('callAccepted', function (data) {
|
||||
socket.broadcast.emit(data.inviter + '-' + data.mapid + '-callAccepted', data.invited);
|
||||
socket.broadcast.emit('maps-' + data.mapid + '-callStarting');
|
||||
});
|
||||
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');
|
||||
});
|
||||
|
||||
// this will ping everyone on a map that there's a person just joined the map
|
||||
socket.on('newMapperNotify', function (data) {
|
||||
|
|
Loading…
Reference in a new issue