Compare commits

...

6 Commits

Author SHA1 Message Date
Senad Uka
28e0eb36b7 Upstream sync 2020-09-16 05:39:08 +02:00
Senad Uka
5cf7be6f13 Upstream sync 2020-09-13 20:09:48 +02:00
Senad Uka
3db230de9b Upstream sync 2020-09-09 05:33:57 +02:00
Senad Uka
e5ac3e9345 Upstream sync 2020-09-06 21:42:50 +02:00
Senad Uka
f611382e9e Upstream sync 2020-09-01 17:15:16 +02:00
Senad Uka
95a14ab2f6 Upstream sync 2020-08-31 18:19:00 +02:00
155 changed files with 1933 additions and 679 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -0,0 +1,7 @@
$(document).on("turbolinks:load", function() {
bsCustomFileInput.init();
})
$(document).on("turbolinks:load", function() {
$(".toast").toast('show');
})

View File

@@ -24,6 +24,8 @@ $(document).on "turbolinks:load", ->
stream_selected = $("#broadcast_video").data('videoType') == 'stream'; stream_selected = $("#broadcast_video").data('videoType') == 'stream';
if data.streamer_status == 'recording' && data.status == 'active' && stream_selected if data.streamer_status == 'recording' && data.status == 'active' && stream_selected
$("#broadcast_video").html data.video_content $("#broadcast_video").html data.video_content
$("#recording_status").html data.recording_status_content
new (Clappr.Player)( new (Clappr.Player)(
<%= "baseUrl: 'http://cdn.clappr.io/latest'," if Rails.env.test? %> <%= "baseUrl: 'http://cdn.clappr.io/latest'," if Rails.env.test? %>
parentId: '#broadcast_video' parentId: '#broadcast_video'
@@ -35,11 +37,13 @@ $(document).on "turbolinks:load", ->
hlsMinimumDvrSize: 1) hlsMinimumDvrSize: 1)
if data.streamer_status == "idle" && data.status == "idle" if data.streamer_status == "idle" && data.status == "idle"
$("#broadcast_video").html data.video_content $("#broadcast_video").html data.video_content
$("#recording_status").html data.recording_status_content
showBroadcastRecordings: (data) -> showBroadcastRecordings: (data) ->
$(".flash-message").html data.flash_content $(".flash-message").html data.flash_content
$("#broadcast_recordings").html data.recordings_content $("#broadcast_recordings").html data.recordings_content
$("#broadcast_recordings_nav").html data.recordings_nav_content $("#broadcast_recordings_nav").html data.recordings_nav_content
$(".toast").toast('show')
refreshBroadcastFilesTab: (data) -> refreshBroadcastFilesTab: (data) ->
$("#broadcast_file_list_#{data.broadcast_token}").html data.files_content $("#broadcast_file_list_#{data.broadcast_token}").html data.files_content

View File

@@ -23,3 +23,4 @@ $(document).on "turbolinks:load", ->
showDownloadStatusUpdate: (content) -> showDownloadStatusUpdate: (content) ->
$(".flash-message").html content $(".flash-message").html content
$(".toast").toast('show')

View File

@@ -1,3 +0,0 @@
$(document).on("turbolinks:load", function() {
bsCustomFileInput.init()
})

View File

@@ -0,0 +1,20 @@
$(document).on("click", "#download_releases", function(event) {
event.preventDefault();
const releasable_ids = JSON.parse($("#selected_releases_form").attr('data-releasable-ids'));
const total_entries = $('#total_entries').val();
const input_ids = $('<input>').attr({ type: 'hidden', name: 'release_ids', value: JSON.stringify(releasable_ids) });
const search_query = $('<input>').attr({ type: 'hidden', name: 'search_query', value: $("form input[type='search']").val() });
const type_filter = $('<input>').attr({ type: 'hidden', name: 'type_filter', value: $('#type_filter_value').val() });
const download_count = releasable_ids.length > 0 ? releasable_ids.length : total_entries;
$(this).parent().append(input_ids);
$(this).parent().append(search_query);
$(this).parent().append(type_filter);
if (confirm(`${download_count} release(s) will be downloaded. Is this correct?`)){
Rails.fire($(this).parent()[0], 'submit');
}
});

View File

@@ -1,7 +1,6 @@
$(document).on("click", "[data-behavior=play_recording]", function() { $(document).on("click", "[data-behavior=play_recording]", function() {
if ($(this).hasClass('active')){ clearPlayingHighlight();
return false; $(this).parent().parent().addClass('playing-highlight');
}
$("#broadcast_video").data('videoType', 'recording'); $("#broadcast_video").data('videoType', 'recording');
@@ -16,13 +15,13 @@ $(document).on("click", "[data-behavior=play_recording]", function() {
height: '100%', height: '100%',
autoPlay: true autoPlay: true
}); });
$(".dropdown-menu").children().removeClass('active');
$(".dropdown-menu").children().children('i').remove();
$(this).siblings().removeClass('active');
$(this).siblings().children("i").remove();
$(this).addClass('active');
$(this).prepend('<i class="fa fa-check">&nbsp;</i>');
}); });
$(document).on("click", "[data-behavior=play_stream]", function() { $("#broadcast_video").data('videoType', 'stream'); }); $(document).on("click", "[data-behavior=play_stream]", function() {
// clearPlayingHighlight();
$("#broadcast_video").data('videoType', 'stream');
});
function clearPlayingHighlight() {
$(".playing-highlight").removeClass("playing-highlight");
}

View File

@@ -0,0 +1,4 @@
$(document).on("click", "#director_mode_switch", function() {
// JQuery click event trigger was not working.
document.getElementById("director_mode_link").click();
});

View File

@@ -1,4 +1,30 @@
// Do not allow file attachments in rich text content // Do not allow file attachments in rich text content
addEventListener("trix-file-accept", function(event) { addEventListener("trix-file-accept", function(event) {
event.preventDefault(); event.preventDefault();
}) });
Trix.config.textAttributes.underline = {
style: { "textDecoration": "underline" },
inheritable: true,
parser: function (element) {
var style = window.getComputedStyle(element);
return style.textDecoration === "underline";
}
}
document.addEventListener('trix-initialize', function (e) {
const trix = e.target;
const toolBar = trix.toolbarElement;
// // Creation of the button
const button = document.createElement("button");
button.setAttribute("type", "button");
button.setAttribute("class", "trix-button trix-button--icon trix-button--icon-underline");
button.setAttribute("data-trix-attribute", "underline");
button.setAttribute("title", "underline");
button.setAttribute("tabindex", "-1");
button.innerText = "U";
// Attachment of the button to the toolBar
toolBar.querySelector('.trix-button-group--text-tools').appendChild(button);
});

View File

@@ -412,6 +412,16 @@ a[data-behavior=seekable-timecode] {
background-color: rgba($black, 0.05); background-color: rgba($black, 0.05);
} }
// Black background
.bg-black {
background-color: $black;
}
// White background
.bg-white {
background-color: $white;
}
// Custom width // Custom width
.w-65 { .w-65 {
width: 65% !important; width: 65% !important;
@@ -422,8 +432,93 @@ a[data-behavior=seekable-timecode] {
max-height: 30rem; max-height: 30rem;
} }
// Max-width 75%
.max-w-75 {
max-width: 75%;
}
// Fix height and width // Fix height and width
.fix-h-and-w { .fix-h-and-w {
width: 308px; width: 308px;
height:308px; height:308px;
} }
// Dropdown shown state overrride
.override-dropdown-show-state {
color: $white !important;
background-color: $black !important;
border-color: transparent !important;
}
// Override custom switch color
.override-custom-control-label::before {
background-color: #000000;
}
// Override nav tab design
.override-nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active {
background: transparent;
border-color: transparent;
border-bottom: 3px solid #ff0000;
}
//Trix underline style
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");
}
}
// 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%);
}
// Toast min width and border radius
.toast-min-w-border-radius {
min-width: 18rem;
border-radius: 0.8rem;
}
// Toast left border primary
.toast-border-left-primary {
border-left: 8px solid $primary;
}
// Toast left border danger
.toast-border-left-danger {
border-left: 8px solid $danger;
}
// Change link color to primary on toast notifications
.toast {
a {
color: $primary;
}
a.btn {
color: white;
}
}

View File

@@ -48,6 +48,10 @@ u {
margin-right: -30px; margin-right: -30px;
} }
.embed-person-photo {
text-align: right;
}
.do-not-copy-warning { .do-not-copy-warning {
padding-right: 15px; padding-right: 15px;
} }

View File

@@ -11,6 +11,7 @@ class BroadcastsChannel < ApplicationCable::Channel
def self.broadcast_stream_updates(broadcast) def self.broadcast_stream_updates(broadcast)
status_content = ApplicationController.render partial: "broadcasts/broadcast_status", locals: { broadcast: broadcast } status_content = ApplicationController.render partial: "broadcasts/broadcast_status", locals: { broadcast: broadcast }
video_content = ApplicationController.render partial: "broadcasts/video", locals: { broadcast: broadcast } video_content = ApplicationController.render partial: "broadcasts/video", locals: { broadcast: broadcast }
recording_status_content = ApplicationController.render partial: "broadcasts/recording_status", locals: { broadcast: broadcast }
broadcast_to broadcast, { broadcast_to broadcast, {
event: :broadcast_stream_update, event: :broadcast_stream_update,
@@ -18,6 +19,7 @@ class BroadcastsChannel < ApplicationCable::Channel
playback_url: broadcast.stream_playback_url, playback_url: broadcast.stream_playback_url,
full_live_stream_playback_url: broadcast.full_live_stream_playback_url, full_live_stream_playback_url: broadcast.full_live_stream_playback_url,
video_content: video_content, video_content: video_content,
recording_status_content: recording_status_content,
status_content: status_content, status_content: status_content,
streamer_status: broadcast.streamer_status streamer_status: broadcast.streamer_status
} }

View File

@@ -1,4 +1,5 @@
class AccountSessionsController < ApplicationController class AccountSessionsController < ApplicationController
skip_before_action :redirect_locked_accounts
def update def update
authorize :account_session, :update? authorize :account_session, :update?
session[:active_account] = account_session_params[:account_id] session[:active_account] = account_session_params[:account_id]

View File

@@ -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

View File

@@ -45,13 +45,14 @@ class Api::ReleasesController < Api::ApiController
if model_name == "acquired_media_release" if model_name == "acquired_media_release"
mapping = { mapping = {
"#{model_name.camelize}": SerializableAcquiredMediaRelease, "#{model_name.camelize}": SerializableAcquiredMediaRelease,
FileInfo: SerializableFileInfo FileInfo: SerializableFileInfo,
"ActiveStorage::Attachment".to_sym => ActiveStorage::SerializableAttachment,
} }
render jsonapi: release, render jsonapi: release,
status: status, status: status,
class: mapping, class: mapping,
include: [:file_infos] include: [:files, :file_infos]
else else
mapping = { mapping = {
"#{model_name.camelize}": show_serializable, "#{model_name.camelize}": show_serializable,

View File

@@ -4,6 +4,7 @@ require './lib/knock_monkeypatch'
class Api::UserTokenController < Knock::AuthTokenController class Api::UserTokenController < Knock::AuthTokenController
include Oath::ControllerHelpers include Oath::ControllerHelpers
include RememberMe::Controller
skip_before_action :verify_authenticity_token skip_before_action :verify_authenticity_token
before_action :sign_in_user before_action :sign_in_user

View File

@@ -13,6 +13,7 @@ class ApplicationController < ActionController::Base
include SetCurrentRequestDetails include SetCurrentRequestDetails
before_action :redirect_accountless before_action :redirect_accountless
before_action :redirect_locked_accounts
private private
@@ -29,6 +30,12 @@ class ApplicationController < ActionController::Base
end end
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? def signed_in_as_admin?
signed_in? && current_user.admin? signed_in? && current_user.admin?
end end

View File

@@ -7,7 +7,7 @@ class BroadcastRecordingsController < ApplicationController
def destroy def destroy
@recording.update(hidden: true) @recording.update(hidden: true)
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page]) set_recordings
end end
private private
@@ -23,4 +23,8 @@ class BroadcastRecordingsController < ApplicationController
def set_recording def set_recording
@recording = authorize policy_scope(@broadcast.broadcast_recordings).find(params[:id]) @recording = authorize policy_scope(@broadcast.broadcast_recordings).find(params[:id])
end end
def set_recordings
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
end
end end

