wait for moderator with action cable

This commit is contained in:
Zachary Chai 2016-10-26 17:15:44 -04:00
parent 3aeef0a4cf
commit b701f2e9a6
16 changed files with 167 additions and 33 deletions

View File

@ -14,4 +14,5 @@
//= require jquery-ui //= require jquery-ui
//= require bootstrap-sprockets //= require bootstrap-sprockets
//= require turbolinks //= require turbolinks
//= require_self
//= require_tree . //= require_tree .

View File

@ -0,0 +1,27 @@
(function() {
var initRooms = function() {
App.messages = App.cable.subscriptions.create({
channel: 'ModeratorJoinsChannel',
username: window.location.pathname.split('/').pop()
},
{
received: function(data) {
if (!Meeting.getInstance().getModJoined()) {
Meeting.getInstance().setModJoined(true);
if (Meeting.getInstance().getWaitingForMod()) {
loopJoin();
}
}
}
});
};
$(document).on("turbolinks:load", function() {
if ($("body[data-controller=landing]").get(0)) {
if ($("body[data-action=rooms]").get(0)) {
initRooms();
}
}
});
}).call(this);

View File

@ -1,21 +1,35 @@
(function() { (function() {
var waitForModerator = function(url) {
$.get(url + "/wait", function(html) {
$(".center-panel-wrapper").html(html);
});
if (!Meeting.getInstance().getWaitingForMod()) {
Meeting.getInstance().setWaitingForMod(true);
if (Meeting.getInstance().getModJoined()) {
loopJoin();
}
}
};
var init = function() { var init = function() {
$('.meeting-join').click (function (event) { $('.meeting-join').click (function (event) {
var url = $('.meeting-url').val(); var url = $('.meeting-url').val();
var name = $('.meeting-user-name').val(); var name = $('.meeting-user-name').val();
$.ajax({ Meeting.getInstance().setURL(url);
url : url + "/join?name=" + name, Meeting.getInstance().setName(name);
dataType : "json", var jqxhr = Meeting.getInstance().getjoinMeetingURL();
type : 'GET',
success : function(data) { jqxhr.done(function(data) {
if (data.messageKey === 'wait_for_moderator') {
waitForModerator(url);
} else {
$(location).attr("href", data.response.join_url); $(location).attr("href", data.response.join_url);
},
error : function(xhr, status, error) {
},
complete : function(xhr, status) {
} }
}); });
jqxhr.fail(function(xhr, status, error) {
console.info("meeting join failed");
});
}); });
$('.meeting-url-copy').click (function (e) { $('.meeting-url-copy').click (function (e) {

View File

@ -0,0 +1,55 @@
var meetingInstance = null;
class Meeting {
constructor(url, name) {
this.url = url;
this.name = name;
}
static getInstance() {
if (meetingInstance) {
return meetingInstance;
}
var url = $('.meeting-url').val();
var name = $('.meeting-user-name').val();
meetingInstance = new Meeting(url, name);
return meetingInstance;
}
getjoinMeetingURL() {
return $.get(this.url + "/join?name=" + this.name, function() {
});
};
setURL(url) {
this.url = url;
}
setName(name) {
this.name = name;
}
setModJoined(modJoined) {
this.modJoined = modJoined;
}
getModJoined() {
return this.modJoined;
}
setWaitingForMod(wMod) {
this.waitingForMod = wMod;
}
getWaitingForMod() {
return this.waitingForMod;
}
}
var loopJoin = function() {
var jqxhr = Meeting.getInstance().getjoinMeetingURL();
jqxhr.done(function(data) {
if (data.messageKey === 'wait_for_moderator') {
setTimeout(loopJoin, 5000);
} else {
$(location).attr("href", data.response.join_url);
}
});
jqxhr.fail(function(xhr, status, error) {
console.info("meeting join failed");
});
}

View File

@ -27,7 +27,7 @@ html, body {
border: 0; border: 0;
} }
.content-box { .center-panel {
.center-block { .center-block {
float: none; float: none;
} }

View File

@ -0,0 +1,5 @@
class ModeratorJoinsChannel < ApplicationCable::Channel
def subscribed
stream_from "moderator_#{params[:username]}_join_channel"
end
end

View File

@ -2,9 +2,9 @@ class BbbController < ApplicationController
# GET /:resource/:id/join # GET /:resource/:id/join
def join def join
if ( !params[:id] ) if ( params[:id].blank? )
render_response("missing_parameter", "meeting token was not included", :bad_request) render_response("missing_parameter", "meeting token was not included", :bad_request)
elsif ( !params[:name] ) elsif ( params[:name].blank? )
render_response("missing_parameter", "user name was not included", :bad_request) render_response("missing_parameter", "user name was not included", :bad_request)
else else
user = User.find_by username: params[:id] user = User.find_by username: params[:id]
@ -25,6 +25,12 @@ class BbbController < ApplicationController
options options
) )
if bbb_res[:returncode] && current_user && current_user == user
ActionCable.server.broadcast "moderator_#{user.username}_join_channel",
moderator: "joined"
end
render_response bbb_res[:messageKey], bbb_res[:message], bbb_res[:status], bbb_res[:response] render_response bbb_res[:messageKey], bbb_res[:message], bbb_res[:status], bbb_res[:response]
end end
end end
@ -35,6 +41,6 @@ class BbbController < ApplicationController
@message = message @message = message
@status = status @status = status
@response = response @response = response
render status: @status && return render status: @status
end end
end end

View File

@ -10,6 +10,10 @@ class LandingController < ApplicationController
end end
end end
def wait_for_moderator
render layout: false
end
def admin? def admin?
@user == current_user @user == current_user
end end
@ -20,7 +24,7 @@ class LandingController < ApplicationController
def render_meeting def render_meeting
@meeting_id = params[:id] @meeting_id = params[:id]
params[:action] = 'meetings' params[:action] = 'meetings'
render :action => 'meeting' render :action => 'meetings'
end end
def render_room def render_room
@ -30,7 +34,7 @@ class LandingController < ApplicationController
redirect_to root_path redirect_to root_path
return return
end end
render :action => 'room' render :action => 'rooms'
end end
end end

View File

@ -29,11 +29,12 @@ module BbbHelper
begin begin
bbb_meeting_info = bbb.get_meeting_info( meeting_id, nil ) bbb_meeting_info = bbb.get_meeting_info( meeting_id, nil )
rescue BigBlueButton::BigBlueButtonException => exc rescue BigBlueButton::BigBlueButtonException => exc
# This means that is not created
if options[:wait_for_moderator] && !options[:user_is_moderator] if options[:wait_for_moderator] && !options[:user_is_moderator]
return wait_moderator_res return wait_moderator_res
end end
# This means that is not created
logger.info "Message for the log file #{exc.key}: #{exc.message}" logger.info "Message for the log file #{exc.key}: #{exc.message}"
# Prepare parameters for create # Prepare parameters for create
@ -79,7 +80,7 @@ module BbbHelper
def wait_moderator_res def wait_moderator_res
{ {
returncode: false, returncode: false,
messageKey: "WaitModerator", messageKey: "wait_for_moderator",
message: "Waiting for moderator", message: "Waiting for moderator",
status: :ok status: :ok
} }
@ -88,7 +89,7 @@ module BbbHelper
def call_invalid_res def call_invalid_res
{ {
returncode: false, returncode: false,
messageKey: "BBBAPICallInvalid", messageKey: "BBB_API_call_invalid",
message: "BBB API call invalid.", message: "BBB API call invalid.",
status: :internal_server_error status: :internal_server_error
} }

View File

@ -1,5 +1,3 @@
<% content_for :title do %> <% content_for :title do %>
<div class="title"> <div class="title">
Hi Everyone Hi Everyone

View File

@ -21,6 +21,7 @@
<%= render 'shared/title', title: page_title %> <%= render 'shared/title', title: page_title %>
<div class="center-panel-wrapper">
<%= render layout: 'shared/center_panel' do %> <%= render layout: 'shared/center_panel' do %>
<div class="center-block col-sm-8"> <div class="center-block col-sm-8">
<% if current_user == @user %> <% if current_user == @user %>
@ -31,6 +32,7 @@
<%= render 'shared/join_form', user: current_user %> <%= render 'shared/join_form', user: current_user %>
</div> </div>
<% end %> <% end %>
</div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,11 @@
<% content_for :title do %>
<div class="title">
Looks like you're the first one here...
</div>
<small>
You will automatically join when the meeting starts
</small>
<% end %>
<%= render layout: 'shared/center_panel' do %>
<% end %>

View File

@ -3,6 +3,7 @@
<head> <head>
<title>Greenlight</title> <title>Greenlight</title>
<%= csrf_meta_tags %> <%= csrf_meta_tags %>
<%= action_cable_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>

View File

@ -1,4 +1,4 @@
<div class="content-box"> <div class="center-panel">
<div class="row"> <div class="row">
<div class="center-block col-sm-4"> <div class="center-block col-sm-4">
<div class="panel panel-default"> <div class="panel panel-default">

View File

@ -31,6 +31,12 @@ Rails.application.configure do
config.action_mailer.perform_caching = false config.action_mailer.perform_caching = false
# action cable socket URI
config.action_cable.url = "ws://localhost/cable"
# allowed action cable origins
Rails.application.config.action_cable.allowed_request_origins = ['http://localhost']
# Print deprecation notices to the Rails logger. # Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log config.active_support.deprecation = :log

View File

@ -1,4 +1,7 @@
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
Rails.application.routes.draw do Rails.application.routes.draw do
mount ActionCable.server => '/cable'
resources :users, only: [:edit, :update] resources :users, only: [:edit, :update]
get '/users/logout', to: 'sessions#destroy', as: :user_logout get '/users/logout', to: 'sessions#destroy', as: :user_logout
@ -7,9 +10,9 @@ Rails.application.routes.draw do
# There are two resources [meetings|rooms] # There are two resources [meetings|rooms]
# meetings offer a landing page for NON authenticated users to create and join session in BigBlueButton # meetings offer a landing page for NON authenticated users to create and join session in BigBlueButton
# rooms offer a customized landing page for authenticated users to create and join session in BigBlueButton # rooms offer a customized landing page for authenticated users to create and join session in BigBlueButton
get '/:resource(/:id)', to: 'landing#index', as: :resource get '/:resource/:id', to: 'landing#index', as: :resource
get '/:resource/:id/join', to: 'bbb#join', as: :bbb_join, defaults: { :format => 'json' } get '/:resource/:id/join', to: 'bbb#join', as: :bbb_join, defaults: { :format => 'json' }
get '/:resource/:id/wait', to: 'landing#wait_for_moderator'
root to: 'landing#index', :resource => "meetings" root to: 'landing#index', :resource => "meetings"
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end end