From 2e8670a8abc0053155ed761d2f2b2dd88b6233a0 Mon Sep 17 00:00:00 2001 From: farhatahmad <35435341+farhatahmad@users.noreply.github.com> Date: Wed, 6 Feb 2019 11:08:19 -0500 Subject: [PATCH] GRN-11: Ability to configure room specific settings (#348) * Added the ability to set room settings on create or update * Added room settings alerts and made fixes to other alerts * Small bug fixes related to rubocop and the create room modal * Update test case and fixed issue with small edge case * Update room.js --- app/assets/javascripts/room.js | 68 +++++++++++++++++++ app/assets/stylesheets/rooms.scss | 5 ++ app/controllers/password_resets_controller.rb | 13 ++-- app/controllers/rooms_controller.rb | 64 +++++++++++++++-- app/controllers/sessions_controller.rb | 6 +- app/controllers/users_controller.rb | 11 +-- app/models/room.rb | 2 + app/views/main/index.html.erb | 8 +-- app/views/password_resets/edit.html.erb | 10 +-- app/views/password_resets/new.html.erb | 8 +-- app/views/rooms/show.html.erb | 8 +-- app/views/shared/_flash_messages.html.erb | 12 +++- app/views/shared/_header.html.erb | 2 +- app/views/shared/_success_banner.html.erb | 18 +++++ .../shared/components/_room_block.html.erb | 10 ++- .../shared/modals/_create_room_modal.html.erb | 43 +++++++++--- config/locales/en.yml | 14 +++- config/routes.rb | 1 + ...0190122210632_add_room_settings_to_room.rb | 7 ++ db/schema.rb | 9 +-- spec/controllers/rooms_controller_spec.rb | 39 ++++++++++- 21 files changed, 284 insertions(+), 74 deletions(-) create mode 100644 app/views/shared/_success_banner.html.erb create mode 100644 db/migrate/20190122210632_add_room_settings_to_room.rb diff --git a/app/assets/javascripts/room.js b/app/assets/javascripts/room.js index ca16cf68..4624588d 100644 --- a/app/assets/javascripts/room.js +++ b/app/assets/javascripts/room.js @@ -51,4 +51,72 @@ $(document).on('turbolinks:load', function(){ }); }); } + + // Display and update all fields related to creating a room in the createRoomModal + $("#create-room").click(function(){ + $("#create-room-name").val("") + $("#createRoomModal form").attr("action", "/") + updateDropdown($(".dropdown-item[value='default']")) + $("#room_mute_on_join").prop("checked", false) + $("#auto-join-label").addClass("mt-3 mb-6") + + //show all elements & their children with a create-only class + $(".create-only").each(function() { + $(this).show() + if($(this).children().length > 0) $(this).children().show() + }) + + //hide all elements & their children with a update-only class + $(".update-only").each(function() { + $(this).hide() + if($(this).children().length > 0) $(this).children().hide() + }) + }) + + // Display and update all fields related to creating a room in the createRoomModal + $(".update-room").click(function(){ + var room_block_uid = $(this).closest("#room-block").data("room-uid") + $("#create-room-name").val($(this).closest("tbody").find("#room-name h4").text()) + $("#createRoomModal form").attr("action", "/" + room_block_uid + "/update_settings") + $("#auto-join-label").removeClass("mt-3 mb-6") + + //show all elements & their children with a update-only class + $(".update-only").each(function() { + $(this).show() + if($(this).children().length > 0) $(this).children().show() + }) + + //hide all elements & their children with a create-only class + $(".create-only").each(function() { + $(this).hide() + if($(this).children().length > 0) $(this).children().hide() + }) + + updateCurrentSettings($(this).closest("#room-block").data("room-settings")) + }) + + //Update the createRoomModal to show the correct current settings + function updateCurrentSettings(settings){ + //set checkbox + if(settings.muteOnStart){ + $("#room_mute_on_join").prop("checked", true) + } else { //default option + $("#room_mute_on_join").prop("checked", false) + } + + //set dropdown value + if (settings.joinViaHtml5) { + updateDropdown($(".dropdown-item[value='html5']")) + } else if (settings.joinViaHtml5 == false) { + updateDropdown($(".dropdown-item[value='flash']")) + } else { //default option + updateDropdown($(".dropdown-item[value='default']")) + } + } }); + +// Updates the dropdown element to show the clicked/correct text +function updateDropdown(element) { + $("#dropdown-trigger").text(element.text()) + $("#room_client").val(element.val()) +} diff --git a/app/assets/stylesheets/rooms.scss b/app/assets/stylesheets/rooms.scss index 09fd5cde..3b90cd1a 100644 --- a/app/assets/stylesheets/rooms.scss +++ b/app/assets/stylesheets/rooms.scss @@ -51,3 +51,8 @@ .edit_hover_class:hover a { visibility: visible; } + +#room-settings-dropdown-label { + vertical-align: middle; + padding-top: 12px; +} diff --git a/app/controllers/password_resets_controller.rb b/app/controllers/password_resets_controller.rb index d315e3f5..df7e700f 100644 --- a/app/controllers/password_resets_controller.rb +++ b/app/controllers/password_resets_controller.rb @@ -32,11 +32,11 @@ class PasswordResetsController < ApplicationController @user.send_password_reset_email(reset_link) redirect_to root_url, notice: I18n.t("email_sent") else - redirect_to new_password_reset_path, notice: I18n.t("no_user_email_exists") + redirect_to new_password_reset_path, alert: I18n.t("no_user_email_exists") end rescue => e logger.error "Error in email delivery: #{e}" - redirect_to root_path, notice: I18n.t(params[:message], default: I18n.t("delivery_error")) + redirect_to root_path, alert: I18n.t(params[:message], default: I18n.t("delivery_error")) end def edit @@ -44,13 +44,14 @@ class PasswordResetsController < ApplicationController def update if params[:user][:password].empty? - flash.now[:notice] = I18n.t("password_empty_notice") + flash.now[:alert] = I18n.t("password_empty_notice") render 'edit' elsif params[:user][:password] != params[:user][:password_confirmation] - flash.now[:notice] = I18n.t("password_different_notice") + flash.now[:alert] = I18n.t("password_different_notice") render 'edit' elsif current_user.update_attributes(user_params) - redirect_to root_path, notice: I18n.t("password_reset_success") + flash[:success] = I18n.t("password_reset_success") + redirect_to root_path else render 'edit' end @@ -73,7 +74,7 @@ class PasswordResetsController < ApplicationController # Checks expiration of reset token. def check_expiration if current_user.password_reset_expired? - redirect_to new_password_reset_url, notice: I18n.t("expired_reset_token") + redirect_to new_password_reset_url, alert: I18n.t("expired_reset_token") end end diff --git a/app/controllers/rooms_controller.rb b/app/controllers/rooms_controller.rb index bd4fd8a1..405634ea 100644 --- a/app/controllers/rooms_controller.rb +++ b/app/controllers/rooms_controller.rb @@ -27,17 +27,22 @@ class RoomsController < ApplicationController # POST / def create - redirect_to root_path unless current_user + redirect_to(root_path) && return unless current_user @room = Room.new(name: room_params[:name]) @room.owner = current_user + @room.room_settings = create_room_settings_string(room_params[:mute_on_join], room_params[:client]) if @room.save if room_params[:auto_join] == "1" start else + flash[:success] = I18n.t("room.create_room_success") redirect_to @room end + else + flash[:alert] = I18n.t("room.create_room_error") + redirect_to current_user.main_room end end @@ -60,9 +65,9 @@ class RoomsController < ApplicationController def update if params[:setting] == "rename_block" @room = Room.find_by!(uid: params[:room_block_uid]) - update_room_attributes + update_room_attributes("name") elsif params[:setting] == "rename_header" - update_room_attributes + update_room_attributes("name") elsif params[:setting] == "rename_recording" @room.update_recording(params[:record_id], "meta_name" => params[:record_name]) end @@ -86,6 +91,10 @@ class RoomsController < ApplicationController # Determine if the user needs to join as a moderator. opts[:user_is_moderator] = @room.owned_by?(current_user) + # Check if the user has specified which client to use + room_settings = JSON.parse(@room[:room_settings]) + opts[:join_via_html5] = room_settings["joinViaHtml5"] if room_settings["joinViaHtml5"] + if current_user redirect_to @room.join_path(current_user.name, opts, current_user.uid) else @@ -112,10 +121,15 @@ class RoomsController < ApplicationController opts = default_meeting_options opts[:user_is_moderator] = true + # Include the user's choices for the room settings + room_settings = JSON.parse(@room[:room_settings]) + opts[:mute_on_start] = room_settings["muteOnStart"] if room_settings["muteOnStart"] + opts[:join_via_html5] = room_settings["joinViaHtml5"] if room_settings["joinViaHtml5"] + begin redirect_to @room.join_path(current_user.name, opts, current_user.uid) rescue BigBlueButton::BigBlueButtonException => exc - redirect_to room_path, notice: I18n.t(exc.key.to_s.underscore, default: I18n.t("bigbluebutton_exception")) + redirect_to room_path, alert: I18n.t(exc.key.to_s.underscore, default: I18n.t("bigbluebutton_exception")) end # Notify users that the room has started. @@ -123,6 +137,24 @@ class RoomsController < ApplicationController NotifyUserWaitingJob.set(wait: 5.seconds).perform_later(@room) end + # POST /:room_uid/update_settings + def update_settings + begin + raise "Room name can't be blank" if room_params[:name].empty? + + @room = Room.find_by!(uid: params[:room_uid]) + # Update the rooms settings + update_room_attributes("settings") + # Update the rooms name if it has been changed + update_room_attributes("name") if @room.name != room_params[:name] + rescue StandardError + flash[:alert] = I18n.t("room.update_settings_error") + else + flash[:success] = I18n.t("room.update_settings_success") + end + redirect_to room_path + end + # GET /:room_uid/logout def logout # Redirect the correct page. @@ -149,14 +181,32 @@ class RoomsController < ApplicationController private - def update_room_attributes + def update_room_attributes(update_type) if @room.owned_by?(current_user) && @room != current_user.main_room - @room.update_attributes(name: params[:room_name]) + if update_type.eql? "name" + @room.update_attributes(name: params[:room_name] || room_params[:name]) + elsif update_type.eql? "settings" + room_settings_string = create_room_settings_string(room_params[:mute_on_join], room_params[:client]) + @room.update_attributes(room_settings: room_settings_string) + end end end + def create_room_settings_string(mute_res, client_res) + room_settings = {} + room_settings["muteOnStart"] = mute_res == "1" ? true : false + + if client_res.eql? "html5" + room_settings["joinViaHtml5"] = true + elsif client_res.eql? "flash" + room_settings["joinViaHtml5"] = false + end + + room_settings.to_json + end + def room_params - params.require(:room).permit(:name, :auto_join) + params.require(:room).permit(:name, :auto_join, :mute_on_join, :client) end # Find the room from the uid. diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 8a752985..690bbc1d 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -29,11 +29,11 @@ class SessionsController < ApplicationController def create user = User.find_by(email: session_params[:email]) if user && !user.greenlight_account? - redirect_to root_path, notice: I18n.t("invalid_login_method") + redirect_to root_path, alert: I18n.t("invalid_login_method") elsif user.try(:authenticate, session_params[:password]) login(user) else - redirect_to root_path, notice: I18n.t("invalid_credentials") + redirect_to root_path, alert: I18n.t("invalid_credentials") end end @@ -48,7 +48,7 @@ class SessionsController < ApplicationController # POST /auth/failure def omniauth_fail - redirect_to root_path, notice: I18n.t(params[:message], default: I18n.t("omniauth_error")) + redirect_to root_path, alert: I18n.t(params[:message], default: I18n.t("omniauth_error")) end private diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 8b4da1e2..d7c780ad 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -85,7 +85,8 @@ class UsersController < ApplicationController if errors.empty? && @user.save # Notify the user that their account has been updated. - redirect_to edit_user_path(@user), notice: I18n.t("info_update_success") + flash[:success] = I18n.t("info_update_success") + redirect_to edit_user_path(@user) else # Append custom errors. errors.each { |k, v| @user.errors.add(k, v) } @@ -93,10 +94,12 @@ class UsersController < ApplicationController end elsif user_params[:email] != @user.email && @user.update_attributes(user_params) @user.update_attributes(email_verified: false) - redirect_to edit_user_path(@user), notice: I18n.t("info_update_success") + flash[:success] = I18n.t("info_update_success") + redirect_to edit_user_path(@user) elsif @user.update_attributes(user_params) update_locale(@user) - redirect_to edit_user_path(@user), notice: I18n.t("info_update_success") + flash[:success] = I18n.t("info_update_success") + redirect_to edit_user_path(@user) else render :edit, params: { settings: params[:settings] } end @@ -178,7 +181,7 @@ class UsersController < ApplicationController private def mailer_delivery_fail - redirect_to root_path, notice: I18n.t(params[:message], default: I18n.t("delivery_error")) + redirect_to root_path, alert: I18n.t(params[:message], default: I18n.t("delivery_error")) end def verification_link(user) diff --git a/app/models/room.rb b/app/models/room.rb index 24e737b8..7d376606 100644 --- a/app/models/room.rb +++ b/app/models/room.rb @@ -52,6 +52,7 @@ class Room < ApplicationRecord moderatorPW: random_password(12), attendeePW: random_password(12), moderatorOnlyMessage: options[:moderator_message], + muteOnStart: options[:mute_on_start] || false, "meta_#{META_LISTED}": false, } @@ -93,6 +94,7 @@ class Room < ApplicationRecord # Generate the join URL. join_opts = {} join_opts[:userID] = uid if uid + join_opts[:joinViaHtml5] = options[:join_via_html5] if options[:join_via_html5] bbb.join_meeting_url(bbb_id, name, password, join_opts) end diff --git a/app/views/main/index.html.erb b/app/views/main/index.html.erb index a812d4ee..0a74edaa 100755 --- a/app/views/main/index.html.erb +++ b/app/views/main/index.html.erb @@ -13,13 +13,7 @@ # with BigBlueButton; if not, see . %> -<% unless flash.empty? %> - <%= render "shared/error_banner" do %> - <% flash.each do |key, value| %> - <%= content_tag :div, value, class: "flash #{key} d-inline" %> - <% end %> - <% end %> -<% end %> +<%= render 'shared/flash_messages' unless flash.empty? %>
diff --git a/app/views/password_resets/edit.html.erb b/app/views/password_resets/edit.html.erb index 929db9e2..8795b234 100644 --- a/app/views/password_resets/edit.html.erb +++ b/app/views/password_resets/edit.html.erb @@ -13,13 +13,7 @@ # with BigBlueButton; if not, see . %> -<% unless flash.empty? %> - <%= render "shared/error_banner" do %> - <% flash.each do |key, value| %> - <%= content_tag :div, value, class: "flash #{key} d-inline" %> - <% end %> - <% end %> -<% end %> +<%= render 'shared/flash_messages' unless flash.empty? %>
@@ -47,4 +41,4 @@
-
\ No newline at end of file + diff --git a/app/views/password_resets/new.html.erb b/app/views/password_resets/new.html.erb index 6493277a..12b72ed2 100644 --- a/app/views/password_resets/new.html.erb +++ b/app/views/password_resets/new.html.erb @@ -13,13 +13,7 @@ # with BigBlueButton; if not, see . %> -<% unless flash.empty? %> - <%= render "shared/error_banner" do %> - <% flash.each do |key, value| %> - <%= content_tag :div, value, class: "flash #{key} d-inline" %> - <% end %> - <% end %> -<% end %> +<%= render 'shared/flash_messages' unless flash.empty? %>
diff --git a/app/views/rooms/show.html.erb b/app/views/rooms/show.html.erb index c2c5c8d5..c832e67f 100644 --- a/app/views/rooms/show.html.erb +++ b/app/views/rooms/show.html.erb @@ -13,13 +13,7 @@ # with BigBlueButton; if not, see . %> -<% unless flash.empty? %> - <%= render "shared/error_banner" do %> - <% flash.each do |key, value| %> - <%= content_tag :div, value, class: "flash #{key} d-inline" %> - <% end %> - <% end %> -<% end %> +<%= render 'shared/flash_messages' unless flash.empty? %>
diff --git a/app/views/shared/_flash_messages.html.erb b/app/views/shared/_flash_messages.html.erb index 01f9682e..b24b32bf 100644 --- a/app/views/shared/_flash_messages.html.erb +++ b/app/views/shared/_flash_messages.html.erb @@ -13,6 +13,14 @@ # with BigBlueButton; if not, see . %> -<% flash.each do |key, value| %> - <%= content_tag :div, value, class: "flash #{key} d-inline-block text-success" %> +<% flash.each do |key,value| %> + <% if key.eql? "success" %> + <%= render "shared/success_banner" do %> + <%= content_tag :div, value, class: "flash #{key} d-inline" %> + <% end %> + <% elsif key.eql? "alert" %> + <%= render "shared/error_banner" do %> + <%= content_tag :div, value, class: "flash #{key} d-inline" %> + <% end %> + <% end %> <% end %> diff --git a/app/views/shared/_header.html.erb b/app/views/shared/_header.html.erb index 236ef390..12526319 100755 --- a/app/views/shared/_header.html.erb +++ b/app/views/shared/_header.html.erb @@ -22,7 +22,7 @@
<% if current_user %> - +   <%= t("header.create_room") %>