View File

@@ -32,6 +32,7 @@ class BroadcastsController < ApplicationController
@conference_url = conference_url_for(@broadcast) @conference_url = conference_url_for(@broadcast)
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page]) @recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
@files = @broadcast.files.order("created_at DESC").paginate(page: params[:files_page]) @files = @broadcast.files.order("created_at DESC").paginate(page: params[:files_page])
render layout: 'application' render layout: 'application'
end end
@@ -113,7 +114,7 @@ class BroadcastsController < ApplicationController
end end
def conference_url_for(broadcast) def conference_url_for(broadcast)
broadcast.video_conference_url_override || url_for([broadcast.project, broadcast, :zoom_meeting]) broadcast.video_conference_url_override.presence || url_for([broadcast.project, broadcast, :zoom_meeting])
end end
def log_create_analytics def log_create_analytics

View File

@@ -7,28 +7,41 @@ class ContractDownloadsController < ApplicationController
def create def create
authorize policy_scope(Download).create authorize policy_scope(Download).create
fetch_releases
download = @project.downloads.create!(release_type: params[:release_type]) download = @project.downloads.create!(release_type: release_type)
other_downloads_in_progress = @project.downloads.unfinished_desc_order.offset(1) other_downloads_in_progress = @project.downloads.unfinished_desc_order.offset(1)
if other_downloads_in_progress.any? if other_downloads_in_progress.any?
in_progress_downloads_details = render_to_string "_other_pending_downloads", locals: { downloads: other_downloads_in_progress, release_type: params[:release_type] }, :layout => false in_progress_downloads_details = render_to_string "_other_pending_downloads", locals: { downloads: other_downloads_in_progress, release_type: release_type }, :layout => false
ProjectsChannel.broadcast_download_generation_update(download, in_progress_downloads_details) ProjectsChannel.broadcast_download_generation_update(download, in_progress_downloads_details)
else else
ProjectsChannel.broadcast_download_generation_update(download, I18n.t("contract_downloads.download.pending", release_type: params[:release_type].titleize)) ProjectsChannel.broadcast_download_generation_update(download, I18n.t("contract_downloads.download.pending", release_type: release_type.titleize))
end end
GenerateContractsZipJob.perform_later(@project, download, params[:release_type], @releases.ids) GenerateContractsZipJob.perform_later(@project, download, release_type, release_ids, search_query, type_filter)
end end
private private
def fetch_releases def release_type
@releases = policy_scope(@project.public_send(releases)) params[:release_type]
end end
def releases def search_query
params[:release_type].constantize.model_name.plural params[:search_query]
end
def type_filter
params[:type_filter]
end
def release_ids
JSON.parse(params[:release_ids])
rescue StandardError
[]
end
def release_name(release_type)
release_type.constantize.model_name.plural
end end
end end

View File

@@ -3,7 +3,7 @@ class ContractsController < ApplicationController
respond_to do |format| respond_to do |format|
format.pdf { send_contract_pdf } format.pdf { send_contract_pdf }
if Rails.env.development? if Rails.env.development? || Rails.env.test?
format.html { render_sample_html } format.html { render_sample_html }
end end
end end

View File

@@ -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

View File

@@ -106,7 +106,7 @@ class MaterialReleasesController < ApplicationController
:term_id, :term_text, :term_id, :term_text,
:restriction_id, :restriction_text, :restriction_id, :restriction_text,
:description, :description,
:contract, { photos: [] } :contract, files: []
) )
end end

View File

@@ -4,4 +4,16 @@ class PagesController < ApplicationController
skip_after_action :verify_authorized skip_after_action :verify_authorized
skip_after_action :verify_policy_scoped skip_after_action :verify_policy_scoped
skip_before_action :require_login skip_before_action :require_login
layout :layout_for_page
private
def layout_for_page
case params[:id]
when 'nanocosmos_player'
false
else
end
end
end end

View File

@@ -0,0 +1,24 @@
class Public::BroadcastRecordingStarringsController < Public::BaseController
skip_after_action :verify_authorized
before_action :set_broadcast
before_action :set_recording
def create
@recording.toggle_star
set_recordings
end
private
def set_broadcast
@broadcast = Broadcast.find_by_token(params[:broadcast_token])
end
def set_recording
@recording = @broadcast.broadcast_recordings.find(params[:broadcast_recording_id])
end
def set_recordings
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
end
end

View File

@@ -0,0 +1,31 @@
class Public::BroadcastRecordingsController < Public::BaseController
skip_after_action :verify_authorized
before_action :set_broadcast, only: [:edit, :update]
before_action :set_recording, only: [:edit, :update]
def edit
end
def update
@recording.update(broadcast_recording_params)
set_recordings
end
private
def broadcast_recording_params
params.require(:broadcast_recording).permit(:name, :description)
end
def set_broadcast
@broadcast = Broadcast.find_by_token(params[:broadcast_token])
end
def set_recording
@recording = @broadcast.broadcast_recordings.find(params[:id])
end
def set_recordings
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
end
end

View File

@@ -44,7 +44,7 @@ class Public::BroadcastsController < Public::BaseController
end end
def conference_url_for(broadcast) def conference_url_for(broadcast)
broadcast.video_conference_url_override || broadcast_zoom_meeting_url(broadcast.token) broadcast.video_conference_url_override.presence || broadcast_zoom_meeting_url(broadcast.token)
end end
class MultiViewBroadcast class MultiViewBroadcast

View File

@@ -92,7 +92,7 @@ class Public::MaterialReleasesController < Public::BaseController
params.require(:material_release).permit(person_params, guardian_params, second_guardian_params, :minor, params.require(:material_release).permit(person_params, guardian_params, second_guardian_params, :minor,
:name, :address_street1, :address_street2, :address_city, :address_state, :address_zip, :address_country, :name, :address_street1, :address_street2, :address_city, :address_state, :address_zip, :address_country,
:signature_base64, :signature_base64,
:locale, :contract_template, :description, photos: [] :locale, :contract_template, :description, files: []
) )
end end

View File

@@ -2,7 +2,7 @@ class VideoAnalyses::AcquiredMediaReleasesController < ApplicationController
before_action :set_video before_action :set_video
def index def index
@acquired_media_file_infos = filtered_file_infos @acquired_media_files = filtered_files
end end
private private
@@ -15,12 +15,12 @@ class VideoAnalyses::AcquiredMediaReleasesController < ApplicationController
params[:query] params[:query]
end end
def filtered_file_infos def filtered_files
releasables = policy_scope(@video.acquired_media_releases) releasables = policy_scope(@video.acquired_media_releases)
results = FileInfo.where(releasable: releasables) results = ActiveStorage::Attachment.where(record: releasables, name: "files")
if query_param.present? if query_param.present?
results = results.search_filename(query_param) results = results.joins(:blob).where("active_storage_blobs.filename ILIKE ?", "%#{query_param}%")
end end
results results

View File

