diff --git a/public/css/vroom.css b/public/css/vroom.css index 8b2ce7f..43d3e4a 100644 --- a/public/css/vroom.css +++ b/public/css/vroom.css @@ -123,6 +123,10 @@ color: red; content: "\e083"; } +#emailNotificationList { + padding-right: 12px; + padding-left: 12px; +} #chatBox { max-height:300px; resize:none; diff --git a/public/js/vroom.js b/public/js/vroom.js index e5beb36..b88feea 100644 --- a/public/js/vroom.js +++ b/public/js/vroom.js @@ -77,6 +77,31 @@ function inviteUrlPopup(){ return false; } +// Remove the address from the list +function removeNotifiedEmail(email){ + var id = email.replace('@', '_AT_').replace('.', '_DOT_'); + $.ajax({ + data: { + action: 'emailNotification', + type: 'remove', + email: email, + room: roomName + }, + error: function() { + $.notify(locale.ERROR_OCCURED, 'error'); + }, + success: function(data) { + if (data.status == 'success'){ + $.notify(data.msg, 'success'); + $('#emailNotification_' + id).remove(); + } + else{ + $.notify(data.msg, 'error'); + } + } + }); +} + // set the height of the thumbnails so they are always equals function setPanelHeight() { $('.panelIndex').height(Math.max.apply(null, $('.panelIndex').map(function() { return $(this).height(); }))); @@ -155,6 +180,10 @@ function initVroom(room) { if (data.role == 'owner'){ $('.unauthEl').hide(500); $('.ownerEl').show(500); + var notif = JSON.parse(data.notif); + $.each(notif.email, function(index, val){ + addNotifiedEmail(val); + }); } else{ $('.ownerEl').hide(500); @@ -515,6 +544,13 @@ function initVroom(room) { peers.local.videoPaused = false; } + // Add a new email address in the list of the ones notified when someone joins + function addNotifiedEmail(email){ + var id = email.replace('@', '_AT_').replace('.', '_DOT_'); + $('
  • ').html(email + ' ').attr('id', 'emailNotification_' + id) + .appendTo('#emailNotificationList'); + } + // An owner is muting/unmuting ourself webrtc.on('owner_toggle_mute', function(data){ if (peers[data.id].role != 'owner'){ @@ -1108,6 +1144,43 @@ function initVroom(room) { }); }); + // Add an email to be notified when someone joins + // First, enable the add button when you start typing + // TODO: should be enabled only when the input looks like an email address + $('#newEmailNotification').on('input', function() { + if ($('#newEmailNotification').val() == ''){ + $('#newEmailNotificationButton').addClass('disabled'); + } + else{ + $('#newEmailNotificationButton').removeClass('disabled'); + } + }); + // Then send this new address to the frontend + $('#newEmailNotificationForm').submit(function(event){ + event.preventDefault(); + $.ajax({ + data: { + action: 'emailNotification', + type: 'add', + email: $('#newEmailNotification').val(), + room: roomName + }, + error: function() { + $.notify(locale.ERROR_OCCURED, 'error'); + }, + success: function(data) { + if (data.status == 'success'){ + $.notify(data.msg, 'success'); + addNotifiedEmail($('#newEmailNotification').val()); + $('#newEmailNotification').val(''); + } + else{ + $.notify(data.msg, 'error'); + } + } + }); + }); + // Choose another color. Useful if two peers have the same $('#changeColorButton').click(function(){ peers.local.color = chooseColor(); diff --git a/public/vroom.pl b/public/vroom.pl index 5b257a0..c45e2cd 100755 --- a/public/vroom.pl +++ b/public/vroom.pl @@ -240,12 +240,14 @@ helper delete_rooms => sub { eval { my $timeout = time()-$config->{inactivityTimeout}; $self->db->do("DELETE FROM participants WHERE id IN (SELECT id FROM rooms WHERE activity_timestamp < $timeout AND persistent='0');"); + $self->db->do("DELETE FROM notifications WHERE id IN (SELECT id FROM rooms WHERE activity_timestamp < $timeout AND persistent='0');"); $self->db->do("DELETE FROM rooms WHERE activity_timestamp < $timeout AND persistent='0';"); } || return undef; if ($config->{persistentInactivityTimeout} && $config->{persistentInactivityTimeout} > 0){ eval { my $timeout = time()-$config->{persistentInactivityTimeout}; $self->db->do("DELETE FROM participants WHERE id IN (SELECT id FROM rooms WHERE activity_timestamp < $timeout AND persistent='1');"); + $self->db->do("DELETE FROM notifications WHERE id IN (SELECT id FROM rooms WHERE activity_timestamp < $timeout AND persistent='1');"); $self->db->do("DELETE FROM rooms WHERE activity_timestamp < $timeout AND persistent='1';"); } || return undef; } @@ -346,6 +348,42 @@ helper set_owner_pass => sub { } }; +# Add an email address to the list of notifications +helper add_notification => sub { + my $self = shift; + my ($room,$email) = @_; + my $data = $self->get_room($room); + return undef unless ($data); + my $sth = eval { $self->db->prepare("INSERT IGNORE INTO notifications (id,email) VALUES (?,?)") } || return undef; + $sth->execute($data->{id},$email) || return undef; + return 1; +}; + +# Return the list of email addresses +helper get_notification => sub { + my $self = shift; + my ($room) = @_; + $room = $self->get_room($room) || return undef; + my $sth = eval { $self->db->prepare("SELECT email FROM notifications WHERE id=?;") } || return undef; + $sth->execute($room->{id}) || return undef; + my @res; + while(my @row = $sth->fetchrow_array){ + push @res, $row[0]; + } + return @res; +}; + +# Remove an email from notification list +helper remove_notification => sub { + my $self = shift; + my ($room,$email) = @_; + my $data = $self->get_room($room); + return undef unless ($data); + my $sth = eval { $self->db->prepare("DELETE FROM notifications where id=? and email=?") } || return undef; + $sth->execute($data->{id},$email) || return undef; + return 1; +}; + # Route / to the index page any '/' => 'index'; @@ -731,15 +769,22 @@ post '/action' => sub { elsif ($action eq 'getRoomInfo'){ my $id = $self->param('id'); my $res = 'error'; + my %emailNotif; if ($self->session($room) && $self->session($room)->{role}){ $res = ($self->set_peer_role($room,$self->session('name'),$id, $self->session($room)->{role})) ? 'success':$res; } + if ($self->session($room)->{role} eq 'owner'){ + my $i = 0; + my @email = $self->get_notification($room); + %emailNotif = map { $i => $email[$i++] } @email; + } return $self->render( json => { role => $self->session($room)->{role}, owner_auth => ($data->{owner_password}) ? 'yes' : 'no', join_auth => ($data->{join_password}) ? 'yes' : 'no', - locked => ($data->{locked}) ? 'yes' : 'no' , + locked => ($data->{locked}) ? 'yes' : 'no', + notif => Mojo::JSON->new->encode({email => { %emailNotif }}), status => $res }, ); @@ -755,6 +800,33 @@ post '/action' => sub { } ); } + # Add a new email for notifications when someone joins + elsif ($action eq 'emailNotification'){ + my $email = $self->param('email'); + my $type = $self->param('type'); + my $status = 'error'; + my $msg = 'ERROR_OCCURED'; + if ($self->session($room)->{role} ne 'owner'){ + $msg = 'NOT_ALLOWED'; + } + elsif ($email !~ m/^\S+@\S+\.\S+$/){ + $msg = 'ERROR_MAIL_INVALID'; + } + elsif ($type eq 'add' && $self->add_notification($room,$email)){ + $status = 'success'; + $msg = 's_WILL_BE_NOTIFIED'; + } + elsif ($type eq 'remove' && $self->remove_notification($room,$email)){ + $status = 'success'; + $msg = 's_WONT_BE_NOTIFIED_ANYMORE'; + } + return $self->render( + json => { + msg => $self->l($msg), + status => $status + } + ); + } }; # use the templates defined in the config diff --git a/templates/default/join.html.ep b/templates/default/join.html.ep index 2232fad..9ac4359 100644 --- a/templates/default/join.html.ep +++ b/templates/default/join.html.ep @@ -149,6 +149,26 @@ +
  • +
  • +
  • +
    +

    <%=l 'NOTIFICATION_ON_JOIN' %>

    +
    + + +