refinerycms-videojs 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/images/refinery/admin/add_video_icon.png +0 -0
- data/app/assets/javascripts/refinery/admin/wymeditor_monkeypatch.js +13 -0
- data/app/assets/stylesheets/refinery/admin/video.css +95 -0
- data/app/controllers/refinery/videos/admin/video_files_controller.rb +16 -0
- data/app/controllers/refinery/videos/admin/videos_controller.rb +59 -0
- data/app/models/refinery/videos/video.rb +119 -0
- data/app/models/refinery/videos/video_file.rb +63 -0
- data/app/views/refinery/admin/dashboard/_additional_dashboard_menu_items.html.erb +4 -0
- data/app/views/refinery/videos/admin/videos/_actions.html.erb +23 -0
- data/app/views/refinery/videos/admin/videos/_embed_video_fields.html.erb +45 -0
- data/app/views/refinery/videos/admin/videos/_file_fields.html.erb +94 -0
- data/app/views/refinery/videos/admin/videos/_form.html.erb +44 -0
- data/app/views/refinery/videos/admin/videos/_form_option_fields.html.erb +17 -0
- data/app/views/refinery/videos/admin/videos/_new_file_field.html.erb +75 -0
- data/app/views/refinery/videos/admin/videos/_preview_form.html.erb +16 -0
- data/app/views/refinery/videos/admin/videos/_records.html.erb +18 -0
- data/app/views/refinery/videos/admin/videos/_sortable_list.html.erb +5 -0
- data/app/views/refinery/videos/admin/videos/_video.html.erb +23 -0
- data/app/views/refinery/videos/admin/videos/_videojs_dependencies.html.erb +2 -0
- data/app/views/refinery/videos/admin/videos/_videos.html.erb +2 -0
- data/app/views/refinery/videos/admin/videos/append_to_wym.js.erb +4 -0
- data/app/views/refinery/videos/admin/videos/dialog_preview.js.erb +2 -0
- data/app/views/refinery/videos/admin/videos/edit.html.erb +1 -0
- data/app/views/refinery/videos/admin/videos/index.html.erb +7 -0
- data/app/views/refinery/videos/admin/videos/insert.html.erb +34 -0
- data/app/views/refinery/videos/admin/videos/new.html.erb +3 -0
- data/app/views/refinery/videos/admin/videos/show.html.erb +4 -0
- data/app/views/sitemap/index.xml.builder +25 -0
- data/config/initializers/refinery/core.rb +11 -0
- data/config/locales/en.yml +76 -0
- data/config/locales/ru.yml +77 -0
- data/config/routes.rb +24 -0
- data/db/migrate/1_create_videos_videos.rb +29 -0
- data/db/migrate/2_create_video_file.rb +25 -0
- data/lib/generators/refinery/videos/templates/assets/javascripts/videojs_loader.js +7 -0
- data/lib/generators/refinery/videos/templates/config/initializers/refinery/videos.rb.erb +20 -0
- data/lib/generators/refinery/videos_generator.rb +18 -0
- data/lib/refinery/videos/configuration.rb +42 -0
- data/lib/refinery/videos/dragonfly.rb +53 -0
- data/lib/refinery/videos/engine.rb +32 -0
- data/lib/refinery/videos/validators/file_size_validator.rb +19 -0
- data/lib/refinery/videos/validators.rb +7 -0
- data/lib/refinery/videos.rb +28 -0
- data/lib/refinerycms-videojs.rb +1 -0
- metadata +138 -0
Binary file
|
@@ -0,0 +1,13 @@
|
|
1
|
+
$insert_video_link = "<ul id='add_video'><li><a href='/refinery/videos/insert?dialog=true'>Add Video</a></li></ul>";
|
2
|
+
window.onload = function ()
|
3
|
+
{
|
4
|
+
if ($.wymeditors(0)) {
|
5
|
+
$('.wym_area_top').append($insert_video_link);
|
6
|
+
init_modal_dialogs();
|
7
|
+
}
|
8
|
+
};
|
9
|
+
|
10
|
+
onCloseDialog = function(){
|
11
|
+
$('iframe#dialog_iframe').attr('src', '');
|
12
|
+
};
|
13
|
+
|
@@ -0,0 +1,95 @@
|
|
1
|
+
#add_video {
|
2
|
+
padding-top: 3px;
|
3
|
+
padding-left: 10px
|
4
|
+
}
|
5
|
+
|
6
|
+
#add_video li a{
|
7
|
+
height: 20px;
|
8
|
+
background-image: url('/assets/refinery/admin/add_video_icon.png');
|
9
|
+
background-repeat: no-repeat;
|
10
|
+
padding-left: 20px;
|
11
|
+
}
|
12
|
+
|
13
|
+
label.inline{
|
14
|
+
display: inline-block;
|
15
|
+
margin-bottom: 10px;
|
16
|
+
margin-top: 0
|
17
|
+
}
|
18
|
+
|
19
|
+
div.inline{
|
20
|
+
display: inline-block;
|
21
|
+
vertical-align: top;
|
22
|
+
margin: 1px 10px 0 0;
|
23
|
+
padding-left: 5px
|
24
|
+
}
|
25
|
+
|
26
|
+
div.parent{
|
27
|
+
margin-bottom: 20px
|
28
|
+
}
|
29
|
+
|
30
|
+
div.video_container{
|
31
|
+
margin: 10px;
|
32
|
+
}
|
33
|
+
|
34
|
+
div.tips{
|
35
|
+
margin: 10px 0 10px 0;
|
36
|
+
font-style: italic;
|
37
|
+
}
|
38
|
+
|
39
|
+
div.use_file{
|
40
|
+
padding-bottom: 5px;
|
41
|
+
padding-top: 2px;
|
42
|
+
}
|
43
|
+
a.select_video_type{
|
44
|
+
font-size: 12px;
|
45
|
+
margin: 10px 10px 10px 0
|
46
|
+
}
|
47
|
+
|
48
|
+
a.select_video_type.selected{
|
49
|
+
font-weight: bold;}
|
50
|
+
|
51
|
+
|
52
|
+
textarea.embed_tag{
|
53
|
+
height: 100px
|
54
|
+
}
|
55
|
+
|
56
|
+
span.short_info{
|
57
|
+
color: grey
|
58
|
+
}
|
59
|
+
|
60
|
+
div.add_remove_buttons{
|
61
|
+
margin-top: 10px
|
62
|
+
}
|
63
|
+
|
64
|
+
div#dialog_list{
|
65
|
+
width: 60%; float: left; min-height: 300px
|
66
|
+
}
|
67
|
+
|
68
|
+
div#dialog_list li.selected{
|
69
|
+
border: 4px solid #22A7F2
|
70
|
+
}
|
71
|
+
|
72
|
+
div#dialog_preview{
|
73
|
+
width:35%; float: right
|
74
|
+
}
|
75
|
+
|
76
|
+
div#preview_form{
|
77
|
+
width:35%; float: right
|
78
|
+
}
|
79
|
+
|
80
|
+
div#preview_form div.dimensions{
|
81
|
+
width:50%; float:left;
|
82
|
+
}
|
83
|
+
|
84
|
+
div#preview_form div.dimensions input{
|
85
|
+
width:70%;
|
86
|
+
}
|
87
|
+
|
88
|
+
div#preview_form div.options{
|
89
|
+
width:50%; float:right;
|
90
|
+
}
|
91
|
+
|
92
|
+
div#dialog_list #records{
|
93
|
+
width: 100%
|
94
|
+
}
|
95
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Refinery
|
2
|
+
module Videos
|
3
|
+
module Admin
|
4
|
+
class VideoFilesController < ::Refinery::AdminController
|
5
|
+
|
6
|
+
def destroy
|
7
|
+
@video_file = VideoFile.find(params[:id])
|
8
|
+
@video = @video_file.video
|
9
|
+
@video_file.destroy
|
10
|
+
redirect_to refinery.edit_videos_admin_video_path(@video), :notice => "#{@video_file.file_name} was successfully removed."
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Refinery
|
2
|
+
module Videos
|
3
|
+
module Admin
|
4
|
+
class VideosController < ::Refinery::AdminController
|
5
|
+
|
6
|
+
crudify :'refinery/videos/video',
|
7
|
+
:title_attribute => 'title',
|
8
|
+
:xhr_paging => true,
|
9
|
+
:order => 'position ASC',
|
10
|
+
:sortable => true
|
11
|
+
|
12
|
+
before_filter :set_embedded, :only => [:new, :create]
|
13
|
+
|
14
|
+
def show
|
15
|
+
@video = Video.find(params[:id])
|
16
|
+
end
|
17
|
+
|
18
|
+
def new
|
19
|
+
@video = Video.new
|
20
|
+
@video.video_files.build
|
21
|
+
end
|
22
|
+
|
23
|
+
def insert
|
24
|
+
search_all_videos if searching?
|
25
|
+
find_all_videos
|
26
|
+
paginate_videos
|
27
|
+
end
|
28
|
+
|
29
|
+
def append_to_wym
|
30
|
+
@video = Video.find(params[:video_id])
|
31
|
+
params['video'].each do |key, value|
|
32
|
+
@video.config[key.to_sym] = value
|
33
|
+
end
|
34
|
+
@html_for_wym = @video.to_html
|
35
|
+
end
|
36
|
+
|
37
|
+
def dialog_preview
|
38
|
+
@video = Video.find(params[:id].delete('video_'))
|
39
|
+
w, h = @video.config[:width], @video.config[:height]
|
40
|
+
@video.config[:width], @video.config[:height] = 300, 200
|
41
|
+
@preview_html = @video.to_html
|
42
|
+
@video.config[:width], @video.config[:height] = w, h
|
43
|
+
@embedded = true if @video.use_shared
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def paginate_videos
|
49
|
+
@videos = @videos.paginate(:page => params[:page], :per_page => Video.per_page(true))
|
50
|
+
end
|
51
|
+
|
52
|
+
def set_embedded
|
53
|
+
@embedded = true if params['embedded']
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'dragonfly'
|
2
|
+
|
3
|
+
module Refinery
|
4
|
+
module Videos
|
5
|
+
class Video < Refinery::Core::BaseModel
|
6
|
+
|
7
|
+
self.table_name = 'refinery_videos'
|
8
|
+
acts_as_indexed :fields => [:title]
|
9
|
+
|
10
|
+
validates :title, :presence => true
|
11
|
+
validate :one_source
|
12
|
+
|
13
|
+
has_many :video_files, :dependent => :destroy
|
14
|
+
accepts_nested_attributes_for :video_files
|
15
|
+
|
16
|
+
belongs_to :poster, :class_name => '::Refinery::Image'
|
17
|
+
accepts_nested_attributes_for :poster
|
18
|
+
|
19
|
+
################## Video config options
|
20
|
+
serialize :config, Hash
|
21
|
+
CONFIG_OPTIONS = {
|
22
|
+
:autoplay => "false", :width => "400", :height => "300",
|
23
|
+
:controls => "true", :preload => "true", :loop => "true"
|
24
|
+
}
|
25
|
+
|
26
|
+
attr_accessible :title, :poster_id, :video_files_attributes,
|
27
|
+
:position, :config, :embed_tag, :use_shared,
|
28
|
+
*CONFIG_OPTIONS.keys
|
29
|
+
|
30
|
+
# Create getters and setters
|
31
|
+
CONFIG_OPTIONS.keys.each do |option|
|
32
|
+
define_method option do
|
33
|
+
self.config[option]
|
34
|
+
end
|
35
|
+
define_method "#{option}=" do |value|
|
36
|
+
self.config[option] = value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
#######################################
|
40
|
+
|
41
|
+
########################### Callbacks
|
42
|
+
after_initialize :set_default_config
|
43
|
+
#####################################
|
44
|
+
|
45
|
+
def to_html
|
46
|
+
if use_shared
|
47
|
+
update_from_config
|
48
|
+
return embed_tag.html_safe
|
49
|
+
end
|
50
|
+
|
51
|
+
data_setup = []
|
52
|
+
CONFIG_OPTIONS.keys.each do |option|
|
53
|
+
if option && (option != :width && option != :height)
|
54
|
+
data_setup << "\"#{option}\": #{config[option] || '\"auto\"'}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
data_setup << "\"poster\": \"#{poster.url}\"" if poster
|
59
|
+
sources = []
|
60
|
+
video_files.each do |file|
|
61
|
+
if file.use_external
|
62
|
+
sources << ["<source src='#{file.external_url}' type='#{file.file_mime_type}'/>"]
|
63
|
+
else
|
64
|
+
sources << ["<source src='#{file.url}' type='#{file.file_mime_type}'/>"]
|
65
|
+
end if file.exist?
|
66
|
+
end
|
67
|
+
html = %Q{<video id="video_#{self.id}" class="video-js vjs-default-skin" width="#{config[:width]}" height="#{config[:height]}" data-setup=' {#{data_setup.join(',')}}'>#{sources.join}</video>}
|
68
|
+
|
69
|
+
html.html_safe
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def short_info
|
74
|
+
return [['.shared_source', embed_tag.scan(/src=".+?"/).first]] if use_shared
|
75
|
+
info = []
|
76
|
+
video_files.each do |file|
|
77
|
+
info << file.short_info
|
78
|
+
end
|
79
|
+
|
80
|
+
info
|
81
|
+
end
|
82
|
+
|
83
|
+
####################################class methods
|
84
|
+
class << self
|
85
|
+
def per_page(dialog = false)
|
86
|
+
dialog ? Videos.pages_per_dialog : Videos.pages_per_admin_index
|
87
|
+
end
|
88
|
+
end
|
89
|
+
#################################################
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def set_default_config
|
94
|
+
if new_record? && config.empty?
|
95
|
+
CONFIG_OPTIONS.each do |option, value|
|
96
|
+
self.send("#{option}=", value)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def update_from_config
|
102
|
+
embed_tag.gsub!(/width="(\d*)?"/, "width=\"#{config[:width]}\"")
|
103
|
+
embed_tag.gsub!(/height="(\d*)?"/, "height=\"#{config[:height]}\"")
|
104
|
+
#fix iframe overlay
|
105
|
+
if embed_tag.include? 'iframe'
|
106
|
+
embed_tag =~ /src="(\S+)"/
|
107
|
+
embed_tag.gsub!(/src="\S+"/, "src=\"#{$1}?wmode=transparent\"")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def one_source
|
112
|
+
errors.add(:embed_tag, 'Please embed video') if use_shared && embed_tag.nil?
|
113
|
+
errors.add(:video_files, 'Please select at least one source') if !use_shared && video_files.empty?
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'dragonfly'
|
2
|
+
|
3
|
+
module Refinery
|
4
|
+
module Videos
|
5
|
+
class VideoFile < Refinery::Core::BaseModel
|
6
|
+
|
7
|
+
self.table_name = 'refinery_video_files'
|
8
|
+
acts_as_indexed :fields => [:file_name, :file_ext]
|
9
|
+
attr_accessible :file, :file_mime_type, :position, :use_external, :external_url
|
10
|
+
belongs_to :video
|
11
|
+
|
12
|
+
MIME_TYPES = {'.mp4' => 'mp4', '.flv' => 'flv', '.webm' => 'webm', '.ogg' => 'ogg', '.ogv' => 'ogg'}
|
13
|
+
|
14
|
+
############################ Dragonfly
|
15
|
+
::Refinery::Videos::Dragonfly.setup!
|
16
|
+
video_accessor :file
|
17
|
+
|
18
|
+
delegate :ext, :size, :mime_type, :url,
|
19
|
+
:to => :file,
|
20
|
+
:allow_nil => true
|
21
|
+
|
22
|
+
#######################################
|
23
|
+
|
24
|
+
########################### Validations
|
25
|
+
validates :file, :presence => true, :unless => :use_external?
|
26
|
+
validates :mime_type, :inclusion => { :in => Refinery::Videos.config[:whitelisted_mime_types],
|
27
|
+
:message => "Wrong file mime_type" }, :if => :file_name?
|
28
|
+
validates :external_url, :presence => true, :if => :use_external?
|
29
|
+
#######################################
|
30
|
+
|
31
|
+
before_save :set_mime_type
|
32
|
+
before_update :set_mime_type
|
33
|
+
|
34
|
+
def exist?
|
35
|
+
use_external ? external_url.present? : file.present?
|
36
|
+
end
|
37
|
+
|
38
|
+
def short_info
|
39
|
+
if use_external
|
40
|
+
['.link', external_url]
|
41
|
+
else
|
42
|
+
['.file', file_name]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def set_mime_type
|
49
|
+
if use_external
|
50
|
+
type = external_url.scan(/\.\w+$/)
|
51
|
+
if type.present? && MIME_TYPES.has_key?(type.first)
|
52
|
+
self.file_mime_type = "video/#{MIME_TYPES[type.first]}"
|
53
|
+
else
|
54
|
+
self.file_mime_type = 'video/mp4'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<ul>
|
2
|
+
<li>
|
3
|
+
<%= render '/refinery/admin/search', :url => refinery.videos_admin_videos_path %>
|
4
|
+
</li>
|
5
|
+
<li>
|
6
|
+
<%= link_to t('.create_new'), refinery.new_videos_admin_video_path,
|
7
|
+
:class => "add_icon" %>
|
8
|
+
</li>
|
9
|
+
<% if !searching? && ::Refinery::Videos::Admin::VideosController.sortable? && ::Refinery::Videos::Video.any? %>
|
10
|
+
<li>
|
11
|
+
<%= link_to t('.reorder', :what => "Videos"),
|
12
|
+
refinery.videos_admin_videos_path,
|
13
|
+
:id => "reorder_action",
|
14
|
+
:class => "reorder_icon" %>
|
15
|
+
|
16
|
+
<%= link_to t('.reorder_done', :what => "Videos"),
|
17
|
+
refinery.videos_admin_videos_path,
|
18
|
+
:id => "reorder_action_done",
|
19
|
+
:style => "display: none;",
|
20
|
+
:class => "reorder_icon" %>
|
21
|
+
</li>
|
22
|
+
<% end %>
|
23
|
+
</ul>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<div class='field'>
|
2
|
+
<%= f.label t('.copy_embed_tag_here') %>
|
3
|
+
<%= f.text_area :embed_tag, :class => 'embed_tag', :required => true %>
|
4
|
+
</div>
|
5
|
+
<%= f.hidden_field :use_shared, :value => true %>
|
6
|
+
|
7
|
+
<script type="text/javascript">
|
8
|
+
$(function(){
|
9
|
+
$('textarea.embed_tag').on('input', function(e){
|
10
|
+
set_width_and_height($(this))
|
11
|
+
});
|
12
|
+
$('#video_width').on('input', function(){
|
13
|
+
set_in_text_area_width('width', $(this));
|
14
|
+
});
|
15
|
+
$('#video_height').on('input', function(){
|
16
|
+
set_in_text_area_width('height', $(this));
|
17
|
+
});
|
18
|
+
|
19
|
+
|
20
|
+
});
|
21
|
+
|
22
|
+
function set_width_and_height(text_area){
|
23
|
+
var val = text_area.val();
|
24
|
+
var width = val.match(/width="(\d+)"/);
|
25
|
+
if (width) {
|
26
|
+
$('#video_width').val(width[1]);
|
27
|
+
}
|
28
|
+
var height = val.match(/height="(\d+)"/);
|
29
|
+
if (height){
|
30
|
+
$('#video_height').val(height[1]);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
function set_in_text_area_width(what, input){
|
35
|
+
var val = input.val();
|
36
|
+
var text = $('textarea.embed_tag').val();
|
37
|
+
var new_text = ''
|
38
|
+
if (what == 'width'){
|
39
|
+
new_text = text.replace(/width="(\d*|\0)"/, 'width="' + val + '"');
|
40
|
+
} else if (what == 'height') {
|
41
|
+
new_text = text.replace(/height="(\d*|\0)"/, 'height="' + val + '"');
|
42
|
+
}
|
43
|
+
$('textarea.embed_tag').val(new_text);
|
44
|
+
}
|
45
|
+
</script>
|
@@ -0,0 +1,94 @@
|
|
1
|
+
<label><%= t('.files') %></label>
|
2
|
+
<div class='tips'><%= t('.file_tip') %></div>
|
3
|
+
<div id='file_fields'>
|
4
|
+
<%= f.fields_for :video_files do |v| %>
|
5
|
+
<div class="parent">
|
6
|
+
<label class="inline">
|
7
|
+
<%= v.radio_button :use_external, false, {:class => "use_file"}.merge(v.object.use_external ? {} : {:checked => true}) %>
|
8
|
+
<span><%= t('.use_file') %></span>
|
9
|
+
</label>
|
10
|
+
<label class="inline">
|
11
|
+
<%= v.radio_button :use_external, true, {:class => "use_external"}.merge(v.object.use_external ? {:checked => true} : {}) %>
|
12
|
+
<span><%= t('.use_external_source') %></span>
|
13
|
+
</label>
|
14
|
+
|
15
|
+
<div class='field'>
|
16
|
+
<div class="use_file" <%= "style='display: none;'" if v.object.use_external %>>
|
17
|
+
<% if v.object.file.present? %>
|
18
|
+
<% if v.object.url %>
|
19
|
+
<%= link_to(t('.download_current'), v.object.url,
|
20
|
+
:title => v.object.file_name) %>
|
21
|
+
<em><%= t('.or') %> </em><%= t('.replace') %>
|
22
|
+
<% else %>
|
23
|
+
<span><%= t('.add_file') %></span>
|
24
|
+
<% end %>
|
25
|
+
<%= v.file_field :file %>
|
26
|
+
<% else %>
|
27
|
+
<span><%= t('.add_file') %></span>
|
28
|
+
<%= v.file_field :file, {}.merge(v.object.use_external ? {} : {:required => true}) %>
|
29
|
+
<% end %>
|
30
|
+
</div>
|
31
|
+
<div class="use_external" <%= "style='display: none;'" unless v.object.use_external %>>
|
32
|
+
<span><%= t('.link_to_source') %></span>
|
33
|
+
<%= v.text_field :external_url, {}.merge(v.object.use_external ? {:required => true} : {}) %>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
<div class='add_remove_buttons'>
|
37
|
+
<% if f.object.video_files.count > 1 %>
|
38
|
+
<% if f.object.persisted? %>
|
39
|
+
<%= link_to(refinery.videos_admin_video_file_path(v.object),
|
40
|
+
:class => "cancel confirm-delete",
|
41
|
+
:title => t('.delete'),
|
42
|
+
:confirm => t('message', :scope => 'refinery.admin.delete', :title => 'file'),
|
43
|
+
:method => :delete) do %>
|
44
|
+
<%= refinery_icon_tag("delete.png") %>
|
45
|
+
<div class="inline"><%= t('.delete_source') %></div>
|
46
|
+
<% end %>
|
47
|
+
<% else %>
|
48
|
+
<a href='#' onclick="remove_field($(this)); return false" class="remove_field" style='display: none'><%= refinery_icon_tag("delete.png")%>
|
49
|
+
<div class="inline"><%= t('.delete_source') %></div>
|
50
|
+
</a>
|
51
|
+
<% end %>
|
52
|
+
<% end %>
|
53
|
+
<a href='#' onclick="add_field($(this)); return false" class="add_field" style='display: none'><%= refinery_icon_tag("add.png") %>
|
54
|
+
<div class="inline"><%= t('.add_source') %></div>
|
55
|
+
</a>
|
56
|
+
</div>
|
57
|
+
</div>
|
58
|
+
|
59
|
+
<% end %>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
<% @video.video_files.build %>
|
63
|
+
<%= render 'new_file_field', :f => f %>
|
64
|
+
|
65
|
+
<div class='field' id='maximum_file_size'>
|
66
|
+
<label>
|
67
|
+
<%= t('.maximum_file_size', :bytes => number_to_human_size(Refinery::Videos.max_file_size)) %>
|
68
|
+
</label>
|
69
|
+
</div>
|
70
|
+
|
71
|
+
<script type="text/javascript">
|
72
|
+
function radio_control(){
|
73
|
+
$('input.use_external').on('change', function(){
|
74
|
+
if ($(this).is(':checked')) {
|
75
|
+
var $parent = $(this).parents('div.parent');
|
76
|
+
$parent.find('div.use_external').show();
|
77
|
+
$parent.find('div.use_file').hide();
|
78
|
+
$parent.find('.use_file input').removeAttr('required');
|
79
|
+
$parent.find('.use_external input').attr('required', 'required');
|
80
|
+
}
|
81
|
+
});
|
82
|
+
$('input.use_file').on('change', function(){
|
83
|
+
if ($(this).is(':checked')) {
|
84
|
+
var $parent = $(this).parents('div.parent');
|
85
|
+
$parent.find('div.use_external').hide();
|
86
|
+
$parent.find('div.use_file').show();
|
87
|
+
$parent.find('.use_file input').attr('required', 'required');
|
88
|
+
$parent.find('.use_external input').removeAttr('required');
|
89
|
+
}
|
90
|
+
});
|
91
|
+
}
|
92
|
+
|
93
|
+
|
94
|
+
</script>
|
@@ -0,0 +1,44 @@
|
|
1
|
+
<% @embedded = true if @video.use_shared %>
|
2
|
+
<%= form_for [refinery, :videos_admin, @video] do |f| %>
|
3
|
+
<%= hidden_field_tag(:embedded, true) if @embedded %>
|
4
|
+
<%= render '/refinery/admin/error_messages',
|
5
|
+
:object => @video,
|
6
|
+
:include_object_name => true %>
|
7
|
+
|
8
|
+
<div class='field'>
|
9
|
+
<%= f.label t('.title') %>
|
10
|
+
<%= f.text_field :title, :required => true %>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<% if @embedded %>
|
14
|
+
<%= render 'embed_video_fields', :f => f %>
|
15
|
+
<% else %>
|
16
|
+
<div class='field'>
|
17
|
+
<%= f.label t('.poster') %>
|
18
|
+
<%= render '/refinery/admin/image_picker',
|
19
|
+
:f => f,
|
20
|
+
:field => :poster_id,
|
21
|
+
:image => @video.poster,
|
22
|
+
:toggle_image_display => false %>
|
23
|
+
|
24
|
+
</div>
|
25
|
+
<%= render 'file_fields', :f => f %>
|
26
|
+
<% end %>
|
27
|
+
|
28
|
+
<div class='field'>
|
29
|
+
<%= f.label t('.width') %>
|
30
|
+
<%= f.text_field :width %>
|
31
|
+
</div>
|
32
|
+
<div class='field'>
|
33
|
+
<%= f.label t('.height') %>
|
34
|
+
<%= f.text_field :height %>
|
35
|
+
</div>
|
36
|
+
|
37
|
+
<%= render('form_option_fields', :f => f) unless @embedded %>
|
38
|
+
|
39
|
+
<%= render '/refinery/admin/form_actions',
|
40
|
+
:f => f,
|
41
|
+
:continue_editing => false,
|
42
|
+
:delete_title => t('delete', :scope => 'refinery.videos.admin.videos.video'),
|
43
|
+
:delete_confirmation => t('message', :scope => 'refinery.admin.delete', :title => @video.title) %>
|
44
|
+
<% end %>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<label><%= t('.options') %></label>
|
2
|
+
<div class='field'>
|
3
|
+
<%= f.check_box :autoplay, { }, "true", "false" %>
|
4
|
+
<%= f.label :autoplay, t('.autoplay'), :class => 'input_label' %>
|
5
|
+
</div>
|
6
|
+
<div class='field'>
|
7
|
+
<%= f.check_box :controls, { }, "true", "false" %>
|
8
|
+
<%= f.label :controls, t('.show_ontrols'), :class => 'input_label' %>
|
9
|
+
</div>
|
10
|
+
<div class='field'>
|
11
|
+
<%= f.check_box :preload, { }, "true", "false" %>
|
12
|
+
<%= f.label :preload, t('.preload_video'), :class => 'input_label' %>
|
13
|
+
</div>
|
14
|
+
<div class='field'>
|
15
|
+
<%= f.check_box :loop, { }, "true", "false" %>
|
16
|
+
<%= f.label :loop, t('.loop_video'), :class => 'input_label' %>
|
17
|
+
</div>
|
@@ -0,0 +1,75 @@
|
|
1
|
+
<%= f.fields_for :video_files, @video.video_files.last do |v| %>
|
2
|
+
<div class="new_field" style="display: none">
|
3
|
+
<label class="inline">
|
4
|
+
<%= v.radio_button :use_external, false, :class => "use_file", :checked => true %>
|
5
|
+
<span><%= t('.use_file') %></span>
|
6
|
+
</label>
|
7
|
+
<label class="inline">
|
8
|
+
<%= v.radio_button :use_external, true, :class => "use_external" %>
|
9
|
+
<span><%= t('.use_external_source') %></span>
|
10
|
+
</label>
|
11
|
+
<div class='field'>
|
12
|
+
<div class="use_file">
|
13
|
+
<span><%= t('.add_file') %></span>
|
14
|
+
<%= v.file_field :file, :id => "new_file_field", :required => true %>
|
15
|
+
</div>
|
16
|
+
<div class="use_external" style='display: none'>
|
17
|
+
<span><%= t('.link_to_source') %></span>
|
18
|
+
<%= v.text_field :external_url, :id => "new_external_url_field" %>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
<div class='add_remove_buttons'>
|
22
|
+
<a href='#' onclick="remove_field($(this)); return false" class="remove_field"><%= refinery_icon_tag("delete.png")%>
|
23
|
+
<div class="inline"><%= t('.delete_source') %></div>
|
24
|
+
</a>
|
25
|
+
<a href='#' onclick="add_field($(this)); return false" class="add_field"><%= refinery_icon_tag("add.png") %>
|
26
|
+
<div class="inline"><%= t('.add_source') %></div>
|
27
|
+
</a>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
<script type="text/javascript">
|
33
|
+
function add_field(plus){
|
34
|
+
plus.parents('div.parent').find('a.add_field').hide();
|
35
|
+
plus.parents('div.parent').find('a.remove_field').show();
|
36
|
+
prepare_new_field();
|
37
|
+
$div = window.new_field.clone();
|
38
|
+
$div.addClass('parent');
|
39
|
+
$div.removeClass('new_field');
|
40
|
+
$('#file_fields').append($div.show());
|
41
|
+
radio_control();
|
42
|
+
}
|
43
|
+
|
44
|
+
function remove_field(minus){
|
45
|
+
minus.parents('div.parent').remove();
|
46
|
+
$('div.parent').last().find('a.add_field').show();
|
47
|
+
if ($('div.parent').length > 1) {
|
48
|
+
$('div.parent').last().find('a.remove_field').show();
|
49
|
+
} else {
|
50
|
+
$('div.parent').find('a.remove_field').hide();
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
$(function(){
|
55
|
+
radio_control();
|
56
|
+
$('div.parent').last().find('a.add_field').show();
|
57
|
+
$without_first = $('div.parent').not($('div.parent').first());
|
58
|
+
if ($('div.parent').length > 1) {
|
59
|
+
$('div.parent').find('a.remove_field').show();
|
60
|
+
}
|
61
|
+
window.new_field = $('div.new_field').remove();
|
62
|
+
$('input[checked="checked"]').attr('checked', 'checked');
|
63
|
+
});
|
64
|
+
|
65
|
+
function prepare_new_field(){
|
66
|
+
var $inputs = window.new_field.find('input');
|
67
|
+
var date = Number(new Date);
|
68
|
+
$.each($inputs, function(){
|
69
|
+
var new_name = $(this).attr('name').replace(/\[\d+\]/,'['+date+']');
|
70
|
+
$(this).attr('name', new_name);
|
71
|
+
var new_id = $(this).attr('id') + date
|
72
|
+
$(this).attr('id', new_id);
|
73
|
+
});
|
74
|
+
}
|
75
|
+
</script>
|