@@ -74,6 +74,7 @@ class VideoReleaseConfirmationsController < ApplicationController
params.require(:video_release_confirmation).permit( params.require(:video_release_confirmation).permit(
:time_elapsed, :time_elapsed,
:file_info_id, :file_info_id,
:file_id,
:channel, :channel,
:timecode_in, :timecode_in,
:timecode_out, :timecode_out,

View File

@@ -40,4 +40,13 @@ module DropzoneHelper
{ name: file_info.filename, size: file_info.byte_size, type: file_info.content_type } { name: file_info.filename, size: file_info.byte_size, type: file_info.content_type }
end.to_json end.to_json
end 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 end

View File

@@ -17,6 +17,7 @@ module TagsHelper
disable_with: disabled_content, disable_with: disabled_content,
}, },
form: { form: {
id: "selected_releases_form",
data: { data: {
releasable_ids: [], releasable_ids: [],
}, },

View File

@@ -12,6 +12,7 @@ class ActiveStorageDropzone {
var acceptedFiles = $(element).data("accepted-files") || "image/*"; var acceptedFiles = $(element).data("accepted-files") || "image/*";
var dictDefaultMessage = $(element).data("placeholder") || "Drop files here"; var dictDefaultMessage = $(element).data("placeholder") || "Drop files here";
var submitButton = $($(element).data("submit-button")); var submitButton = $($(element).data("submit-button"));
var maxFileSize = $(element).data("max-file-size");
var that = this; var that = this;
this.myDropzone = new this.DropzoneClass(element, { this.myDropzone = new this.DropzoneClass(element, {
@@ -20,6 +21,7 @@ class ActiveStorageDropzone {
acceptedFiles: acceptedFiles, acceptedFiles: acceptedFiles,
parallelUploads: 30, parallelUploads: 30,
dictDefaultMessage: dictDefaultMessage, dictDefaultMessage: dictDefaultMessage,
maxFilesize: maxFileSize,
init: function () { init: function () {
this.on("sending", (file, xhr, formData) => { this.on("sending", (file, xhr, formData) => {

View File

@@ -7,13 +7,14 @@ class GenerateContractsZipJob < ApplicationJob
@project = job.arguments.first @project = job.arguments.first
@download = job.arguments.second @download = job.arguments.second
@release_type = job.arguments.third @release_type = job.arguments.third
@folder_name = "#{@project.name.parameterize}_#{get_release_name(@release_type).gsub('_', '-')}" @release_ids = job.arguments.fourth
@search_query = job.arguments.fifth
@type_filter = job.arguments[5]
@folder_name = "#{@project.name.parameterize}_#{release_name.gsub('_', '-')}"
@download.update!(name: @folder_name, status: :pending) @download.update!(name: @folder_name, status: :pending)
end end
def perform(project, download, release_type, release_ids) def perform(project, download, release_type, release_ids, search_query, type_filter)
releases = project.public_send(get_release_name(release_type)).where(id: release_ids)
::ReleaseContractCollectionService.new(releases, @folder_name).build do |dir, files| ::ReleaseContractCollectionService.new(releases, @folder_name).build do |dir, files|
zipfile_name = "#{dir}/#{@folder_name}.zip" zipfile_name = "#{dir}/#{@folder_name}.zip"
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile| Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
@@ -61,7 +62,32 @@ class GenerateContractsZipJob < ApplicationJob
end end
end end
def get_release_name(release_type) def release_name
release_type.constantize.model_name.plural @release_type.constantize.model_name.plural
end
def all_releases
@project.public_send(release_name)
end
def releases
if @release_ids.any?
return all_releases.where(id: @release_ids)
end
results = all_releases
if all_releases.respond_to?(:complete, :incomplete)
results = case @type_filter
when 'complete'
all_releases.complete
when 'incomplete'
all_releases.incomplete
else
all_releases
end
end
results = results.search(@search_query) if @search_query.present?
results
end end
end end

View File

@@ -15,6 +15,7 @@ class MatchAppearanceReleasesJob < ApplicationJob
matches = response.matches || [] matches = response.matches || []
key_signed_id_hash = Hash[filtered_attachments_object[:keys].zip(filtered_attachments_object[:signed_ids])] key_signed_id_hash = Hash[filtered_attachments_object[:keys].zip(filtered_attachments_object[:signed_ids])]
handle_matches matches, project, key_signed_id_hash handle_matches matches, project, key_signed_id_hash
handle_unmatches matches, project, key_signed_id_hash
matching_request.destroy matching_request.destroy
end end
@@ -40,6 +41,21 @@ class MatchAppearanceReleasesJob < ApplicationJob
end end
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) def create_release(project, contract, headshot, identifier)
random_contract_no = AppearanceRelease.random_contract_number.to_s random_contract_no = AppearanceRelease.random_contract_number.to_s
is_incomplete = contract.nil? || headshot.nil? is_incomplete = contract.nil? || headshot.nil?

View File

@@ -15,6 +15,7 @@ class AcquiredMediaRelease < ApplicationRecord
include SecondGuardianPhotoable include SecondGuardianPhotoable
include GuardianName include GuardianName
include SecondGuardianName include SecondGuardianName
include FilesFilterable
class << self class << self
def custom_csv_exportable_headers def custom_csv_exportable_headers
@@ -106,16 +107,4 @@ class AcquiredMediaRelease < ApplicationRecord
def files_count def files_count
files.any? ? files.size : I18n.t('acquired_media_releases.acquired_media_release.no_media') files.any? ? files.size : I18n.t('acquired_media_releases.acquired_media_release.no_media')
end end
def image_files
files_blobs.where("content_type ILIKE ?", "%image%")
end
def video_files
files_blobs.where("content_type ILIKE ?", "%video%")
end
def other_files
files_blobs.where("NOT content_type ILIKE ANY (array[?])", ["%image%", "%video%"])
end
end end

View File

@@ -7,8 +7,10 @@ class BroadcastRecording < ApplicationRecord
scope :visible, -> { where(hidden: false) } scope :visible, -> { where(hidden: false) }
before_save :set_title_and_description
def download_url def download_url
"https://stream.mux.com/#{asset_playback_uid}/#{file_name}?download=#{download_file_name}" "https://stream.mux.com/#{asset_playback_uid}/#{file_name}?download=#{name}"
end end
def playback_url def playback_url
@@ -16,6 +18,21 @@ class BroadcastRecording < ApplicationRecord
end end
def download_file_name def download_file_name
"#{broadcast_name}_Date_#{created_at.in_time_zone(broadcast.shoot_location_time_zone).strftime("%Y-%m-%d")}_Time_#{created_at.in_time_zone(broadcast.shoot_location_time_zone).strftime("%T")}".parameterize "#{broadcast_name}_Date_#{Time.now.in_time_zone(broadcast.shoot_location_time_zone).strftime("%Y-%m-%d")}_Time_#{Time.now.in_time_zone(broadcast.shoot_location_time_zone).strftime("%T")}".parameterize
end
def toggle_star
toggle! :starred
end
def thumbnail_url(width = 300)
"https://image.mux.com/#{asset_playback_uid}/thumbnail.jpg?width=#{width}"
end
private
def set_title_and_description
self.name ||= download_file_name
self.description ||= "No description provided for this recording."
end end
end end

View File

@@ -0,0 +1,17 @@
module FilesFilterable
extend ActiveSupport::Concern
included do
def image_files
files_blobs.where("content_type ILIKE ?", "%image%")
end
def video_files
files_blobs.where("content_type ILIKE ?", "%video%")
end
def other_files
files_blobs.where("NOT content_type ILIKE ANY (array[?])", ["%image%", "%video%"])
end
end
end

View File

@@ -18,7 +18,7 @@ class ContractTemplate < ApplicationRecord
has_many :medical_releases, dependent: :restrict_with_error has_many :medical_releases, dependent: :restrict_with_error
has_many :misc_releases, dependent: :restrict_with_error has_many :misc_releases, dependent: :restrict_with_error
monetize :fee_cents monetize :fee_old_cents
has_rich_text :body has_rich_text :body
has_rich_text :guardian_clause has_rich_text :guardian_clause
has_rich_text :signature_legal_text has_rich_text :signature_legal_text
@@ -29,7 +29,7 @@ class ContractTemplate < ApplicationRecord
validates :name, presence: true validates :name, presence: true
validates :release_type, presence: true validates :release_type, presence: true
validates :fee_cents, numericality: { validates :fee_old_cents, numericality: {
greater_than_or_equal_to: 0, greater_than_or_equal_to: 0,
less_than_or_equal_to: 99_999_999_99 less_than_or_equal_to: 99_999_999_99
} }
@@ -50,7 +50,11 @@ class ContractTemplate < ApplicationRecord
enum accessibility: [:public_template, :private_template] enum accessibility: [:public_template, :private_template]
def fee? def fee?
!fee.zero? fee.present?
end
def fee_old?
!fee_old.zero?
end end
def releases def releases

View File

@@ -3,7 +3,7 @@ class MaterialRelease < ApplicationRecord
include Contractable include Contractable
include Exploitable include Exploitable
include Notable include Notable
include Photoable include Photoable # This association needs to be removed after changing the API. Removing it right now will cause failure in API specs.
include Releasable include Releasable
include Searchable include Searchable
include Signable include Signable
@@ -16,11 +16,11 @@ class MaterialRelease < ApplicationRecord
include SecondGuardianPhotoable include SecondGuardianPhotoable
include GuardianName include GuardianName
include SecondGuardianName include SecondGuardianName
include FilesFilterable
class << self class << self
def custom_csv_exportable_headers def custom_csv_exportable_headers
%i[name owner_info] %i[name owner_info files_count]
end end
end end
@@ -57,6 +57,8 @@ class MaterialRelease < ApplicationRecord
%w[guardian_2_address_country country] %w[guardian_2_address_country country]
] ]
has_many_attached :files
# We don't care for the argument but method WILL receive option name # We don't care for the argument but method WILL receive option name
# when called from inside with_option block, hence * argument # when called from inside with_option block, hence * argument
def self.face_photo_acceptable_content_types(*) def self.face_photo_acceptable_content_types(*)
@@ -92,4 +94,8 @@ class MaterialRelease < ApplicationRecord
def uses_edl? def uses_edl?
true true
end end
def files_count
files.any? ? files.size : I18n.t('material_releases.material_release.no_media')
end
end end

View File

@@ -9,6 +9,10 @@ class VideoReleaseConfirmation < ApplicationRecord
Timecode.from_seconds(time_elapsed.to_f).to_s Timecode.from_seconds(time_elapsed.to_f).to_s
end end
def file
ActiveStorage::Attachment.find(file_id)
end
private private
class ReleaseRankOrder class ReleaseRankOrder

View File

@@ -0,0 +1,9 @@
class AccountLockPolicy < ApplicationPolicy
def create?
user.admin?
end
def destroy?
user.admin?
end
end

View File

@@ -1,4 +1,8 @@
class BroadcastRecordingPolicy < ApplicationPolicy class BroadcastRecordingPolicy < ApplicationPolicy
def create?
true
end
def destroy? def destroy?
if user.nil? || user.user.nil? if user.nil? || user.user.nil?
return false return false
@@ -6,4 +10,12 @@ class BroadcastRecordingPolicy < ApplicationPolicy
user.manager? || user.account_manager? user.manager? || user.account_manager?
end end
def edit?
true
end
def update?
true
end
end end

View File

@@ -19,12 +19,16 @@ class MaterialReleasePolicy < ReleasePolicy
user.manager? || user.account_manager? user.manager? || user.account_manager?
end end
def edit_photos? def edit_files?
true true
end end
def update_files?
edit_files?
end
def update_photos? def update_photos?
edit_photos? edit_files?
end end
def tag_multiple? def tag_multiple?

View File

@@ -17,4 +17,14 @@ class SerializableAcquiredMediaRelease < JSONAPI::Serializable::Resource
{ count: @object.file_infos.size } { count: @object.file_infos.size }
end end
end end
has_many :files do
data do
@object.files
end
meta do
{ count: @object.files.size }
end
end
end end

View File

@@ -1,5 +1,9 @@
class SerializableUser < JSONAPI::Serializable::Resource class SerializableUser < JSONAPI::Serializable::Resource
type "user" type "user"
attributes :email attributes :email, :full_name
attribute :company_name do
@object.primary_account.name
end
end end

View File

@@ -24,7 +24,7 @@ class ReleaseContractCollectionService
end end
files = Dir.entries("#{dir}/").select { |f| !File.directory? f } files = Dir.entries("#{dir}/").select { |f| !File.directory? f }
raise StandardError.new "Contracts or Contract Templates not found." unless files.any? # raise StandardError.new "Contracts or Contract Templates not found." unless files.any?
yield(dir, files) yield(dir, files)
} }
end end

View File

@@ -6,7 +6,7 @@
<%= form.email_field :email, class: "form-group" %> <%= form.email_field :email, class: "form-group" %>
<%= form.password_field :password %> <%= form.password_field :password %>
<%= form.text_field :account_name, label: 'Account Name' %> <%= 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" } %>
<div class="pt-3"> <div class="pt-3">
<%= form.submit "Start Free Trial", class: "btn btn-block btn-danger font-weight-bold" %> <%= form.submit "Start Free Trial", class: "btn btn-block btn-danger font-weight-bold" %>
</div> </div>

View File

@@ -4,6 +4,9 @@
<h3>Welcome To <%= suite_wordmark("d-inline-block") %></h3> <h3>Welcome To <%= suite_wordmark("d-inline-block") %></h3>
<div class="mt-4"> <div class="mt-4">
<p>Sign up for a <strong>14 Day Free Trial</strong> which includes full access to the following products. No credit card required!</p> <p>Sign up for a <strong>14 Day Free Trial</strong> which includes full access to the following products. No credit card required!</p>
<div class="d-flex justify-content-between pb-2">
<div><%= image_tag "ME_PRO_black.png", width: "96.66%" %></div>
</div>
<div class="d-flex justify-content-between pb-2"> <div class="d-flex justify-content-between pb-2">
<div><%= image_tag "logo_directme.png", width: "90%" %></div> <div><%= image_tag "logo_directme.png", width: "90%" %></div>
<div><%= image_tag "logo_releaseme.png", width: "90%" %></div> <div><%= image_tag "logo_releaseme.png", width: "90%" %></div>

View File

@@ -1,8 +1,11 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<input id="total_entries" type=hidden value=<%= @acquired_media_releases.total_entries %> />
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3"> <div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3">
<% if policy(AcquiredMediaRelease).new? %> <% if policy(AcquiredMediaRelease).new? %>
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, @project, :acquired_media_release], class: "btn btn-primary mr-2 mb-2" %> <div class="mr-auto">
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, @project, :acquired_media_release], class: "btn btn-primary mr-2 mb-2" %>
</div>
<% end %> <% end %>
<% if @acquired_media_releases.any? && policy(AcquiredMediaRelease).tag_multiple? %> <% if @acquired_media_releases.any? && policy(AcquiredMediaRelease).tag_multiple? %>
@@ -10,7 +13,7 @@
<% end %> <% end %>
<% if @acquired_media_releases.any? && policy(AcquiredMediaRelease).download_multiple? %> <% if @acquired_media_releases.any? && policy(AcquiredMediaRelease).download_multiple? %>
<%= link_to "Download All", [@project, :contract_downloads, release_type: @acquired_media_releases.name], method: :post, remote: true, class: "btn btn-light border ml-auto mr-2 mb-2", data: { <%= button_to "Download", [@project, :contract_downloads, release_type: @acquired_media_releases.name], id: "download_releases", method: :post, remote: true, class: "btn btn-light border mr-2 mb-2", data: {
disable_with: "Please wait..." } %> disable_with: "Please wait..." } %>
<% end %> <% end %>

View File

@@ -1,3 +1,5 @@
$("#acquired_media_releases").html("<%= j render(@acquired_media_releases) %>"); $("#acquired_media_releases").html("<%= j render(@acquired_media_releases) %>");
$("form input[type='search']").val("<%= params[:query] %>"); $("form input[type='search']").val("<%= params[:query] %>");
$("#acquired_media_releases_pagination").html("<%= j will_paginate(@acquired_media_releases) %>"); $("#acquired_media_releases_pagination").html("<%= j will_paginate(@acquired_media_releases) %>");
$("#selected_releases_form").attr('data-releasable-ids', JSON.stringify([]));
$("#total_entries").val(<%= @acquired_media_releases.total_entries %>);

View File

@@ -30,6 +30,11 @@
<%= link_to fa_icon("arrow-right", text: "Overview"), admin_account_path(account), class: "dropdown-item" %> <%= link_to fa_icon("arrow-right", text: "Overview"), admin_account_path(account), class: "dropdown-item" %>
<%= link_to fa_icon("pencil", text: "Edit"), edit_admin_account_path(account), class: "dropdown-item" %> <%= link_to fa_icon("pencil", text: "Edit"), edit_admin_account_path(account), class: "dropdown-item" %>
<%= link_to fa_icon("arrow-right", text: "Account Managers"), account_auths_path({ account_id: account.id}), class: "dropdown-item" %> <%= link_to fa_icon("arrow-right", text: "Account Managers"), account_auths_path({ account_id: account.id}), class: "dropdown-item" %>
<% if account.locked? %>
<%= link_to fa_icon("unlock", text: "Unlock Account"), [:admin, account, :lock], method: :delete, class: "dropdown-item" %>
<% else %>
<%= link_to fa_icon("lock", text: "Lock Account"), [:admin, account, :lock], method: :post, class: "dropdown-item" %>
<% end %>
</div> </div>
</div> </div>
</td> </td>

View File

@@ -1,5 +1,6 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<input id="total_entries" type=hidden value=<%= @appearance_releases.total_entries %> />
<div id="upload-progress-container" class="mb-1"></div> <div id="upload-progress-container" class="mb-1"></div>
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-2"> <div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-2">
<% if policy(AppearanceRelease).new? %> <% if policy(AppearanceRelease).new? %>
@@ -16,7 +17,7 @@
<% end %> <% end %>
<% if @appearance_releases.any? && policy(AppearanceRelease).download_multiple? %> <% if @appearance_releases.any? && policy(AppearanceRelease).download_multiple? %>
<%= link_to "Download All", [@project, :contract_downloads, release_type: @appearance_releases.name], method: :post, remote: true, class: "btn btn-light border mr-2 mb-2", data: { disable_with: "Please wait..." } %> <%= button_to "Download", [@project, :contract_downloads, release_type: @appearance_releases.name], id: "download_releases", method: :post, remote: true, class: "btn btn-light border mr-2 mb-2", data: { disable_with: "Please wait..." } %>
<% end %> <% end %>
</div> </div>
</div> </div>

View File

@@ -3,3 +3,5 @@ $("form input[type='search']").val("<%= params[:query] %>");
$("#type_filter_actions").html("<%= j render 'type_filter_actions' %>"); $("#type_filter_actions").html("<%= j render 'type_filter_actions' %>");
$("#appearance_releases_pagination").html("<%= j will_paginate(@appearance_releases) %>"); $("#appearance_releases_pagination").html("<%= j will_paginate(@appearance_releases) %>");
$('#type_filter_value').val("<%= params[:type_filter] %>"); $('#type_filter_value').val("<%= params[:type_filter] %>");
$("#selected_releases_form").attr('data-releasable-ids', JSON.stringify([]));
$("#total_entries").val(<%= @appearance_releases.total_entries %>);

View File

@@ -1,5 +1,22 @@
<% if flash.alert.present? %> <!-- Wrapping element flash message-->
<div class="alert alert-danger text-center text-md-left"><%= flash.alert.html_safe %></div> <div class="position-relative" style="z-index: 9999;">
<% elsif flash.notice.present? %> <!-- Position toasts -->
<div class="alert alert-primary text-center text-md-left"><%= flash.notice.html_safe %></div> <div class="position-absolute" style="top: 0.5rem; right: 0.5rem;">
<% end %> <% if flash.alert.present? %>
<div class="toast fade show bg-black text-white toast-min-w-border-radius" data-autohide="false">
<div class="toast-body toast-border-left-danger">
<button type="button" class="close text-white ml-2" data-dismiss="toast">&times;</button>
<p><%= flash.alert.html_safe %></p>
</div>
</div>
<% elsif flash.notice.present? %>
<div class="toast fade show bg-black text-white toast-min-w-border-radius" data-autohide="false">
<div class="toast-body toast-border-left-primary">
<button type="button" class="close text-white ml-2" data-dismiss="toast">&times;</button>
<p><%= flash.notice.html_safe %></p>
</div>
</div>
<% end %>
</div>
</div>

View File

@@ -0,0 +1,11 @@
$('[data-id="<%= dom_id(@recording) %>"]').remove();
<% if @recordings.empty? %>
$("#broadcast_recordings_nav").append('<p class="dropdown-item text-muted">Recordings will appear here</p>')
<% end %>
$("#broadcast_recordings").html("<%= j render(partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast }) %>");
// Close and remove the modal
$("#edit_broadcast_recording_modal").on("hidden.bs.modal", function (e) {
$("#edit_broadcast_recording_modal").remove();
});
$("#edit_broadcast_recording_modal").modal("hide");

View File

@@ -1,6 +1 @@
var dom_id = "<%= dom_id(@recording) %>" <%= render("broadcast_recordings/refresh_recordings_list") %>
$('[data-id="' + dom_id + '"]').remove();
<% if @recordings.empty? %>
$("#broadcast_recordings_nav").append('<p class="dropdown-item text-muted">Recordings will appear here</p>')
<% end %>
$("#broadcast_recordings").html("<%= j render(partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast }) %>");

View File

@@ -1,3 +1 @@
<%= link_to broadcast_recording.download_file_name, "javascript:void(0);", class: "dropdown-item", data: { behavior: "play_recording", playback_url: broadcast_recording.playback_url, id: dom_id(broadcast_recording) } %> <%= link_to broadcast_recording.name, "javascript:void(0);", class: "dropdown-item", data: { behavior: "play_recording", playback_url: broadcast_recording.playback_url, id: dom_id(broadcast_recording) } %>

View File

@@ -1,18 +1,31 @@
<% if recordings.present? %> <ul class="list-unstyled">
<p>Click below to download the recordings of the live stream.</p> <% recordings.each do |recording| %>
<ul class="mt-2"> <li class="media p-3">
<% recordings.each do |recording| %> <% if policy(BroadcastRecording).update? %>
<li> <%= link_to fa_icon("#{recording.starred ? 'star' : 'star-o'} fw"), broadcast_broadcast_recording_broadcast_recording_starrings_path(broadcast.token, recording), method: :post, class: "text-warning mr-3", remote: true %>
<%= link_to(recording.download_file_name, recording.download_url, target: "_blank") %> <% end %>
<% if (controller.class.module_parent.to_s != "Public" && policy(BroadcastRecording).destroy?) %>
<%= link_to "Hide", [broadcast.project, broadcast, recording], class: "btn-sm btn-primary ml-1 text-decoration-none", remote: true, method: :delete, data: { confirm: t('.confirm_hide') } %> <div class="play-thumbnail">
<%= image_tag(recording.thumbnail_url, class: 'mr-2', size: "64x64") %>
<%= content_tag :div, class: "play-btn", data: { behavior: "play_recording", playback_url: recording.playback_url, id: dom_id(recording) } do %>
<%= render "broadcasts/play_button_svg" %>
<% end %> <% end %>
</li> </div>
<% end %>
</ul> <div class="media-body">
<div id="recordings_pagination" class="row mt-5 justify-content-center"> <h5 class="mt-0 mb-1"><%= recording.name %></h5>
<%= will_paginate(recordings, params: {controller: "broadcasts", action: "show", project_id: broadcast.project_id, id: broadcast.id, page: params[:page], active_tab: 'recordings'}) %> <small class="text-muted"><%= recording.description %></small>
</div> </div>
<% else %>
<p>Recording of the live stream will appear here.</p> <% if policy(BroadcastRecording).edit? %>
<% end %> <%= link_to fa_icon('edit'), edit_broadcast_broadcast_recording_path(broadcast.token, recording), remote: true %>
<% end %>
<%= link_to(fa_icon('download'), recording.download_url, target: "_blank") %>
</li>
<% end %>
</ul>
<div id="recordings_pagination" class="row mt-5 justify-content-center">
<%= will_paginate(recordings, params: {controller: "broadcasts", action: "show", project_id: broadcast.project_id, id: broadcast.id, page: params[:page], active_tab: 'recordings'}) %>
</div>

View File

@@ -1,21 +1,9 @@
<% if broadcast.streamer_connected? || (broadcast.streamer_recording? && !broadcast.active?) %> <% if broadcast.streamer_connected? || (broadcast.streamer_recording? && !broadcast.active?) %>
<div class="alert alert-info text-center text-md-left"> <p class="mb-1">Live stream has connected successfully and will be available soon.</p>
<%= fa_icon "info-circle" %>
<strong>Live stream has connected successfully and will be available soon.</strong>
</div>
<% elsif broadcast.streamer_recording? && broadcast.active? %> <% elsif broadcast.streamer_recording? && broadcast.active? %>
<div class="alert alert-success text-center text-md-left"> <p class="mb-1">Live stream has begun, click play to watch it.</p>
<%= fa_icon "success" %>
<strong>Live stream has begun, click play to watch it.</strong>
</div>
<% elsif broadcast.streamer_disconnected? %> <% elsif broadcast.streamer_disconnected? %>
<div class="alert alert-warning text-center text-md-left"> <p class="mb-1">Live stream got disconnected.</p>
<%= fa_icon "warning" %>
<strong>Live stream got disconnected.</strong>
</div>
<% elsif (broadcast.idle? && broadcast.streamer_idle?) || (broadcast.created? && broadcast.streamer_idle?) %> <% elsif (broadcast.idle? && broadcast.streamer_idle?) || (broadcast.created? && broadcast.streamer_idle?) %>
<div class="alert alert-info text-center text-md-left"> <p class="mb-1">Live stream is waiting to begin.</p>
<%= fa_icon "info-circle" %>
<strong>Live stream is waiting to begin.</strong>
</div>
<% end %> <% end %>

View File

@@ -1,4 +1,4 @@
<div class="text-center pb-2" id="broadcast_file_form_<%= broadcast.token %>"> <div class="text-center p-3" id="broadcast_file_form_<%= broadcast.token %>">
<% if controller.class.module_parent.to_s == "Public" %> <% if controller.class.module_parent.to_s == "Public" %>
<%= render partial: "public/broadcasts/file_form", locals: { model: [broadcast], token: broadcast.token } %> <%= render partial: "public/broadcasts/file_form", locals: { model: [broadcast], token: broadcast.token } %>
<% else %> <% else %>

View File

@@ -0,0 +1,35 @@
<% # TODO: Refactor this %>
<% if params[:director_mode] %>
<% if controller.class.module_parent.to_s == "Public" %>
<% live_take_url = url_for(params.permit!.merge(director_mode: true, token: broadcast.token)) %>
<% else %>
<% live_take_url = url_for(params.permit!.merge(director_mode: true, id: broadcast.id)) %>
<% end %>
<hr/>
<% else %>
<% if controller.class.module_parent.to_s == "Public" %>
<% live_take_url = url_for(params.permit!.merge(token: broadcast.token).except(:director_mode)) %>
<% else %>
<% live_take_url = url_for(params.permit!.merge(id: broadcast.id).except(:director_mode)) %>
<% end %>
<% end %>
<div id="live-take" class="media p-3 playing-highlight">
<div id="recording_status">
<%= render 'broadcasts/recording_status', broadcast: broadcast %>
</div>
<div class="play-thumbnail">
<%= image_tag "live_icon.png", class: "mr-2", width: 64, alt: "Live stream thumbnail" %>
<%= link_to live_take_url, class: "play-btn", data: { behavior: "play_stream" } do %>
<%= render "broadcasts/play_button_svg" %>
<% end %>
</div>
<div class="media-body">
<h5 class="mt-0"><%= broadcast.name %></h5>
<small id="broadcast_updates" class="text-muted">
<%= render partial: 'broadcasts/broadcast_status', locals: { broadcast: broadcast } %>
</small>
</div>
</div>

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26">
<polygon class="play-btn-svg" points="9.33 6.69 9.33 19.39 19.3 13.04 9.33 6.69"/>
</svg>

After

Width:  |  Height:  |  Size: 153 B

View File

@@ -0,0 +1 @@
<%= fa_icon "circle fw", class: class_string('mr-2', 'text-danger' => broadcast.streamer_recording? && broadcast.active?) %>

View File

@@ -1,5 +1,5 @@
<% if broadcast.director_mode_video_embed.present? && params[:director_mode].present? %> <% if broadcast.director_mode_video_embed.present? && params[:non_director_mode].nil? %>
<div class="embed-responsive-item" data-video-type="stream"> <div id="director_broadcast_video" class="embed-responsive-item" data-video-type="stream">
<%= raw broadcast.director_mode_video_embed %> <%= raw broadcast.director_mode_video_embed %>
</div> </div>
<% elsif broadcast.streamer_recording? && broadcast.active? %> <% elsif broadcast.streamer_recording? && broadcast.active? %>
@@ -9,7 +9,7 @@
<table class="w-100 h-100 bg-secondary"> <table class="w-100 h-100 bg-secondary">
<tbody> <tbody>
<tr> <tr>
<td class="text-center align-middle text-white"> <td class="text-center align-middle text-white bg-black">
Video player will appear here when the stream becomes available. Video player will appear here when the stream becomes available.
</td> </td>
</tr> </tr>

View File

@@ -13,160 +13,164 @@
<% end %> <% end %>
<% end %> <% end %>
<style>
body {
overflow-x: hidden;
}
</style>
<% content_for :header do %> <% content_for :header do %>
<header class="container-fluid py-3 border-bottom sticky-top bg-light"> <header></header>
<div class="row align-items-center justify-content-center">
<div class="col-4 text-center">
<%= product_wordmark(:direct_me, class: 'navbar-brand') %>
</div>
</div>
</header>
<% end %> <% end %>
<div class="row"> <div class="row no-gutters m-n3">
<div class="col-lg-8 col-md-12 mb-3"> <div class="col-lg-9 col-md-12 bg-black vh-100">
<div class="card shadow-sm"> <div class="d-flex justify-content-start align-items-center flex-row p-3 mb-5 bg-dark">
<div class="card-header"> <%= product_wordmark(:direct_me, class: 'navbar-brand text-white') %>
<div class="d-flex justify-content-between align-items-center"> <div class="ml-4 dropdown">
<h1 class="h3 m-0"><%= @broadcast.name %></h1> <% if @multi_view_broadcasts.present? %>
<div class="dropdown"> <%= link_to "#", class: "btn btn-light dropdown-toggle text-white bg-black border-0 override-dropdown-show-state", role: "button", id: "dropdownMenuLink", data: { toggle: "dropdown" }, aria: { haspopup: "true", expanded: "false" } do %>
<%= link_to "Switch View", "#", class: "btn btn-light border dropdown-toggle", role: "button", id: "dropdownMenuLink", data: { toggle: "dropdown" }, aria: { haspopup: "true", expanded: "false" } %> <i class="fa fa-video-camera text-primary" aria-hidden="true"></i><span class="ml-2" id="selected_stream"><%= @broadcast.name %></span>
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink"> <% end %>
<h5 class="dropdown-header">Live Streams</h5> <% else %>
<%= link_to fa_icon("check", text: @broadcast.name.titleize), "#", data: { behavior: "play_stream"}, class: "dropdown-item active" %> <%= link_to "javascript:void(0);", class: "btn btn-light text-white bg-black border-0 override-dropdown-show-state", role: "button", id: "dropdownMenuLink", aria: { haspopup: "true", expanded: "false" } do %>
<% @multi_view_broadcasts.each do |broadcast| %> <i class="fa fa-video-camera text-primary" aria-hidden="true"></i><span class="ml-2" id="selected_stream"><%= @broadcast.name %></span>
<% if broadcast.id != @broadcast.id %> <% end %>
<%= link_to broadcast.name.titleize, broadcast.url, data: { behavior: "play_stream"}, class: class_string("dropdown-item", "active" => @broadcast.id == broadcast.id) %> <% end %>
<div class="dropdown-menu bg-black" aria-labelledby="dropdownMenuLink">
<%= link_to fa_icon("check", text: @broadcast.name.titleize), "#", data: { behavior: "play_stream"}, class: "dropdown-item active" %>
<% @multi_view_broadcasts.each do |broadcast| %>
<% if broadcast.id != @broadcast.id %>
<% if params[:non_director_mode] %>
<% if controller.class.module_parent.to_s == "Public" %>
<%= link_to broadcast.name.titleize, url_for(params.permit!.merge(non_director_mode: true, token: broadcast.token)), data: { behavior: "play_stream"}, class: class_string("dropdown-item", "active" => @broadcast.id == broadcast.id) %>
<% else %>
<%= link_to broadcast.name.titleize, url_for(params.permit!.merge(non_director_mode: true, id: broadcast.id)), data: { behavior: "play_stream"}, class: class_string("dropdown-item", "active" => @broadcast.id == broadcast.id) %>
<% end %>
<% else %>
<% if controller.class.module_parent.to_s == "Public" %>
<%= link_to broadcast.name.titleize, url_for(params.permit!.merge(token: broadcast.token).except(:non_director_mode)), data: { behavior: "play_stream"}, class: class_string("dropdown-item", "active" => @broadcast.id == broadcast.id) %>
<% else %>
<%= link_to broadcast.name.titleize, url_for(params.permit!.merge(id: broadcast.id).except(:non_director_mode)), data: { behavior: "play_stream"}, class: class_string("dropdown-item", "active" => @broadcast.id == broadcast.id) %>
<% end %> <% end %>
<% end %> <% end %>
<% if @broadcast.director_mode_video_embed.present? %>
<h5 class="dropdown-header">Director Mode</h5>
<% unless params[:director_mode] %>
<%= link_to "Enable Director Mode", url_for(params.permit!.merge(director_mode: true)), class: "dropdown-item" %>
<% else %>
<%= link_to "Disable Director Mode", url_for(params.permit!.except(:director_mode)), class: "dropdown-item" %>
<% end %>
<% end %>
<h5 class="dropdown-header">Previous Sessions</h5>
<div id="broadcast_recordings_nav">
<% if @recordings.any? %>
<%= render partial: "broadcasts/broadcast_recording_nav", collection: @recordings, as: :broadcast_recording %>
<% else %>
<p class="dropdown-item text-muted">Recordings will appear here</p>
<% end %>
</div>
</div>
</div>
</div>
</div>
<div class="card-body p-0">
<div class="embed-responsive embed-responsive-16by9">
<%= render partial: 'broadcasts/video', locals: { broadcast: @broadcast } %>
<% if @broadcast.streamer_recording? && @broadcast.active? %>
<%= javascript_tag nonce: true do %>
new Clappr.Player({
parentId: '#broadcast_video',
source: "<%= @broadcast.stream_playback_url %>",
width: '100%',
height: '100%',
mute: true,
autoPlay: true,
hlsMinimumDvrSize: 1
});
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
</div> </div>
<% if @broadcast.director_mode_video_embed.present? %>
<% if params[:non_director_mode] %>
<div class="custom-control custom-switch ml-auto">
<input type="checkbox" name="non_director_mode" value="true" class="custom-control-input" id="director_mode_switch" />
<label class="custom-control-label text-white override-custom-control-label" for="director_mode_switch">Director Mode</label>
</div>
<%= link_to "Enable Director Mode", url_for(params.permit!.except(:non_director_mode)), class: "d-none", id: "director_mode_link" %>
<% else %>
<div class="custom-control custom-switch ml-auto">
<input type="checkbox" name="non_director_mode" value="true" class="custom-control-input" id="director_mode_switch" checked="checked" />
<label class="custom-control-label text-white override-custom-control-label" for="director_mode_switch">Director Mode</label>
</div>
<%= link_to "Disable Director Mode", url_for(params.permit!.merge(non_director_mode: true)), class: "d-none", id: "director_mode_link" %>
<% end %>
<% end %>
</div>
<div class="embed-responsive embed-responsive-16by9" id="video_content">
<%= render partial: 'broadcasts/video', locals: { broadcast: @broadcast } %>
<% if @broadcast.streamer_recording? && @broadcast.active? %>
<%= javascript_tag nonce: true do %>
new Clappr.Player({
parentId: '#broadcast_video',
source: "<%= @broadcast.full_live_stream_playback_url %>",
width: '100%',
height: '100%',
mute: true,
autoPlay: true,
hlsMinimumDvrSize: 1
});
<% end %>
<% end %>
</div> </div>
</div> </div>
<div class="col-lg-4 col-md-12 mb-3"> <div class="col-lg-3 col-md-12 bg-white vh-100 overflow-auto">
<div class="card shadow-sm mb-3"> <div class="px-3 pt-3">
<div class="card-header"> <% unless controller.class.module_parent.to_s == "Public" %>
<ul class="nav nav-tabs card-header-tabs"> <% if @multi_view_broadcasts.present? %>
<li class="nav-item"> <% tokens = @multi_view_broadcasts.map(&:token) %>
<%= link_to "Home", "#home", class: class_string("nav-link", "active" => !params[:active_tab].present?), data: { toggle: "tab" } %> <div class="btn-group">
</li> <button type="button" class="btn btn-primary" id="broadcast_share_url" data-behavior="clipboard" href="<%= broadcast_url(@broadcast.token, multi_view_tokens: tokens) %>">Share URL</button>
<li class="nav-item"> <button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<%= link_to "Previous Sessions", "#recordings", class: class_string("nav-link", "active" => params[:active_tab] == "recordings"), data: { toggle: "tab" } %> <span class="sr-only">Toggle Dropdown</span>
</li> </button>
</ul> <div class="dropdown-menu">
</div> <%= link_to t('.actions.reset_url'), [@project, @broadcast], method: :patch, class: "dropdown-item" %>
<div class="card-body p-3">
<div class="tab-content">
<div class="<%= class_string("tab-pane fade show", "active" => !params[:active_tab].present?) %>" id="home">
<div id="broadcast_updates">
<%= render partial: 'broadcasts/broadcast_status', locals: { broadcast: @broadcast } %>
</div>
<% unless controller.class.module_parent.to_s == "Public" %>
<hr>
<div class="form-group">
<label for="broadcast_share_url">To share the stream, copy the URL below. Anyone with the link can view the stream.</label>
<div class="input-group">
<% if @multi_view_broadcasts.present? %>
<% tokens = @multi_view_broadcasts.map(&:token) %>
<input type="text" class="form-control" value="<%= broadcast_url(@broadcast.token, multi_view_tokens: tokens) %>" readonly>
<div class="input-group-append">
<button type="button" id="broadcast_share_url" class="btn btn-success" data-behavior="clipboard" href="<%= broadcast_url(@broadcast.token, multi_view_tokens: tokens) %>">
<i class="fa fa-clipboard"></i>
Copy URL
</button>
<%= link_to t('.actions.reset_url'), [@project, @broadcast], method: :patch, class: "btn btn-danger" %>
</div>
<% else %>
<input type="text" class="form-control" value="<%= broadcast_url(@broadcast.token) %>" readonly>
<div class="input-group-append">
<button type="button" id="broadcast_share_url" class="btn btn-success" data-behavior="clipboard" href="<%= broadcast_url(@broadcast.token) %>">
<i class="fa fa-clipboard"></i>
Copy URL
</button>
<%= link_to t('.actions.reset_url'), [@project, @broadcast], method: :patch, class: "btn btn-danger" %>
</div>
<% end %>
</div>
</div>
<hr>
<% end %>
<p class="card-text">If you want to join the ZOOM meeting dedicated to this broadcast, follow the link below.</p>
<%= link_to 'Video Conference', @conference_url, class: 'btn btn-primary btn-block', target: '_blank' %>
</div>
<div class="<%= class_string("tab-pane fade show", "active" => params[:active_tab] == 'recordings') %>" id="recordings">
<div id="broadcast_recordings">
<%= render partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast } %>
</div> </div>
</div> </div>
<% else %>
<div class="btn-group">
<button type="button" class="btn btn-primary" id="broadcast_share_url" data-behavior="clipboard" href="<%= broadcast_url(@broadcast.token) %>">Share URL</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu">
<%= link_to t('.actions.reset_url'), [@project, @broadcast], method: :patch, class: "dropdown-item" %>
</div>
</div>
<% end %>
<% end %>
<%= link_to 'Video Conference', @conference_url, class: 'btn btn-primary', target: '_blank' %>
</div>
<hr/>
<ul class="nav nav-tabs override-nav-tabs mb-3">
<li class="nav-item">
<%= link_to "Takes", "#recordings", class: class_string("nav-link", "active" => !params[:active_tab].present?), data: { toggle: "tab" } %>
</li>
<li class="nav-item">
<%= link_to "Files", "#files", class: class_string("nav-link", "active" => params[:active_tab] == "files"), data: { toggle: "tab" } %>
</li>
</ul>
<div class="tab-content">
<div class="<%= class_string("tab-pane fade show", "active" => !params[:active_tab].present?) %>" id="recordings">
<div id="live_take">
<%= render partial: 'broadcasts/live_take', locals: { broadcast: @broadcast } %>
</div>
<% if params[:non_director_mode] %>
<% if controller.class.module_parent.to_s == "Public" %>
<%= link_to "Play #{@broadcast.name.titleize}", url_for(params.permit!.merge(non_director_mode: true, token: @broadcast.token)), data: { behavior: "play_stream"}, class: "mt-2 btn btn-primary" %>
<% else %>
<%= link_to "Play #{@broadcast.name.titleize}", url_for(params.permit!.merge(non_director_mode: true, id: @broadcast.id)), data: { behavior: "play_stream"}, class: "mt-2 btn btn-primary" %>
<% end %>
<hr/>
<% else %>
<% if controller.class.module_parent.to_s == "Public" %>
<%= link_to "Play #{@broadcast.name.titleize}", url_for(params.permit!.merge(token: @broadcast.token).except(:non_director_mode)), data: { behavior: "play_stream"}, class: "mt-2 btn btn-primary" %>
<% else %>
<%= link_to "Play #{@broadcast.name.titleize}", url_for(params.permit!.merge(id: @broadcast.id).except(:non_director_mode)), data: { behavior: "play_stream"}, class: "mt-2 btn btn-primary" %>
<% end %>
<hr/>
<% end %>
<div id="broadcast_recordings">
<%= render partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast } %>
</div> </div>
</div> </div>
</div> <div class="<%= class_string("tab-pane fade show", "active" => params[:active_tab] == "files") %>" id="files">
<% if @multi_view_broadcasts.present? %>
<!-- files section --> <ul class="nav nav-tabs">
<div id="files" class="card shadow-sm mb-3">
<div class="card-header">
<h2 class="h5">Files</h2>
<% if @multi_view_broadcasts %>
<ul class="nav nav-tabs card-header-tabs">
<% @multi_view_broadcasts.each_with_index do |mvb, index| %> <% @multi_view_broadcasts.each_with_index do |mvb, index| %>
<li class="nav-item"> <li class="nav-item">
<%= link_to mvb.name, "#files_broadcast_#{mvb.token}", class: class_string("nav-link", "active" => (params[:active_files_tab] == mvb.token || (params[:active_files_tab].nil? && index == 0))), data: { toggle: "tab" } %> <%= link_to mvb.name, "#files_broadcast_#{mvb.token}", class: class_string("nav-link", "active" => (params[:active_files_tab] == mvb.token || (params[:active_files_tab].nil? && index == 0))), data: { toggle: "tab" } %>
</li> </li>
<% end %> <% end %>
</ul> </ul>
<% end %> <div class="tab-content">
</div>
<div class="card-body p-3">
<div class="tab-content">
<% if @multi_view_broadcasts.present? %>
<% @multi_view_broadcasts.each_with_index do |mvb, index| %> <% @multi_view_broadcasts.each_with_index do |mvb, index| %>
<div class="<%= class_string("tab-pane fade show", "active" => (params[:active_files_tab] == mvb.token || (params[:active_files_tab].nil? && index == 0))) %>" id="files_broadcast_<%= mvb.token %>"> <div class="<%= class_string("tab-pane fade show", "active" => (params[:active_files_tab] == mvb.token || (params[:active_files_tab].nil? && index == 0))) %>" id="files_broadcast_<%= mvb.token %>">
<%= render partial: 'broadcasts/files_section', locals: { broadcast: mvb, files: mvb.files } %> <%= render partial: 'broadcasts/files_section', locals: { broadcast: mvb, files: mvb.files } %>
</div> </div>
<% end %> <% end %>
<% else %> </div>
<div class="tab-pane fade show active" id="files_broadcast_<%= @broadcast.id %>"> <% else %>
<%= render partial: 'broadcasts/files_section', locals: { broadcast: @broadcast, files: @files } %> <%= render partial: 'broadcasts/files_section', locals: { broadcast: @broadcast, files: @files } %>
</div> <% end %>
<% end %>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -5,7 +5,7 @@
</td> </td>
<td> <td>
<% if contract_template.fee? %> <% if contract_template.fee? %>
<%= number_to_currency(contract_template.fee) %> <%= contract_template.fee %>
<% else %> <% else %>
<%= t(".no_fee") %> <%= t(".no_fee") %>
<% end %> <% end %>

View File

@@ -9,7 +9,7 @@
<%= form.radio_button :accessibility, :private_template, label: "Private" %> <%= form.radio_button :accessibility, :private_template, label: "Private" %>
</div> </div>
<div class="form-row" id="fee_field"> <div class="form-row" id="fee_field">
<%= form.number_field :fee, min:"0", max:"99999999", step: "0.01", prepend: "$", wrapper_class: "col-sm-6" %> <%= form.text_field :fee, wrapper_class: "col-sm-6" %>
</div> </div>
<% end %> <% end %>

View File

@@ -0,0 +1,37 @@
<% has_logo = local_assigns[:logo] %>
<% has_user_photo = releasable.model_name == "AppearanceRelease" && releasable.person_photo.attached? %>
<% if has_logo || has_user_photo %>
<table class="heading-table">
<tr>
<td>
<% if has_logo %>
<div class="logo">
<%= render "blank_contracts/logo", logo: logo %>
</div>
<% end %>
</td>
<td class="embed-person-photo">
<% if has_user_photo %>
<%= image_tag releasable.photos.first.variant(auto_orient: true, resize: "200x200"), id: "top-person-photo" %>
<% end %>
</td>
</tr>
</table>
<hr>
<% end %>
<% if preview %>
<h1>PREVIEW ONLY</h1>
<% end %>
<% if contract_template.body.present? %>
<%= contract_template.body %>
<br/>
<% end %>
<% if releasable.minor? && contract_template.guardian_clause.present? %>
<p class="text-left"><strong>Guardian Clause</strong></p>
<%= contract_template.guardian_clause %>
<% end %>

View File

@@ -36,7 +36,7 @@
<%= description_list_pair "Filming Hours:", releasable&.filming_hours %> <%= description_list_pair "Filming Hours:", releasable&.filming_hours %>
<% end %> <% end %>
<% if contract_template.fee? %> <% if contract_template.fee? %>
<%= description_list_pair "Fee:", number_to_currency(contract_template.fee) %> <%= description_list_pair "Fee:", contract_template.fee %>
<% end %> <% end %>
<% if releasable.model_name == "MaterialRelease" %> <% if releasable.model_name == "MaterialRelease" %>
<%= description_list_pair "Description:", releasable.description %> <%= description_list_pair "Description:", releasable.description %>

View File

@@ -1,22 +1,13 @@
<% if local_assigns[:logo] %> <% logo = local_assigns[:logo] ? local_assigns[:logo] : nil %>
<div class="logo">
<%= render "contracts/logo", logo: logo %> <% if logo || (releasable.model_name == 'AppearanceRelease' && releasable.person_photo.attached?) ||
contract_template.body.present? || (releasable.minor? && contract_template.guardian_clause.present?) %>
<div class="page">
<%= render "contracts/logo_page", logo: logo, preview: preview, releasable: releasable, contract_template: contract_template %>
</div> </div>
<hr>
<% end %>
<% if preview %>
<h1>PREVIEW ONLY</h1>
<% end %>
<% if contract_template.body.present? %>
<%= contract_template.body %>
<br/>
<% end %>
<% if releasable.minor? && contract_template.guardian_clause.present? %>
<p class="text-left"><strong>Guardian Clause</strong></p>
<%= contract_template.guardian_clause %>
<% end %> <% end %>
<% if releasable.respond_to?(:question_1_answer) %> <% if contract_template.present? && contract_template.has_questionnaire? %>
<div class="page"> <div class="page">
<%= render "contracts/questionnaire", releasable: releasable, contract_template: contract_template, preview: preview %> <%= render "contracts/questionnaire", releasable: releasable, contract_template: contract_template, preview: preview %>
</div> </div>
@@ -52,7 +43,7 @@
</div> </div>
<% end %> <% end %>
<% if releasable.class == AcquiredMediaRelease %> <% if releasable.respond_to?(:image_files) %>
<div class="page"> <div class="page">
<%= render "contracts/files", release: releasable, preview: preview %> <%= render "contracts/files", release: releasable, preview: preview %>
</div> </div>

View File

@@ -17,12 +17,12 @@
</head> </head>
<body> <body>
<div class="flash-message">
<%= render "flash" %>
</div>
<%= content_for?(:header) ? yield(:header) : render("header") %> <%= content_for?(:header) ? yield(:header) : render("header") %>
<%= render "masquerade" if masquerading? %> <%= render "masquerade" if masquerading? %>
<main class="container-fluid py-3"> <main class="container-fluid py-3">
<div class="flash-message"></div>
<%= render "flash" %>
</div>
<%= content_for?(:content) ? yield(:content) : yield %> <%= content_for?(:content) ? yield(:content) : yield %>
</main> </main>
</body> </body>

View File

@@ -1,8 +1,11 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<input id="total_entries" type=hidden value=<%= @location_releases.total_entries %> />
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3"> <div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3">
<% if policy(LocationRelease).new? %> <% if policy(LocationRelease).new? %>
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, @project, :location_release], class: "btn btn-primary mr-2 mb-2" %> <div class="mr-auto">
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, @project, :location_release], class: "btn btn-primary mr-2 mb-2" %>
</div>
<% end %> <% end %>
<% if @location_releases.any? && policy(LocationRelease).tag_multiple? %> <% if @location_releases.any? && policy(LocationRelease).tag_multiple? %>
@@ -10,7 +13,7 @@
<% end %> <% end %>
<% if @location_releases.any? && policy(LocationRelease).download_multiple? %> <% if @location_releases.any? && policy(LocationRelease).download_multiple? %>
<%= link_to "Download All", [@project, :contract_downloads, release_type: @location_releases.name], method: :post, remote: true, class: "btn btn-light border ml-auto mr-2 mb-2", data: { <%= button_to "Download", [@project, :contract_downloads, release_type: @location_releases.name], id: "download_releases", method: :post, remote: true, class: "btn btn-light border mr-2 mb-2", data: {
disable_with: "Please wait..." } %> disable_with: "Please wait..." } %>
<% end %> <% end %>

View File

@@ -1,3 +1,5 @@
$("#location_releases").html("<%= j render(@location_releases) %>"); $("#location_releases").html("<%= j render(@location_releases) %>");
$("form input[type='search']").val("<%= params[:query] %>"); $("form input[type='search']").val("<%= params[:query] %>");
$("#location_releases_pagination").html("<%= j will_paginate(@location_releases) %>"); $("#location_releases_pagination").html("<%= j will_paginate(@location_releases) %>");
$("#selected_releases_form").attr('data-releasable-ids', JSON.stringify([]));
$("#total_entries").val(<%= @location_releases.total_entries %>);

View File

@@ -0,0 +1 @@
<p><%= t '.account_locked_message' %></p>

View File

@@ -57,8 +57,8 @@
<hr> <hr>
<%= field_set_tag content_tag(:span, t(".photos.heading"), class: "h6 text-muted text-uppercase") do %> <%= field_set_tag content_tag(:span, t(".files.heading"), class: "h6 text-muted text-uppercase") do %>
<%= render "shared/photos_dropzone_fields", form: form, release: material_release %> <%= render "shared/releasable_files_dropzone", form: form, releasable: material_release %>
<div class="<%= class_string("collapse" => !material_release.minor?) %>" data-ujs-target="guardian-fields"> <div class="<%= class_string("collapse" => !material_release.minor?) %>" data-ujs-target="guardian-fields">
<br> <br>

View File

@@ -9,10 +9,10 @@
<% end %> <% end %>
</td> </td>
<td> <td>
<% if material_release.photo.attached? %> <% if material_release.files.any? %>
<%= image_tag medium_variant(material_release.photo), class: "img-fluid" %> <%= material_release.files.size %>
<% else %> <% else %>
<%= fa_icon("warning", text: t(".no_photos"), class: "text-danger") %> <%= fa_icon("warning", text: t(".no_media"), class: "text-danger") %>
<% end %> <% end %>
</td> </td>
<td> <td>
@@ -41,8 +41,8 @@
<% if policy(material_release.tags).new? %> <% if policy(material_release.tags).new? %>
<%= link_to fa_icon("tags fw", text: "Tags"), [:new, material_release, :acts_as_taggable_on_tag], class: "dropdown-item", remote: true %> <%= link_to fa_icon("tags fw", text: "Tags"), [:new, material_release, :acts_as_taggable_on_tag], class: "dropdown-item", remote: true %>
<% end %> <% end %>
<% if policy(material_release).edit_photos? %> <% if policy(material_release).edit_files? %>
<%= link_to fa_icon("picture-o fw", text: "Photos"), [:edit, material_release, :photos], class: "dropdown-item" %> <%= link_to fa_icon("file-o fw", text: "Media"), [:edit, material_release, :files], class: "dropdown-item" %>
<% end %> <% end %>
<% if policy(Contract).show? && (material_release.contract.attached? || material_release.contract_template.present?) %> <% if policy(Contract).show? && (material_release.contract.attached? || material_release.contract_template.present?) %>
<%= link_to fa_icon("download fw", text: "Download"), [material_release, :contracts, format: "pdf"], class: "dropdown-item", target: "_blank" %> <%= link_to fa_icon("download fw", text: "Download"), [material_release, :contracts, format: "pdf"], class: "dropdown-item", target: "_blank" %>

View File

@@ -1,8 +1,11 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<input id="total_entries" type=hidden value=<%= @material_releases.total_entries %> />
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3"> <div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3">
<% if policy(MaterialRelease).new? %> <% if policy(MaterialRelease).new? %>
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, @project, :material_release], class: "btn btn-primary mr-2 mb-2" %> <div class="mr-auto">
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, @project, :material_release], class: "btn btn-primary mr-2 mb-2" %>
</div>
<% end %> <% end %>
<% if @material_releases.any? && policy(MaterialRelease).tag_multiple? %> <% if @material_releases.any? && policy(MaterialRelease).tag_multiple? %>
@@ -10,7 +13,7 @@
<% end %> <% end %>
<% if @material_releases.any? && policy(MaterialRelease).download_multiple? %> <% if @material_releases.any? && policy(MaterialRelease).download_multiple? %>
<%= link_to "Download All", [@project, :contract_downloads, release_type: @material_releases.name], method: :post, remote: true, class: "btn btn-light border ml-auto mr-2 mb-2", data: { <%= button_to "Download", [@project, :contract_downloads, release_type: @material_releases.name], id: "download_releases", method: :post, remote: true, class: "btn btn-light border mr-2 mb-2", data: {
disable_with: "Please wait..." } %> disable_with: "Please wait..." } %>
<% end %> <% end %>
@@ -27,7 +30,7 @@
<tr> <tr>
<th data-behavior="all-selectable"><%= check_box_tag "material_release_ids[]", false, false %></th> <th data-behavior="all-selectable"><%= check_box_tag "material_release_ids[]", false, false %></th>
<th><%= t '.table_headers.approved'%></th> <th><%= t '.table_headers.approved'%></th>
<th></th> <th><%= t(".table_headers.files_count") %></th>
<th><%= MaterialRelease.human_attribute_name(:name) %></th> <th><%= MaterialRelease.human_attribute_name(:name) %></th>
<th><%= t(".table_headers.owner_info") %> <th><%= t(".table_headers.owner_info") %>
<th><%= t(".table_headers.notes") %></th> <th><%= t(".table_headers.notes") %></th>

View File

@@ -1,3 +1,5 @@
$("#material_releases").html("<%= j render(@material_releases) %>"); $("#material_releases").html("<%= j render(@material_releases) %>");
$("form input[type='search']").val("<%= params[:query] %>"); $("form input[type='search']").val("<%= params[:query] %>");
$("#material_releases_pagination").html("<%= j will_paginate(@material_releases) %>"); $("#material_releases_pagination").html("<%= j will_paginate(@material_releases) %>");
$("#selected_releases_form").attr('data-releasable-ids', JSON.stringify([]));
$("#total_entries").val(<%= @material_releases.total_entries %>);

View File

@@ -1,12 +1,15 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<input id="total_entries" type=hidden value=<%= @medical_releases.total_entries %> />
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3"> <div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3">
<% if @medical_releases.any? && policy(MedicalRelease).tag_multiple? %> <% if @medical_releases.any? && policy(MedicalRelease).tag_multiple? %>
<%= button_to_bulk_tagging(@project) %> <div class="ml-auto">
<%= button_to_bulk_tagging(@project) %>
</div>
<% end %> <% end %>
<% if @medical_releases.any? && policy(MedicalRelease).download_multiple? %> <% if @medical_releases.any? && policy(MedicalRelease).download_multiple? %>
<%= link_to "Download All", [@project, :contract_downloads, release_type: @medical_releases.name], method: :post, remote: true, class: "btn btn-light border ml-auto mr-2 mb-2", data: { <%= button_to "Download", [@project, :contract_downloads, release_type: @medical_releases.name], id: "download_releases", method: :post, remote: true, class: "btn btn-light border mr-2 mb-2", data: {
disable_with: "Please wait..." } %> disable_with: "Please wait..." } %>
<% end %> <% end %>

View File

@@ -1,3 +1,5 @@
$("#medical_releases").html("<%= j render(@medical_releases) %>"); $("#medical_releases").html("<%= j render(@medical_releases) %>");
$("form input[type='search']").val("<%= params[:query] %>"); $("form input[type='search']").val("<%= params[:query] %>");
$("#medical_releases_pagination").html("<%= j will_paginate(@medical_releases) %>"); $("#medical_releases_pagination").html("<%= j will_paginate(@medical_releases) %>");
$("#selected_releases_form").attr('data-releasable-ids', JSON.stringify([]));
$("#total_entries").val(<%= @medical_releases.total_entries %>);

View File

@@ -1,12 +1,15 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<input id="total_entries" type=hidden value=<%= @misc_releases.total_entries %> />
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3"> <div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3">
<% if @misc_releases.any? && policy(MiscRelease).tag_multiple? %> <% if @misc_releases.any? && policy(MiscRelease).tag_multiple? %>
<%= button_to_bulk_tagging(@project) %> <div class="ml-auto">
<%= button_to_bulk_tagging(@project) %>
</div>
<% end %> <% end %>
<% if @misc_releases.any? && policy(MiscRelease).download_multiple? %> <% if @misc_releases.any? && policy(MiscRelease).download_multiple? %>
<%= link_to "Download All", [@project, :contract_downloads, release_type: @misc_releases.name], method: :post, remote: true, class: "btn btn-light border ml-auto mr-2 mb-2", data: { <%= button_to "Download", [@project, :contract_downloads, release_type: @misc_releases.name], id: "download_releases", method: :post, remote: true, class: "btn btn-light border mr-2 mb-2", data: {
disable_with: "Please wait..." } %> disable_with: "Please wait..." } %>
<% end %> <% end %>

View File

@@ -1,3 +1,5 @@
$("#misc_releases").html("<%= j render(@misc_releases) %>"); $("#misc_releases").html("<%= j render(@misc_releases) %>");
$("form input[type='search']").val("<%= params[:query] %>"); $("form input[type='search']").val("<%= params[:query] %>");
$("#misc_releases_pagination").html("<%= j will_paginate(@misc_releases) %>"); $("#misc_releases_pagination").html("<%= j will_paginate(@misc_releases) %>");
$("#selected_releases_form").attr('data-releasable-ids', JSON.stringify([]));
$("#total_entries").val(<%= @misc_releases.total_entries %>);

View File

@@ -1,8 +1,11 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<input id="total_entries" type=hidden value=<%= @music_releases.total_entries %> />
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3"> <div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3">
<% if policy(MusicRelease).new? %> <% if policy(MusicRelease).new? %>
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, @project, :music_release], class: "btn btn-primary mr-2 mb-2" %> <div class="mr-auto">
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, @project, :music_release], class: "btn btn-primary mr-2 mb-2" %>
</div>
<% end %> <% end %>
<% if @music_releases.any? && policy(MusicRelease).tag_multiple? %> <% if @music_releases.any? && policy(MusicRelease).tag_multiple? %>
@@ -10,7 +13,7 @@
<% end %> <% end %>
<% if @music_releases.any? && policy(MusicRelease).download_multiple? %> <% if @music_releases.any? && policy(MusicRelease).download_multiple? %>
<%= link_to "Download All", [@project, :contract_downloads, release_type: @music_releases.name], method: :post, remote: true, class: "btn btn-light border ml-auto mr-2 mb-2" %> <%= button_to "Download", [@project, :contract_downloads, release_type: @music_releases.name], id: "download_releases", method: :post, remote: true, class: "btn btn-light border mr-2 mb-2" %>
<% end %> <% end %>
<%= bootstrap_form_with url: [@project, :music_releases], method: :get, remote: true, layout: :inline, id: "search" do |form| %> <%= bootstrap_form_with url: [@project, :music_releases], method: :get, remote: true, layout: :inline, id: "search" do |form| %>

