diff --git a/app/assets/images/ME_PRO_black.png b/app/assets/images/ME_PRO_black.png new file mode 100644 index 0000000..2fc7bd6 Binary files /dev/null and b/app/assets/images/ME_PRO_black.png differ diff --git a/app/assets/images/live_icon.png b/app/assets/images/live_icon.png new file mode 100644 index 0000000..26a6d22 Binary files /dev/null and b/app/assets/images/live_icon.png differ diff --git a/app/assets/javascripts/channels/broadcasts.coffee.erb b/app/assets/javascripts/channels/broadcasts.coffee.erb index 9765bc2..fddc672 100644 --- a/app/assets/javascripts/channels/broadcasts.coffee.erb +++ b/app/assets/javascripts/channels/broadcasts.coffee.erb @@ -24,7 +24,7 @@ $(document).on "turbolinks:load", -> stream_selected = $("#broadcast_video").data('videoType') == 'stream'; if data.streamer_status == 'recording' && data.status == 'active' && stream_selected $("#broadcast_video").html data.video_content - $("#live_take").html data.live_take_content + $("#recording_status").html data.recording_status_content new (Clappr.Player)( <%= "baseUrl: 'http://cdn.clappr.io/latest'," if Rails.env.test? %> @@ -37,7 +37,7 @@ $(document).on "turbolinks:load", -> hlsMinimumDvrSize: 1) if data.streamer_status == "idle" && data.status == "idle" $("#broadcast_video").html data.video_content - $("#live_take").html data.live_take_content + $("#recording_status").html data.recording_status_content showBroadcastRecordings: (data) -> $(".flash-message").html data.flash_content diff --git a/app/assets/javascripts/stream_player.js.erb b/app/assets/javascripts/stream_player.js.erb index af1aee9..b525d33 100644 --- a/app/assets/javascripts/stream_player.js.erb +++ b/app/assets/javascripts/stream_player.js.erb @@ -1,4 +1,7 @@ $(document).on("click", "[data-behavior=play_recording]", function() { + clearPlayingHighlight(); + $(this).parent().parent().addClass('playing-highlight'); + $("#broadcast_video").data('videoType', 'recording'); var playback_url = $(this).attr("data-playback-url") @@ -14,4 +17,11 @@ $(document).on("click", "[data-behavior=play_recording]", function() { }); }); -$(document).on("click", "[data-behavior=play_stream]", function() { $("#broadcast_video").data('videoType', 'stream'); }); \ No newline at end of file +$(document).on("click", "[data-behavior=play_stream]", function() { +// clearPlayingHighlight(); + $("#broadcast_video").data('videoType', 'stream'); +}); + +function clearPlayingHighlight() { + $(".playing-highlight").removeClass("playing-highlight"); +} \ No newline at end of file diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 23289e9..5dc9303 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -467,4 +467,31 @@ trix-toolbar { .trix-button--icon-underline::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3Cpath d='M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z'/%3E%3C/svg%3E"); } -} \ No newline at end of file +} + +// Play button SVG +.play-btn { + width: 60%; + height: auto; +} + +.play-btn-svg{ + transition: 0.3s; + stroke:#fedfc2; + opacity: 0; +} + +.play-btn:hover .play-btn-svg { + fill-opacity: 0; + opacity: 1; +} + +// Play button in video thumbnail preview +.play-thumbnail { position: relative; } +.play-thumbnail img { display: block; } +.play-thumbnail .play-btn { position: absolute; bottom:5px; left:10px; } + +// Active recording highlight +.playing-highlight { + background-color: scale-color($primary, $lightness: 80%); +} diff --git a/app/channels/broadcasts_channel.rb b/app/channels/broadcasts_channel.rb index 5109d93..918dfe3 100644 --- a/app/channels/broadcasts_channel.rb +++ b/app/channels/broadcasts_channel.rb @@ -11,7 +11,7 @@ class BroadcastsChannel < ApplicationCable::Channel def self.broadcast_stream_updates(broadcast) status_content = ApplicationController.render partial: "broadcasts/broadcast_status", locals: { broadcast: broadcast } video_content = ApplicationController.render partial: "broadcasts/video", locals: { broadcast: broadcast } - live_take = ApplicationController.render partial: "broadcasts/live_take", locals: { broadcast: broadcast } + recording_status_content = ApplicationController.render partial: "broadcasts/recording_status", locals: { broadcast: broadcast } broadcast_to broadcast, { event: :broadcast_stream_update, @@ -19,7 +19,7 @@ class BroadcastsChannel < ApplicationCable::Channel playback_url: broadcast.stream_playback_url, full_live_stream_playback_url: broadcast.full_live_stream_playback_url, video_content: video_content, - live_take_content: live_take, + recording_status_content: recording_status_content, status_content: status_content, streamer_status: broadcast.streamer_status } diff --git a/app/controllers/account_sessions_controller.rb b/app/controllers/account_sessions_controller.rb index dc9b4ca..3e83657 100644 --- a/app/controllers/account_sessions_controller.rb +++ b/app/controllers/account_sessions_controller.rb @@ -1,4 +1,5 @@ class AccountSessionsController < ApplicationController + skip_before_action :redirect_locked_accounts def update authorize :account_session, :update? session[:active_account] = account_session_params[:account_id] diff --git a/app/controllers/admin/account_locks_controller.rb b/app/controllers/admin/account_locks_controller.rb new file mode 100644 index 0000000..21aa3bd --- /dev/null +++ b/app/controllers/admin/account_locks_controller.rb @@ -0,0 +1,31 @@ +class Admin::AccountLocksController < Admin::ApplicationController + before_action :set_account + + def create + authorize :account_lock, :create? + @account.update(locked: true) + redirect_to admin_accounts_path, notice: 'Account locked' + end + + def destroy + authorize :account_lock, :destroy? + @account.update(locked: false) + redirect_to admin_accounts_path, notice: 'Account unlocked' + end + + private + + def set_account + if params[:account_id].present? + @account = Account.find_by(slug: params[:account_id]) + else + failure_redirect + end + rescue ActiveRecord::RecordNotFound + failure_redirect + end + + def failure_redirect + redirect_to admin_accounts_path, alert: 'Failed to find the account' + end +end \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 6f6b302..ef1dce4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -13,6 +13,7 @@ class ApplicationController < ActionController::Base include SetCurrentRequestDetails before_action :redirect_accountless + before_action :redirect_locked_accounts private @@ -29,6 +30,12 @@ class ApplicationController < ActionController::Base end end + def redirect_locked_accounts + if Current.user && !Current.user.admin? && Current.account.present? && Current.account.locked? + redirect_to locked_account_path + end + end + def signed_in_as_admin? signed_in? && current_user.admin? end diff --git a/app/controllers/locked_accounts_controller.rb b/app/controllers/locked_accounts_controller.rb new file mode 100644 index 0000000..90a0618 --- /dev/null +++ b/app/controllers/locked_accounts_controller.rb @@ -0,0 +1,10 @@ +class LockedAccountsController < ApplicationController + skip_before_action :redirect_locked_accounts + skip_after_action :verify_policy_scoped + + def index + unless Current.account.locked? + redirect_to projects_path + end + end +end diff --git a/app/helpers/dropzone_helper.rb b/app/helpers/dropzone_helper.rb index 321bac3..0d1aa66 100644 --- a/app/helpers/dropzone_helper.rb +++ b/app/helpers/dropzone_helper.rb @@ -40,4 +40,13 @@ module DropzoneHelper { name: file_info.filename, size: file_info.byte_size, type: file_info.content_type } end.to_json end + + def dropzone_file_size_limit_for(releasable) + case releasable.model_name.param_key + when "material_release", "acquired_media_release" + 1000000 + else + 256 + end + end end diff --git a/app/javascript/packs/active_storage_dropzone.js b/app/javascript/packs/active_storage_dropzone.js index 74b7fbe..e57e99f 100644 --- a/app/javascript/packs/active_storage_dropzone.js +++ b/app/javascript/packs/active_storage_dropzone.js @@ -12,6 +12,7 @@ class ActiveStorageDropzone { var acceptedFiles = $(element).data("accepted-files") || "image/*"; var dictDefaultMessage = $(element).data("placeholder") || "Drop files here"; var submitButton = $($(element).data("submit-button")); + var maxFileSize = $(element).data("max-file-size"); var that = this; this.myDropzone = new this.DropzoneClass(element, { @@ -20,6 +21,7 @@ class ActiveStorageDropzone { acceptedFiles: acceptedFiles, parallelUploads: 30, dictDefaultMessage: dictDefaultMessage, + maxFilesize: maxFileSize, init: function () { this.on("sending", (file, xhr, formData) => { diff --git a/app/jobs/match_appearance_releases_job.rb b/app/jobs/match_appearance_releases_job.rb index 5136170..66c7ee0 100644 --- a/app/jobs/match_appearance_releases_job.rb +++ b/app/jobs/match_appearance_releases_job.rb @@ -15,6 +15,7 @@ class MatchAppearanceReleasesJob < ApplicationJob matches = response.matches || [] key_signed_id_hash = Hash[filtered_attachments_object[:keys].zip(filtered_attachments_object[:signed_ids])] handle_matches matches, project, key_signed_id_hash + handle_unmatches matches, project, key_signed_id_hash matching_request.destroy end @@ -40,6 +41,21 @@ class MatchAppearanceReleasesJob < ApplicationJob end end + def handle_unmatches(matches, project, key_signed_id_hash) + matched_keys = matches.flat_map { |match| match.contracts + match.headshots } + unmatches = key_signed_id_hash.find_all { |key, _| !key.in?(matched_keys) } + + unmatches.each do |key, signed_id| + blob = ActiveStorage::Blob.find_signed signed_id + + if blob.image? + create_release(project, nil, signed_id, nil) + else + create_release(project, signed_id, nil, nil) + end + end + end + def create_release(project, contract, headshot, identifier) random_contract_no = AppearanceRelease.random_contract_number.to_s is_incomplete = contract.nil? || headshot.nil? diff --git a/app/policies/account_lock_policy.rb b/app/policies/account_lock_policy.rb new file mode 100644 index 0000000..f14f1f6 --- /dev/null +++ b/app/policies/account_lock_policy.rb @@ -0,0 +1,9 @@ +class AccountLockPolicy < ApplicationPolicy + def create? + user.admin? + end + + def destroy? + user.admin? + end +end diff --git a/app/views/accounts/_form.html.erb b/app/views/accounts/_form.html.erb index b95def2..d696b97 100644 --- a/app/views/accounts/_form.html.erb +++ b/app/views/accounts/_form.html.erb @@ -6,7 +6,7 @@ <%= form.email_field :email, class: "form-group" %> <%= form.password_field :password %> <%= form.text_field :account_name, label: 'Account Name' %> - <%= form.select :interested_product_name, options_for_select(["I'm interested in all products", "DirectME", "ReleaseME", "CastME", "EditME", "DeliverME", "ExpenseME"]), { label: "What product are you most interested in?" }, { class: "form-control custom-select" } %> + <%= form.select :interested_product_name, options_for_select(["I'm interested in all products", "ME Suite PRO", "DirectME", "ReleaseME", "CastME", "EditME", "DeliverME", "ExpenseME"]), { label: "What product are you most interested in?" }, { class: "form-control custom-select" } %>
Sign up for a 14 Day Free Trial which includes full access to the following products. No credit card required!
+<%= recording.description %>
-Recording of the live stream will appear here.
-<% end %> + +Live stream has connected successfully and will be available soon.
-Live stream has begun, click play to watch it.
-Live stream got disconnected.
-Live stream is waiting to begin.
-