Add mute/pause/kick action for room owners

Fix #24
master
Daniel Berteaud 11 years ago
parent 648a5b01a6
commit 51945c1c51
  1. 21
      public/css/vroom.css
  2. 152
      public/js/vroom.js
  3. 18
      public/vroom.pl
  4. 14
      templates/default/kicked.html.ep

@ -99,6 +99,27 @@
.unauthEl{ .unauthEl{
display: none; display: none;
} }
.ownerActions {
position: absolute;
left: 15px;
top: 0px;
display: none;
}
.actionMute:before{
font-family: 'Glyphicons Halflings';
color: red;
content: "\e036";
}
.actionPause:before{
font-family: 'Glyphicons Halflings';
color: red;
content: "\e106";
}
.actionKick:before{
font-family: 'Glyphicons Halflings';
color: red;
content: "\e020";
}
#chatBox { #chatBox {
max-height:300px; max-height:300px;
resize:none; resize:none;

@ -35,7 +35,12 @@ var locale = {
SCREEN_s: '', SCREEN_s: '',
TO_INVITE_SHARE_THIS_URL: '', TO_INVITE_SHARE_THIS_URL: '',
NO_SOUND_DETECTED: '', NO_SOUND_DETECTED: '',
DISPLAY_NAME_TOO_LONG: '' DISPLAY_NAME_TOO_LONG: '',
s_IS_MUTING_YOU: '',
s_IS_MUTING_s: '',
s_IS_SUSPENDING_YOU: '',
s_IS_SUSPENDING_s: '',
s_IS_KICKING_s: ''
}; };
// Localize the strings we need // Localize the strings we need
@ -162,6 +167,7 @@ function initVroom(room) {
$.notify(locale.ERROR_OCCURED, 'error'); $.notify(locale.ERROR_OCCURED, 'error');
}, },
success: function(data){ success: function(data){
if (peers[id]){
peers[id].role = data.role; peers[id].role = data.role;
if (data.role == 'owner'){ if (data.role == 'owner'){
$("#overlay_" + id).append('<div id="owner_' + id + '" class="owner"></div>'); $("#overlay_" + id).append('<div id="owner_' + id + '" class="owner"></div>');
@ -170,6 +176,7 @@ function initVroom(room) {
$('#owner_' + id).remove(); $('#owner_' + id).remove();
} }
} }
}
}); });
} }
@ -241,6 +248,35 @@ function initVroom(room) {
$('<div></div>').addClass('volumeBar').attr('id', 'volume_' + id).appendTo(div); $('<div></div>').addClass('volumeBar').attr('id', 'volume_' + id).appendTo(div);
$('<div></div>').addClass('displayName').attr('id', 'name_' + id).appendTo(div); $('<div></div>').addClass('displayName').attr('id', 'name_' + id).appendTo(div);
$('<div></div>').attr('id', 'overlay_' + id).appendTo(div); $('<div></div>').attr('id', 'overlay_' + id).appendTo(div);
$('<div></div>').addClass('ownerActions').attr('id', 'ownerActions_' + id).appendTo(div)
.append($('<div></div>',{
class: 'btn-group'
})
.append($('<button></button>', {
class: 'actionMute btn btn-default btn-sm',
id: 'actionMute_' + id,
click: function() { mutePeer(id) },
}))
.append($('<button></button>', {
class: 'actionPause btn btn-default btn-sm',
id: 'actionPause_' + id,
click: function() { pausePeer(id) },
}))
.append($('<button></button>', {
class: 'actionKick btn btn-default btn-sm',
id: 'actionKick_' + id,
click: function() { kickPeer(id) },
})));
$(div).hover(
function(){
if (peers.local.role == 'owner'){
$('#ownerActions_' + id).show(200);
}
},
function(){
$('#ownerActions_' + id).hide(200);
}
);
// Create a new dataChannel // Create a new dataChannel
// will be used for text chat and displayName // will be used for text chat and displayName
var color = chooseColor(); var color = chooseColor();
@ -389,6 +425,104 @@ function initVroom(room) {
saveAs(blob, filename); saveAs(blob, filename);
} }
// Mute a peer
function mutePeer(id){
webrtc.sendToAll('owner_mute', {peer: id});
}
// Puase a peer
function pausePeer(id){
webrtc.sendToAll('owner_pause', {peer: id});
}
// Kick a peer
function kickPeer(id){
webrtc.sendToAll('owner_kick', {peer: id});
// Wait a bit for the peer to leave, but end connection if it's still here
// after 2 seconds
setTimeout(function(){
if (peers[id]){
peers[id].obj.end();
}
}, 2000);
}
// Mute our mic
function muteMic(){
webrtc.mute();
peers.local.micMuted = true;
showVolume($('#localVolume'), -45);
}
// Unmute
function unmuteMic(){
webrtc.unmute();
peers.local.micMuted = false;
}
// Suspend or webcam
function suspendCam(){
webrtc.pauseVideo();
peers.local.videoPaused = true;
}
// Resume webcam
function resumeCam(){
webrtc.resumeVideo();
peers.local.videoPaused = false;
}
// An owner is muting ourself
webrtc.on('owner_mute', function(data){
if (peers[data.id].role != 'owner'){
return;
}
if (data.payload.peer && data.payload.peer == peers.local.id){
// Ignore this if the remote peer isn't the owner of the room
if (!peers.local.micMuted){
muteMic();
$("#muteMicLabel").addClass('btn-danger active');
$('#muteMicButton').prop('checked', true);
$.notify(sprintf(locale.s_IS_MUTING_YOU, peers[data.id].displayName), 'info');
}
}
else{
$.notify(sprintf(locale.s_IS_MUTING_s, peers[data.id].displayName, peers[data.payload.peer].displayName), 'info');
}
});
// An owner is pausing our webcam
webrtc.on('owner_pause', function(data){
if (peers[data.id].role != 'owner'){
return;
}
if (data.payload.peer && data.payload.peer == peers.local.id){
if (!peers.local.paused){
suspendCam();
$("#suspendCamLabel").addClass('btn-danger active');
$('#suspendCamButton').prop('checked', true);
$.notify(sprintf(locale.s_IS_SUSPENDING_YOU, peers[data.id].displayName), 'info');
}
}
else{
$.notify(sprintf(locale.s_IS_SUSPENDING_s, peers[data.id].displayName, peers[data.payload.peer].displayName), 'info');
}
});
// An owner is kicking us from the room
webrtc.on('owner_kick', function(data){
if (peers[data.id].role != 'owner'){
return;
}
if (data.payload.peer && data.payload.peer == peers.local.id){
hangupCall;
window.location.assign(rootUrl + 'kicked/' + roomName);
}
else{
$.notify(sprintf(locale.s_IS_KICKING_s, peers[data.id].displayName, peers[data.payload.peer].displayName), 'info');
// Wait a bit for the peer to leave, but end connection if it's still here
// after 2 seconds
setTimeout(function(){
if (peers[data.id]){
peers[data.id].obj.end();
}
}, 2000);
}
});
// Handle volume changes from our own mic // Handle volume changes from our own mic
webrtc.on('volumeChange', function (volume, treshold) { webrtc.on('volumeChange', function (volume, treshold) {
if (volume > maxVol){ if (volume > maxVol){
@ -558,6 +692,9 @@ function initVroom(room) {
$('#mainVideo').html(''); $('#mainVideo').html('');
mainVid = false; mainVid = false;
} }
if (peer && peers[peer.id]){
delete peers[peer.id];
}
}); });
// Error sending something through dataChannel // Error sending something through dataChannel
@ -709,15 +846,12 @@ function initVroom(room) {
$('#muteMicButton').change(function() { $('#muteMicButton').change(function() {
var action = ($(this).is(":checked")) ? 'mute':'unmute'; var action = ($(this).is(":checked")) ? 'mute':'unmute';
if (action === 'mute'){ if (action === 'mute'){
webrtc.mute(); muteMic();
peers.local.micMuted = true;
showVolume($('#localVolume'), -45);
$("#muteMicLabel").addClass('btn-danger'); $("#muteMicLabel").addClass('btn-danger');
$.notify(locale.MIC_MUTED, 'info'); $.notify(locale.MIC_MUTED, 'info');
} }
else{ else{
webrtc.unmute(); unmuteMic();
peers.local.micMuted = false;
$("#muteMicLabel").removeClass('btn-danger'); $("#muteMicLabel").removeClass('btn-danger');
$.notify(locale.MIC_UNMUTED, 'info'); $.notify(locale.MIC_UNMUTED, 'info');
} }
@ -727,14 +861,12 @@ function initVroom(room) {
$('#suspendCamButton').change(function() { $('#suspendCamButton').change(function() {
var action = ($(this).is(":checked")) ? 'pause':'resume'; var action = ($(this).is(":checked")) ? 'pause':'resume';
if (action === 'pause'){ if (action === 'pause'){
webrtc.pauseVideo(); suspendCam();
peers.local.videoPaused = true;
$("#suspendCamLabel").addClass('btn-danger'); $("#suspendCamLabel").addClass('btn-danger');
$.notify(locale.CAM_SUSPENDED, 'info'); $.notify(locale.CAM_SUSPENDED, 'info');
} }
else{ else{
webrtc.resumeVideo(); resumeCam();
peers.local.videoPaused = false;
$("#suspendCamLabel").removeClass('btn-danger'); $("#suspendCamLabel").removeClass('btn-danger');
$.notify(locale.CAM_RESUMED, 'info'); $.notify(locale.CAM_RESUMED, 'info');
} }

@ -270,7 +270,7 @@ helper valid_room_name => sub {
my ($name) = @_; my ($name) = @_;
my $ret = undef; my $ret = undef;
# A few names are reserved # A few names are reserved
my @reserved = qw(about help feedback goodbye admin create localize action missing dies password); my @reserved = qw(about help feedback goodbye admin create localize action missing dies password kicked);
if ($name =~ m/^[\w\-]{1,49}$/ && !grep { $name eq $_ } @reserved){ if ($name =~ m/^[\w\-]{1,49}$/ && !grep { $name eq $_ } @reserved){
$ret = 1; $ret = 1;
} }
@ -397,6 +397,22 @@ get '/goodby/(:room)' => sub {
$self->logout; $self->logout;
} => 'goodby'; } => 'goodby';
# Route for the kicked page
# Should be merged with the goodby route
get '/kicked/(:room)' => sub {
my $self = shift;
my $room = $self->stash('room');
if (!$self->get_room($room)){
return $self->render('error',
err => 'ERROR_ROOM_s_DOESNT_EXIST',
msg => sprintf ($self->l("ERROR_ROOM_s_DOESNT_EXIST"), $room),
room => $room
);
}
$self->remove_participant($room,$self->session('name'));
$self->logout;
} => 'kicked';
# This handler creates a new room # This handler creates a new room
post '/create' => sub { post '/create' => sub {
my $self = shift; my $self = shift;

@ -0,0 +1,14 @@
% title $self->l('KICKED');
%= include 'header'
%= include 'public_toolbar'
<div class="container-fluid">
<div class="jumbotron alert-danger">
<h2><%=l 'YOU_HAVE_BEEN_KICKED' %></h2>
<p><%=l 'AN_ADMIN_HAS_KICKED_YOU' %></p>
<div class="btn-group">
<a class="btn btn-primary btn-lg" role="button" href="<%= $self->get_url('/') %>"><%=l 'BACK_TO_MAIN_MENU' %></a>
</div>
</div>
</div>
%= include 'js_common'
%= include 'footer'
Loading…
Cancel
Save