View File

@@ -1,3 +1,5 @@
$("#music_releases").html("<%= j render(@music_releases) %>"); $("#music_releases").html("<%= j render(@music_releases) %>");
$("form input[type='search']").val("<%= params[:query] %>"); $("form input[type='search']").val("<%= params[:query] %>");
$("#music_releases_pagination").html("<%= j will_paginate(@music_releases) %>"); $("#music_releases_pagination").html("<%= j will_paginate(@music_releases) %>");
$("#selected_releases_form").attr('data-releasable-ids', JSON.stringify([]));
$("#total_entries").val(<%= @music_releases.total_entries %>);

View File

@@ -0,0 +1,45 @@
<div>
<div id="playerDiv"></div>
<script type="text/javascript" src="https://demo.nanocosmos.de/nanoplayer/api/release/nanoplayer.4.min.js"></script>
<%= javascript_tag nonce: true do %>
var urlParams = new URLSearchParams(window.location.search);
var streamName = urlParams.get('stream_name');
console.log("streamName", streamName);
var player;
var config = {
"source": {
"entries": [
{
"h5live": {
// your rtmp stream
"rtmp": {
"url": "rtmp://bintu-play.nanocosmos.de/play",
"streamname": streamName,
},
"server": {
"websocket": "wss://bintu-h5live.nanocosmos.de:443/h5live/stream.mp4",
"hls": "https://bintu-h5live.nanocosmos.de:443/h5live/http/playlist.m3u8",
"progressive": "https://bintu-h5live.nanocosmos.de:443/h5live/http/stream.mp4"
}
}
}
]
},
"style": {
"width": "auto",
}
};
function initPlayer() {
player = new NanoPlayer('playerDiv');
player.setup(config).then(function (config) {
console.log('setup ok with config: ' + JSON.stringify(config));
}, function (error) {
console.log(error);
});
}
// load player from playerDiv
document.addEventListener('DOMContentLoaded', function () {
initPlayer();
});
<% end %>
</div>

