Compare commits

..

2 Commits

Author SHA1 Message Date
Bilal
3eb03168f2 add Underline button to the trix editor 2020-09-07 18:09:45 +03:00
Senad Uka
e5ac3e9345 Upstream sync 2020-09-06 21:42:50 +02:00
18 changed files with 163 additions and 32 deletions

View File

@@ -1,8 +1,4 @@
$(document).on("click", "[data-behavior=play_recording]", function() { $(document).on("click", "[data-behavior=play_recording]", function() {
if ($(this).hasClass('active')){
return false;
}
$("#broadcast_video").data('videoType', 'recording'); $("#broadcast_video").data('videoType', 'recording');
var playback_url = $(this).attr("data-playback-url") var playback_url = $(this).attr("data-playback-url")
@@ -16,13 +12,6 @@ $(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() { $("#broadcast_video").data('videoType', 'stream'); });

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

@@ -461,3 +461,10 @@ a[data-behavior=seekable-timecode] {
border-color: transparent; border-color: transparent;
border-bottom: 3px solid #ff0000; 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");
}
}

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

@@ -12,10 +12,10 @@ class BroadcastRecordingPolicy < ApplicationPolicy
end end
def edit? def edit?
destroy? true
end end
def update? def update?
edit? true
end end
end end

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

@@ -3,12 +3,12 @@
<% recordings.each do |recording| %> <% recordings.each do |recording| %>
<div class="list-group-item list-group-item-action"> <div class="list-group-item list-group-item-action">
<div class="d-flex align-items-start"> <div class="d-flex align-items-start">
<% if (controller.class.module_parent.to_s != "Public" && policy(BroadcastRecording).update?) %> <% if policy(BroadcastRecording).update? %>
<%= link_to fa_icon("#{recording.starred ? 'star' : 'star-o'} fw"), [broadcast.project, broadcast, recording, :broadcast_recording_starrings], method: :post, class: "text-warning mr-3", remote: true %> <%= link_to fa_icon("#{recording.starred ? 'star' : 'star-o'} fw"), [broadcast.project, broadcast, recording, :broadcast_recording_starrings], method: :post, class: "text-warning mr-3", remote: true %>
<% end %> <% end %>
<%= image_tag(recording.thumbnail_url, class: 'img-thumbnail img-fluid max-w-75') %> <%= image_tag(recording.thumbnail_url, class: 'img-thumbnail img-fluid max-w-75', data: { behavior: "play_recording", playback_url: recording.playback_url, id: dom_id(recording) }) %>
<div class="ml-auto"> <div class="ml-auto">
<% if (controller.class.module_parent.to_s != "Public" && policy(BroadcastRecording).edit?) %> <% if policy(BroadcastRecording).edit? %>
<%= link_to fa_icon('edit'), [:edit, broadcast.project, broadcast, recording], remote: true %> <%= link_to fa_icon('edit'), [:edit, broadcast.project, broadcast, recording], remote: true %>
<% end %> <% end %>
<%= link_to(fa_icon('download'), recording.download_url, target: "_blank") %> <%= link_to(fa_icon('download'), recording.download_url, target: "_blank") %>

View File

@@ -9,4 +9,4 @@
</div> </div>
</div> </div>
</div> </div>
<hr/>

View File

@@ -22,11 +22,16 @@
<div class="d-flex justify-content-start align-items-center flex-row p-3 mb-5 bg-dark"> <div class="d-flex justify-content-start align-items-center flex-row p-3 mb-5 bg-dark">
<%= product_wordmark(:direct_me, class: 'navbar-brand text-white') %> <%= product_wordmark(:direct_me, class: 'navbar-brand text-white') %>
<div class="ml-4 dropdown"> <div class="ml-4 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 %> <% if @multi_view_broadcasts.present? %>
<i class="fa fa-video-camera text-primary" aria-hidden="true"></i><span class="ml-2" id="selected_stream"><%= @broadcast.name %></span> <%= 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 %>
<i class="fa fa-video-camera text-primary" aria-hidden="true"></i><span class="ml-2" id="selected_stream"><%= @broadcast.name %></span>
<% end %>
<% else %>
<%= 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 %>
<i class="fa fa-video-camera text-primary" aria-hidden="true"></i><span class="ml-2" id="selected_stream"><%= @broadcast.name %></span>
<% end %>
<% end %> <% end %>
<div class="dropdown-menu bg-black" aria-labelledby="dropdownMenuLink"> <div class="dropdown-menu bg-black" aria-labelledby="dropdownMenuLink">
<h5 class="dropdown-header">Live Streams</h5>
<%= link_to fa_icon("check", text: @broadcast.name.titleize), "#", data: { behavior: "play_stream"}, class: "dropdown-item active" %> <%= link_to fa_icon("check", text: @broadcast.name.titleize), "#", data: { behavior: "play_stream"}, class: "dropdown-item active" %>
<% @multi_view_broadcasts.each do |broadcast| %> <% @multi_view_broadcasts.each do |broadcast| %>
<% if broadcast.id != @broadcast.id %> <% if broadcast.id != @broadcast.id %>
@@ -120,6 +125,21 @@
<div id="live_take"> <div id="live_take">
<%= render partial: 'broadcasts/live_take', locals: { broadcast: @broadcast } %> <%= render partial: 'broadcasts/live_take', locals: { broadcast: @broadcast } %>
</div> </div>
<% if params[:director_mode] %>
<% if controller.class.module_parent.to_s == "Public" %>
<%= link_to "Play #{@broadcast.name.titleize}", url_for(params.permit!.merge(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(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(: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(:director_mode)), data: { behavior: "play_stream"}, class: "mt-2 btn btn-primary" %>
<% end %>
<hr/>
<% end %>
<div id="broadcast_recordings"> <div id="broadcast_recordings">
<%= render partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast } %> <%= render partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast } %>
</div> </div>

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

@@ -9,12 +9,12 @@ Rails.application.config.content_security_policy do |policy|
policy.font_src :self, :https, :data policy.font_src :self, :https, :data
policy.img_src :self, :https, :data policy.img_src :self, :https, :data
policy.object_src :self policy.object_src :self
policy.script_src :self, :https, AppHost.new.domain_with_port, "https://stream.mux.com", :blob, :unsafe_eval policy.script_src :self, :https, AppHost.new.domain_with_port, "https://stream.mux.com", "https://demo.nanocosmos.de", :blob, :unsafe_eval
policy.media_src :self, :https, AppHost.new.domain_with_port, "https://stream.mux.com", :data, :blob policy.media_src :self, :https, AppHost.new.domain_with_port, "https://stream.mux.com", :data, :blob
# policy.style_src :self, :https, :unsafe_inline # policy.style_src :self, :https, :unsafe_inline
# If you are using webpack-dev-server then specify webpack-dev-server host # If you are using webpack-dev-server then specify webpack-dev-server host
# policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development? # policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
policy.connect_src :self, :https, "ws://#{AppHost.new.domain_with_port}", "wss://#{AppHost.new.domain_with_port}" policy.connect_src :self, :https, "ws://#{AppHost.new.domain_with_port}", "wss://#{AppHost.new.domain_with_port}", "wss://bintu-h5live.nanocosmos.de"
# Specify URI for violation reports # Specify URI for violation reports
# policy.report_uri "/csp-violation-report-endpoint" # policy.report_uri "/csp-violation-report-endpoint"

View File

@@ -200,6 +200,7 @@ Rails.application.routes.draw do
get "cookies_disabled" => 'pages#show', id: "cookies_disabled", as: :cookies_disabled get "cookies_disabled" => 'pages#show', id: "cookies_disabled", as: :cookies_disabled
get "accountless_user" => 'pages#show', id: "accountless_user", as: :accountless_user get "accountless_user" => 'pages#show', id: "accountless_user", as: :accountless_user
get "nanocosmos_player" => 'pages#show', id: "nanocosmos_player", as: :nanocosmos_player
resource :session, only: [:new, :create] resource :session, only: [:new, :create]
resources :password_resets, only: [:new, :create, :edit, :update] resources :password_resets, only: [:new, :create, :edit, :update]

View File

@@ -542,9 +542,9 @@ CREATE TABLE public.broadcast_recordings (
updated_at timestamp(6) without time zone NOT NULL, updated_at timestamp(6) without time zone NOT NULL,
duration double precision, duration double precision,
hidden boolean DEFAULT false, hidden boolean DEFAULT false,
starred boolean DEFAULT false,
name character varying, name character varying,
description text, description text
starred boolean DEFAULT false
); );
@@ -1492,7 +1492,6 @@ CREATE TABLE public.settings (
-- --
CREATE SEQUENCE public.settings_id_seq CREATE SEQUENCE public.settings_id_seq
AS integer
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
NO MINVALUE NO MINVALUE
@@ -1528,7 +1527,6 @@ CREATE TABLE public.taggings (
-- --
CREATE SEQUENCE public.taggings_id_seq CREATE SEQUENCE public.taggings_id_seq
AS integer
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
NO MINVALUE NO MINVALUE
@@ -1559,7 +1557,6 @@ CREATE TABLE public.tags (
-- --
CREATE SEQUENCE public.tags_id_seq CREATE SEQUENCE public.tags_id_seq
AS integer
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
NO MINVALUE NO MINVALUE

View File

@@ -30,6 +30,16 @@ RSpec.describe Api::AcquiredMediaReleasesController, type: :controller do
expect(response).to be_successful expect(response).to be_successful
end end
it 'contains files attachment data' do
tested_release = create(:acquired_media_release, name: 'ct1', project_id: project.id)
sign_in_to_api(current_user)
get :show, params: { id: tested_release.id }
expect(response.body).to match /file_infos/
expect(response.body).to match /files/
end
end end
describe '#create' do describe '#create' do

View File

@@ -14,6 +14,8 @@ RSpec.describe Api::ProfilesController, type: :controller do
expect(response).to be_successful expect(response).to be_successful
expect(response_body_data).to include('id' => current_user.to_param, 'type' => 'user') expect(response_body_data).to include('id' => current_user.to_param, 'type' => 'user')
expect(response_body_data_attributes).to include('email' => current_user.email) expect(response_body_data_attributes).to include('email' => current_user.email)
expect(response_body_data_attributes).to include('full_name' => current_user.full_name)
expect(response_body_data_attributes).to include('company_name' => current_user.primary_account.name)
end end
end end

View File

@@ -386,6 +386,13 @@ RSpec.feature 'User manages contract templates', type: :feature do
expect(ct.signature_legal_text.id).not_to eq ContractTemplate.last.signature_legal_text.id expect(ct.signature_legal_text.id).not_to eq ContractTemplate.last.signature_legal_text.id
end end
scenario 'trix editor has underline button', js: true do
visit new_project_contract_template_path(project)
select 'Appearance Release', from: 'Release type'
expect(page).to have_selector("button[data-trix-attribute='underline']")
end
context 'When the user is associate' do context 'When the user is associate' do
let(:current_user) { create(:user, :associate) } let(:current_user) { create(:user, :associate) }