forked from External/greenlight
Merge pull request #191 from joshua-arts/html5-support
Add support for HTML5 client
This commit is contained in:
commit
3b32a92c36
3
Gemfile
3
Gemfile
|
@ -89,3 +89,6 @@ gem 'yt', '~> 0.28.0'
|
|||
|
||||
# Simple HTTP client.
|
||||
gem 'faraday'
|
||||
|
||||
# For device detection to determine BigBlueButton client.
|
||||
gem 'browser'
|
||||
|
|
|
@ -46,6 +46,7 @@ GEM
|
|||
sass (~> 3.2)
|
||||
bootstrap-social-rails (4.12.0)
|
||||
railties (>= 3.1)
|
||||
browser (2.5.1)
|
||||
builder (3.2.3)
|
||||
byebug (9.0.6)
|
||||
climate_control (0.2.0)
|
||||
|
@ -279,6 +280,7 @@ DEPENDENCIES
|
|||
bigbluebutton-api-ruby
|
||||
bootstrap-sass (= 3.3.0.0)
|
||||
bootstrap-social-rails (~> 4.12)
|
||||
browser
|
||||
byebug
|
||||
coffee-rails (~> 4.2)
|
||||
dotenv-rails
|
||||
|
|
|
@ -117,8 +117,8 @@ var initialPopulate = function(){
|
|||
|
||||
// Populate waiting meetings.
|
||||
Object.keys(data['waiting']).forEach(function(key) {
|
||||
WAITING[name] = {'name': key, 'users': data['waiting'][key]}
|
||||
updateMeetingText(WAITING[name])
|
||||
WAITING[key] = {'name': key, 'users': data['waiting'][key]}
|
||||
updateMeetingText(WAITING[key])
|
||||
})
|
||||
|
||||
// Add the meetings to the active meetings list.
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
body: I18n.user_waiting_body.replace(/%{user}/, data.user).replace(/%{meeting}/, '"'+data.meeting_name+'"')
|
||||
});
|
||||
}
|
||||
} else if(data.action === 'unable_to_join') {
|
||||
showAlert(I18n.unable_to_join_mobile, 6000)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
jqxhr.done(function(data) {
|
||||
if (data.messageKey === 'wait_for_moderator') {
|
||||
waitForModerator(Meeting.getInstance().getURL());
|
||||
} else {
|
||||
} else if (data.messageKey === 'ok') {
|
||||
$(location).attr("href", data.response.join_url);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -69,7 +69,8 @@ var showNotification = function(title, options) {
|
|||
if (Notification.permission === "granted") {
|
||||
var icon = '<%= asset_path("bbb-logo.png") %>';
|
||||
options = $.extend(options, {
|
||||
icon: icon
|
||||
icon: icon,
|
||||
tag: 'UserWaiting'
|
||||
});
|
||||
var notification = new Notification(title, options);
|
||||
notification.onclick = function() {
|
||||
|
|
|
@ -93,7 +93,10 @@ class BbbController < ApplicationController
|
|||
if bbb_res[:returncode] && current_user == user
|
||||
JoinMeetingJob.perform_later(user, params[:id], base_url)
|
||||
WaitingList.empty(options[:room_owner], options[:meeting_name])
|
||||
# user will be waiting for a moderator
|
||||
# the user can't join because they are on mobile and HTML5 is not enabled.
|
||||
elsif bbb_res[:messageKey] == 'unable_to_join'
|
||||
NotifyUserCantJoinJob.perform_later(user.encrypted_id, params[:id], params[:name])
|
||||
# user will be waiting for a moderator
|
||||
else
|
||||
NotifyUserWaitingJob.perform_later(user.encrypted_id, params[:id], params[:name])
|
||||
end
|
||||
|
|
|
@ -19,13 +19,19 @@ class UsersController < ActionController::Base
|
|||
# For updating a users background image.
|
||||
def update
|
||||
|
||||
# Make sure they actually select a file.
|
||||
if params[:user] then
|
||||
if params[:commit] == t('upload')
|
||||
# Make sure they actually select a file.
|
||||
if params[:user] then
|
||||
@user = User.find(params[:id])
|
||||
@user.assign_attributes(background: user_params[:background])
|
||||
flash[:danger] = t('invalid_file') unless @user.save
|
||||
else
|
||||
flash[:danger] = t('no_file')
|
||||
end
|
||||
elsif params[:commit] == t('switch_clients')
|
||||
# Switch the users default client.
|
||||
@user = User.find(params[:id])
|
||||
@user.assign_attributes(background: user_params[:background])
|
||||
flash[:danger] = t('invalid_file') unless @user.save
|
||||
else
|
||||
flash[:danger] = t('no_file')
|
||||
@user.update_attributes(use_html5: !@user.use_html5)
|
||||
end
|
||||
|
||||
# Reload the page to apply changes and show flash messages.
|
||||
|
|
|
@ -16,4 +16,8 @@
|
|||
|
||||
module LandingHelper
|
||||
|
||||
def html5_enabled?
|
||||
Rails.configuration.html5_enabled
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||
#
|
||||
# Copyright (c) 2016 BigBlueButton Inc. and by respective authors (see below).
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class NotifyUserCantJoinJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
def perform(room, meeting, user)
|
||||
payload = { action: 'unable_to_join', user: user, meeting_name: meeting }
|
||||
ActionCable.server.broadcast "#{room}-#{meeting}_meeting_updates_channel", payload
|
||||
end
|
||||
end
|
|
@ -53,71 +53,109 @@ module BbbApi
|
|||
if !bbb
|
||||
return call_invalid_res
|
||||
else
|
||||
meeting_id = bbb_meeting_id(meeting_token)
|
||||
# Verify HTML5 is running.
|
||||
html5_running = Rails.configuration.html5_enabled
|
||||
|
||||
# Determine if the user is on mobile.
|
||||
browser = Browser.new(request.user_agent)
|
||||
mobile = browser.device.tablet?
|
||||
|
||||
# If the user is on mobile and the BigBlueButton server isn't running the HTML5 client,
|
||||
# they can't join or create meetings.
|
||||
if mobile and !html5_running then
|
||||
return unable_to_join_res
|
||||
else
|
||||
meeting_id = bbb_meeting_id(meeting_token)
|
||||
|
||||
# See if the meeting is running
|
||||
begin
|
||||
bbb_meeting_info = bbb.get_meeting_info(meeting_id, nil)
|
||||
rescue BigBlueButton::BigBlueButtonException => exc
|
||||
# This means that is not created
|
||||
# See if the meeting is running
|
||||
begin
|
||||
bbb_meeting_info = bbb.get_meeting_info(meeting_id, nil)
|
||||
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
|
||||
end
|
||||
|
||||
logger.info "Message for the log file #{exc.key}: #{exc.message}"
|
||||
|
||||
# Prepare parameters for create
|
||||
logout_url = options[:meeting_logout_url] || "#{request.base_url}"
|
||||
moderator_password = random_password(12)
|
||||
viewer_password = random_password(12)
|
||||
meeting_options = {
|
||||
record: options[:meeting_recorded].to_s,
|
||||
logoutURL: logout_url,
|
||||
moderatorPW: moderator_password,
|
||||
attendeePW: viewer_password,
|
||||
moderatorOnlyMessage: options[:moderator_message],
|
||||
"meta_#{BbbApi::META_LISTED}": false,
|
||||
"meta_#{BbbApi::META_TOKEN}": meeting_token
|
||||
}
|
||||
|
||||
meeting_options.merge!(
|
||||
{ "meta_#{BbbApi::META_HOOK_URL}": options[:hook_url] }
|
||||
) if options[:hook_url]
|
||||
|
||||
# these parameters are used to filter recordings by room and meeting
|
||||
meeting_options.merge!(
|
||||
{ "meta_room-id": options[:room_owner],
|
||||
"meta_meeting-name": options[:meeting_name]}
|
||||
) if options[:room_owner]
|
||||
|
||||
# Only register webhooks if they are enabled it's not a guest meeting.
|
||||
if Rails.configuration.use_webhooks && params[:resource] == 'rooms'
|
||||
webhook_register(options[:hook_url], meeting_id)
|
||||
end
|
||||
|
||||
# Create the meeting
|
||||
begin
|
||||
bbb.create_meeting(options[:meeting_name], meeting_id, meeting_options)
|
||||
rescue BigBlueButton::BigBlueButtonException => exc
|
||||
logger.info "BBB error on create #{exc.key}: #{exc.message}"
|
||||
end
|
||||
|
||||
# And then get meeting info
|
||||
bbb_meeting_info = bbb.get_meeting_info( meeting_id, nil )
|
||||
end
|
||||
|
||||
if options[:wait_for_moderator] && !options[:user_is_moderator] && bbb_meeting_info[:moderatorCount] <= 0
|
||||
return wait_moderator_res
|
||||
end
|
||||
|
||||
logger.info "Message for the log file #{exc.key}: #{exc.message}"
|
||||
|
||||
# Prepare parameters for create
|
||||
logout_url = options[:meeting_logout_url] || "#{request.base_url}"
|
||||
moderator_password = random_password(12)
|
||||
viewer_password = random_password(12)
|
||||
meeting_options = {
|
||||
record: options[:meeting_recorded].to_s,
|
||||
logoutURL: logout_url,
|
||||
moderatorPW: moderator_password,
|
||||
attendeePW: viewer_password,
|
||||
moderatorOnlyMessage: options[:moderator_message],
|
||||
"meta_#{BbbApi::META_LISTED}": false,
|
||||
"meta_#{BbbApi::META_TOKEN}": meeting_token
|
||||
}
|
||||
meeting_options.merge!(
|
||||
{ "meta_#{BbbApi::META_HOOK_URL}": options[:hook_url] }
|
||||
) if options[:hook_url]
|
||||
|
||||
# these parameters are used to filter recordings by room and meeting
|
||||
meeting_options.merge!(
|
||||
{ "meta_room-id": options[:room_owner],
|
||||
"meta_meeting-name": options[:meeting_name]}
|
||||
) if options[:room_owner]
|
||||
|
||||
# Only register webhooks if they are enabled it's not a guest meeting.
|
||||
if Rails.configuration.use_webhooks && params[:resource] == 'rooms'
|
||||
webhook_register(options[:hook_url], meeting_id)
|
||||
# Get the join url
|
||||
if (options[:user_is_moderator])
|
||||
password = bbb_meeting_info[:moderatorPW]
|
||||
else
|
||||
password = bbb_meeting_info[:attendeePW]
|
||||
end
|
||||
|
||||
# Determine which client to join as.
|
||||
if current_user.nil?
|
||||
use_html5 = Rails.configuration.use_html5_by_default
|
||||
else
|
||||
use_html5 = current_user.use_html5
|
||||
end
|
||||
|
||||
# Restrict client if needed.
|
||||
if mobile && html5_running
|
||||
# Must use HTML5 because they are on mobile.
|
||||
use_html5 = true
|
||||
elsif !mobile && !html5_running
|
||||
# HTML5 is not running, so must use Flash.
|
||||
use_html5 = false
|
||||
end
|
||||
|
||||
# Generate the join URL.
|
||||
if use_html5
|
||||
clientURL = bbb_endpoint.gsub('bigbluebutton/', 'html5client/join')
|
||||
join_url = bbb.join_meeting_url(meeting_id, full_name, password, {clientURL: clientURL})
|
||||
else
|
||||
join_url = bbb.join_meeting_url(meeting_id, full_name, password)
|
||||
end
|
||||
|
||||
# Create the meeting
|
||||
begin
|
||||
bbb.create_meeting(options[:meeting_name], meeting_id, meeting_options)
|
||||
rescue BigBlueButton::BigBlueButtonException => exc
|
||||
logger.info "BBB error on create #{exc.key}: #{exc.message}"
|
||||
end
|
||||
|
||||
# And then get meeting info
|
||||
bbb_meeting_info = bbb.get_meeting_info( meeting_id, nil )
|
||||
return success_join_res(join_url)
|
||||
end
|
||||
|
||||
if options[:wait_for_moderator] && !options[:user_is_moderator] && bbb_meeting_info[:moderatorCount] <= 0
|
||||
return wait_moderator_res
|
||||
end
|
||||
|
||||
# Get the join url
|
||||
if (options[:user_is_moderator])
|
||||
password = bbb_meeting_info[:moderatorPW]
|
||||
else
|
||||
password = bbb_meeting_info[:attendeePW]
|
||||
end
|
||||
join_url = bbb.join_meeting_url(meeting_id, full_name, password )
|
||||
return success_join_res(join_url)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -300,6 +338,15 @@ module BbbApi
|
|||
}
|
||||
}
|
||||
end
|
||||
|
||||
def unable_to_join_res
|
||||
{
|
||||
returncode: false,
|
||||
messageKey: "unable_to_join",
|
||||
message: "Unable to join.",
|
||||
status: :ok
|
||||
}
|
||||
end
|
||||
|
||||
def wait_moderator_res
|
||||
{
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
<% if @user %>
|
||||
<div class="upload-form">
|
||||
<h3><%= t('background_image') %></h3>
|
||||
<p> <%= t('background_image') + ": " + (@user.background_file_name || '') %> </p>
|
||||
<%= form_for @user, :html => { :multipart => true } do |f| %>
|
||||
<div class="form-group">
|
||||
|
@ -31,6 +32,18 @@
|
|||
<%= f.submit t('upload'), class: 'btn btn-info' %>
|
||||
<% end %>
|
||||
</div>
|
||||
<br>
|
||||
<div class="html5-check">
|
||||
<h3><%= t('prefered_client') %></h3>
|
||||
<% if html5_enabled? %>
|
||||
<p><%= t('currently_joining_with', client: @user.use_html5 ? t('client_html5') : t('client_flash')) %></p>
|
||||
<%= form_for @user do |f| %>
|
||||
<%= f.submit t('switch_clients'), class: 'btn btn-info' %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<p><%= t('html5_not_enabled') %></p>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<h3><%= t('preferences_logged') %></h3>
|
||||
<% end %>
|
||||
|
|
|
@ -48,6 +48,7 @@ module Greenlight
|
|||
config.disable_guest_access = ENV['DISABLE_GUEST_ACCESS'] && ENV['DISABLE_GUEST_ACCESS'] == "true"
|
||||
config.enable_youtube_uploading = ENV['ENABLE_YOUTUBE_UPLOADING'] && ENV['ENABLE_YOUTUBE_UPLOADING'] == "true"
|
||||
config.enable_qrcode_generation = ENV['ENABLE_QRCODE_GENERATION'] && ENV['ENABLE_QRCODE_GENERATION'] == "true"
|
||||
config.use_html5_by_default = ENV['USE_HTML5_BY_DEFAULT'] == "true"
|
||||
|
||||
# SMTP and action mailer
|
||||
if config.mail_notifications
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||
#
|
||||
# Copyright (c) 2016 BigBlueButton Inc. and by respective authors (see below).
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Send a request to check if the HTML5 client is enabled on the BigBlueButton server.
|
||||
res = Faraday.get(Rails.configuration.bigbluebutton_endpoint.gsub('bigbluebutton/', 'html5client/check'))
|
||||
Rails.application.config.html5_enabled = res.status == 200
|
|
@ -70,14 +70,18 @@ en-US:
|
|||
recording_unpublished: Recording was unpublished
|
||||
share: Share
|
||||
successful_upload: Recording successfully uploaded to Youtube!
|
||||
unable_to_join_mobile: This BigBlueButton server does not use the HTML5 client, which means you are unable to join on mobile.
|
||||
unpublish_recording: Hide recording
|
||||
unlisted: Unlisted
|
||||
unpublished: No one
|
||||
upload_youtube: Youtube
|
||||
user_waiting_body: "%{user} is waiting to join %{meeting}!"
|
||||
user_waiting_title: A user is waiting
|
||||
client_html5: HTML5
|
||||
client_flash: Flash
|
||||
copied: Copied
|
||||
copy_error: Use Ctrl-c to copy
|
||||
currently_joining_with: Currently prefering the %{client} client.
|
||||
create_your_session: Create your own meeting
|
||||
date_recorded: Date
|
||||
disallowed_characters_msg: Characters not allowed in meeting name $&,
|
||||
|
@ -94,6 +98,7 @@ en-US:
|
|||
hi_all: Hi Everyone
|
||||
home_page: Home page
|
||||
home_title: Welcome to BigBlueButton
|
||||
html5_not_enabled: This server is not HTML5 enabled, so you must use the Flash client.
|
||||
invalid_file: You may only upload an image file (jpg, gif, png).
|
||||
invalid_login: Invalid log in credentials.
|
||||
invite: Invite
|
||||
|
@ -157,6 +162,7 @@ en-US:
|
|||
past_recordings: Past Recordings
|
||||
preferences: Preferences
|
||||
preferences_logged: You must be logged in to edit preferences.
|
||||
prefered_client: Prefered Client
|
||||
presentation: Presentation
|
||||
previous_meetings: (previous meetings)
|
||||
qrcode:
|
||||
|
@ -176,6 +182,7 @@ en-US:
|
|||
start: Start
|
||||
start_join: Start
|
||||
start_meeting: Start meeting
|
||||
switch_clients: Switch Clients
|
||||
test_mailer:
|
||||
test_email:
|
||||
subject: Test Email
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddUseHtml5ToUsers < ActiveRecord::Migration[5.0]
|
||||
def change
|
||||
add_column :users, :use_html5, :boolean, default: false
|
||||
end
|
||||
end
|
13
db/schema.rb
13
db/schema.rb
|
@ -10,22 +10,23 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20170518190442) do
|
||||
ActiveRecord::Schema.define(version: 20170928183010) do
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.string "provider", null: false
|
||||
t.string "uid", null: false
|
||||
t.string "provider", null: false
|
||||
t.string "uid", null: false
|
||||
t.string "name"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "username"
|
||||
t.string "encrypted_id", null: false
|
||||
t.string "encrypted_id", null: false
|
||||
t.string "email"
|
||||
t.string "background_file_name"
|
||||
t.string "background_content_type"
|
||||
t.integer "background_file_size"
|
||||
t.datetime "background_updated_at"
|
||||
t.string "token"
|
||||
t.boolean "use_html5", default: false
|
||||
t.index ["email"], name: "index_users_on_email", unique: true
|
||||
t.index ["encrypted_id"], name: "index_users_on_encrypted_id", unique: true
|
||||
t.index ["provider", "uid"], name: "index_users_on_provider_and_uid", unique: true
|
||||
|
|
11
sample.env
11
sample.env
|
@ -23,6 +23,17 @@ SECRET_KEY_BASE=
|
|||
# BIGBLUEBUTTON_ENDPOINT=
|
||||
# BIGBLUEBUTTON_SECRET=
|
||||
|
||||
# Set default client (optional)
|
||||
#
|
||||
# By default, GreenLight will join users to a BigBlueButton session using the Flash
|
||||
# client. By setting USE_HTML5_BY_DEFAULT to true, you can configure GreenLight to
|
||||
# use the HTML5 client by default. GreenLight will only use the default for
|
||||
# non-authenticated users. Users who have authenticated are able to set their
|
||||
# prefered client under preferences. Also note that if the HTML5 client is not
|
||||
# running on a BigBlueButton server, all clients will be joined using Flash
|
||||
# regardless on any settings.
|
||||
USE_HTML5_BY_DEFAULT=false
|
||||
|
||||
# Twitter Login Provider (optional)
|
||||
#
|
||||
# You will need to register the app at https://apps.twitter.com/
|
||||
|
|
|
@ -49,7 +49,7 @@ def getParticipantsInfo(events_xml)
|
|||
end
|
||||
|
||||
def get_id_from_event(event)
|
||||
(event.xpath('externalUserId').empty?) ? event.xpath('userId').text.split('_')[0] : event.xpath('externalUserId').text
|
||||
(event.xpath('externalUserId').empty?) ? event.xpath('userId').text : event.xpath('externalUserId').text
|
||||
end
|
||||
|
||||
# Gets the join and leave times for each user, as well as total duration of stay.
|
||||
|
|
Loading…
Reference in New Issue