View File

@@ -6,7 +6,7 @@
<p><%= @contract_template.body %></p> <p><%= @contract_template.body %></p>
<% if @contract_template.fee? %> <% if @contract_template.fee? %>
<p> <p>
Fee <span class="font-weight-bold text-success"><%= number_to_currency @contract_template.fee %></span> Fee <span class="font-weight-bold text-success"><%= @contract_template.fee %></span>
</p> </p>
<% end %> <% end %>
<% end %> <% end %>

View File

@@ -7,7 +7,7 @@
<p><%= @contract_template.body %></p> <p><%= @contract_template.body %></p>
<% if @contract_template.fee? %> <% if @contract_template.fee? %>
<p> <p>
Fee <span class="font-weight-bold text-success"><%= number_to_currency @contract_template.fee %></span> Fee <span class="font-weight-bold text-success"><%= @contract_template.fee %></span>
</p> </p>
<% end %> <% end %>
<% end %> <% end %>

View File

@@ -0,0 +1 @@
$("#broadcast_recordings").html("<%= j render(partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast }) %>");

View File

@@ -0,0 +1,24 @@
<%= content_tag :div, class: "modal modal-right", id: "edit_broadcast_recording_modal", aria: { labelledby: "modalLabel", hidden: true }, role: "dialog", tabindex: -1 do %>
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalLabel">Edit Broadcast Recording</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<%= bootstrap_form_with model: [broadcast, recording], url: broadcast_broadcast_recording_path(broadcast.token, recording), layout: :horizontal, label_col: "col-3", control_col: "col-9" do |form| %>
<div class="modal-body">
<div id="broadcast_recording_fields">
<%= form.text_field :name %>
<%= form.text_area :description %>
</div>
</div>
<div class="modal-footer">
<%= form.button "Close", class: "btn btn-secondary", data: { dismiss: "modal" } %>
<%= form.submit "Update Broadcast Recording", class: "btn btn-primary", data: { disable_with: t("shared.disable_with") } %>
</div>
<% end %>
</div>
</div>
<% end %>

View File

@@ -0,0 +1,11 @@
$('[data-id="<%= dom_id(@recording) %>"]').remove();
<% if @recordings.empty? %>
$("#broadcast_recordings_nav").append('<p class="dropdown-item text-muted">Recordings will appear here</p>')
<% end %>
$("#broadcast_recordings").html("<%= j render(partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast }) %>");
// Close and remove the modal
$("#edit_broadcast_recording_modal").on("hidden.bs.modal", function (e) {
$("#edit_broadcast_recording_modal").remove();
});
$("#edit_broadcast_recording_modal").modal("hide");

View File

@@ -0,0 +1,6 @@
<% # Remove the modal if it already exists %>
$("#edit_broadcast_recording_modal").remove();
<% # Create and show the modal %>
$("body").append("<%= j render(partial: 'edit_broadcast_recording_modal', locals: { broadcast: @broadcast, recording: @recording }) %>");
$("#edit_broadcast_recording_modal").modal("toggle");

View File

@@ -0,0 +1 @@
<%= render("public/broadcast_recordings/refresh_recordings_list") %>

View File

@@ -6,7 +6,7 @@
<p><%= @contract_template.body %></p> <p><%= @contract_template.body %></p>
<% if @contract_template.fee? %> <% if @contract_template.fee? %>
<p> <p>
Fee <span class="font-weight-bold text-success"><%= number_to_currency @contract_template.fee %></span> Fee <span class="font-weight-bold text-success"><%= @contract_template.fee %></span>
</p> </p>
<% end %> <% end %>
<% end %> <% end %>

View File

@@ -6,7 +6,7 @@
<p><%= @contract_template.body %></p> <p><%= @contract_template.body %></p>
<% if @contract_template.fee? %> <% if @contract_template.fee? %>
<p> <p>
Fee <span class="font-weight-bold text-success"><%= number_to_currency @contract_template.fee %></span> Fee <span class="font-weight-bold text-success"><%= @contract_template.fee %></span>
</p> </p>
<% end %> <% end %>
<% end %> <% end %>
@@ -45,8 +45,8 @@
<%= render "shared/address_fields", form: form, subject: "person", required: true %> <%= render "shared/address_fields", form: form, subject: "person", required: true %>
<% end %> <% end %>
<%= card_field_set_tag t(".photo.heading") do %> <%= card_field_set_tag t(".files.heading") do %>
<%= render "shared/photos_dropzone_fields", form: form, release: @material_release %> <%= render "shared/releasable_files_dropzone", form: form, releasable: @material_release %>
<% end %> <% end %>
<hr> <hr>

View File

@@ -7,7 +7,7 @@
<%= @contract_template.body %> <%= @contract_template.body %>
<% if @contract_template.fee? %> <% if @contract_template.fee? %>
<p> <p>
Fee <span class="font-weight-bold text-success"><%= number_to_currency @contract_template.fee %></span> Fee <span class="font-weight-bold text-success"><%= @contract_template.fee %></span>
</p> </p>
<% end %> <% end %>
<% end %> <% end %>

View File

@@ -7,7 +7,7 @@
<p><%= @contract_template.body %></p> <p><%= @contract_template.body %></p>
<% if @contract_template.fee? %> <% if @contract_template.fee? %>
<p> <p>
Fee <span class="font-weight-bold text-success"><%= number_to_currency @contract_template.fee %></span> Fee <span class="font-weight-bold text-success"><%= @contract_template.fee %></span>
</p> </p>
<% end %> <% end %>
<% end %> <% end %>

View File

@@ -14,4 +14,5 @@
data-file-input-id="releasable_files" data-file-input-id="releasable_files"
data-existing-files="<%= mock_photos_json(releasable.files) %>" data-existing-files="<%= mock_photos_json(releasable.files) %>"
data-placeholder="<%= dropzone_placeholder_message_for(releasable) %>" data-placeholder="<%= dropzone_placeholder_message_for(releasable) %>"
data-submit-button="#submit_folder"></div> data-submit-button="#submit_folder"
data-max-file-size="<%= dropzone_file_size_limit_for(releasable) %>"></div>

View File

@@ -1,8 +1,11 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<input id="total_entries" type=hidden value=<%= @talent_releases.total_entries %> />
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3"> <div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3">
<% if policy(TalentRelease).new? %> <% if policy(TalentRelease).new? %>
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, @project, :talent_release], class: "btn btn-primary mr-2 mb-2" %> <div class="mr-auto">
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, @project, :talent_release], class: "btn btn-primary mr-2 mb-2" %>
</div>
<% end %> <% end %>
<% if @talent_releases.any? && policy(TalentRelease).tag_multiple? %> <% if @talent_releases.any? && policy(TalentRelease).tag_multiple? %>
@@ -10,7 +13,7 @@
<% end %> <% end %>
<% if @talent_releases.any? && policy(TalentRelease).download_multiple? %> <% if @talent_releases.any? && policy(TalentRelease).download_multiple? %>
<%= link_to "Download All", [@project, :contract_downloads, release_type: @talent_releases.name], method: :post, remote: true, class: "btn btn-light border ml-auto mr-2 mb-2", data: { <%= button_to "Download", [@project, :contract_downloads, release_type: @talent_releases.name], id: "download_releases", method: :post, remote: true, class: "btn btn-light border mr-2 mb-2", data: {
disable_with: "Please wait..." } %> disable_with: "Please wait..." } %>
<% end %> <% end %>

Some files were not shown because too many files have changed in this diff Show More