diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index 5027ba88e..994163e3d 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -93,7 +93,6 @@ class ArticlesController < ApplicationController if @article.update(article_params.merge(edited_at: edited_at_date)) handle_org_assignment handle_hiring_tag - assign_video_attributes if @article.published Notification.send_all(@article, "Published") if @article.previous_changes.include?("published") path = @article.path @@ -101,10 +100,6 @@ class ArticlesController < ApplicationController Notification.remove_all(@article, "Published") path = "/#{@article.username}/#{@article.slug}?preview=#{@article.password}" end - if params[:article][:video] - render action: "video_upload" - return - end redirect_to (params[:destination] || path) else render :edit @@ -186,18 +181,6 @@ class ArticlesController < ApplicationController :video, :video_code, :video_source_url, :video_thumbnail_url) end - def assign_video_attributes - if params[:article][:video] - @article.video = params[:article][:video] - @article.video_state = "PROGRESSING" - @article.video_code = @article.video.split("dev-to-input-v0/")[1] - @article.video_source_url = "https://dw71fyauz7yz9.cloudfront.net/#{@article.video_code}/#{@article.video_code}.m3u8" - @article.video_thumbnail_url = "https://dw71fyauz7yz9.cloudfront.net/#{@article.video_code}/thumbs-#{@article.video_code}-00001.png" - @article.save - - end - end - def job_opportunity_params return nil unless params[:article][:job_opportunity].present? params[:article].require(:job_opportunity).permit( diff --git a/app/controllers/videos_controller.rb b/app/controllers/videos_controller.rb new file mode 100644 index 000000000..622ccccc5 --- /dev/null +++ b/app/controllers/videos_controller.rb @@ -0,0 +1,32 @@ +class VideosController < ApplicationController + before_action :check_video_permission + + def new + end + + def create + @article = Article.new(body_markdown:"---\ntitle: Unpublished Video ~ #{rand(100000).to_s(26)}\npublished: false\ndescription: \ntags: \n---\n\n",processed_html:"") + @article.user_id = current_user.id + @article.show_comments = true + assign_video_attributes + @article.save! + render action: "js_response" + end + + def assign_video_attributes + if params[:article][:video] && current_user.has_role?(:video_permission) + @article.video = params[:article][:video] + @article.video_state = "PROGRESSING" + @article.video_code = @article.video.split("dev-to-input-v0/")[1] + @article.video_source_url = "https://dw71fyauz7yz9.cloudfront.net/#{@article.video_code}/#{@article.video_code}.m3u8" + @article.video_thumbnail_url = "https://dw71fyauz7yz9.cloudfront.net/#{@article.video_code}/thumbs-#{@article.video_code}-00001.png" + + end + end + + private + + def check_video_permission + redirect_to "/enter" unless current_user&.has_role?(:video_permission) + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e6672f9b8..99d29070f 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -22,6 +22,7 @@ module ApplicationHelper controller_name == "pages" || controller_name == "dashboards"|| controller_name == "moderations"|| + controller_name == "videos"|| controller_name == "stories" || controller_name == "comments" || controller_name == "notifications" || diff --git a/app/models/article.rb b/app/models/article.rb index 3cb5ac44f..602790a17 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -31,6 +31,7 @@ class Article < ApplicationRecord # validates :description, length: { in: 10..170, if: :published? } validates :body_markdown, uniqueness: { scope: :user_id } validate :validate_tag + validate :validate_video validates :video_state, inclusion: { in: %w(PROGRESSING COMPLETED) }, allow_nil: true before_validation :evaluate_markdown @@ -380,6 +381,12 @@ class Article < ApplicationRecord end end + def validate_video + if published && video_state == "PROGRESSING" + return errors.add(:published, "cannot be set to true if video is still processing") + end + end + def create_slug if slug.blank? && title.present? && !published self.slug = title_to_slug + "-temp-slug-#{rand(10_000_000)}" diff --git a/app/models/role.rb b/app/models/role.rb index ab7e4e1ec..d33286eae 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -25,6 +25,7 @@ class Role < ApplicationRecord level_2_member level_1_member workshop_pass + video_permission ), } scopify diff --git a/app/views/articles/edit.html.erb b/app/views/articles/edit.html.erb index d20d64426..2d14e13e3 100644 --- a/app/views/articles/edit.html.erb +++ b/app/views/articles/edit.html.erb @@ -1,64 +1,37 @@ <% title "Edit Article - DEV" %> - <% if params[:beta_form] %> - <%= render 'react_form' %> - <% else %> - <% if @article.body_html && @article.body_html.size > 10 %> - <%= render 'inline_form' %> - <% else %> - <%= render 'articles/markdown_form' %> - <% end %> - <% end %> - -<% if @user.has_role?(:super_admin) %> -
- <%= stylesheet_link_tag 's3_direct_upload', media: 'all' %> +<% if @article.video.present? %> +
<% if @article.video_state == "PROGRESSING" %> -

Video Transcoding In Progress

- -



+

⏳ Video Transcoding In Progress ⏳

+ +
+

+ You'll get an email when it's finished. Contact ben@dev.to if the email never comes, or if anything else is broken. 😱 +

+

+ This is an unpublished article with a video. Publish it as usual when the video is done processing. +

+
<% elsif @article.video_state == "COMPLETED" %>

Video uploaded - <%= @article.video_code %>

<%= render "articles/video_player", meta_tags: false, article: @article %> -

Thumbnail:

- -

Change thumbnail:

+

Change preview image:

<%= form_for(@article) do |f| %> <%= f.text_field :video_thumbnail_url, placeholder: "New Thumbnail URL" %> <%= f.submit %> <% end %>
Video is in beta ❤️


- <% else %> -

Upload Video 📹

- <%= s3_uploader_form callback_url: "/articles/#{@article.id}", - callback_method: "PUT", - callback_param: "article[video]", - key: "video-upload__#{SecureRandom.hex}", - key_starts_with: "video-upload__", - acl: "public-read", - max_file_size: 500.megabytes, - id: "s3-uploader", - class: "upload-form", - data: {:key => :val} do %> - <%= file_field_tag :file %> - - <% end %> -
-


- <% end %> - - <%= javascript_include_tag 's3_direct_upload' %> - + <% end %> + <% end %> + +<% if params[:beta_form] %> + <%= render 'react_form' %> +<% else %> + <% if @article.body_html && @article.body_html.size > 10 %> + <%= render 'inline_form' %> + <% else %> + <%= render 'articles/markdown_form' %> + <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/articles/show.html.erb b/app/views/articles/show.html.erb index a22977fb6..011dc8e32 100644 --- a/app/views/articles/show.html.erb +++ b/app/views/articles/show.html.erb @@ -69,6 +69,9 @@ data-live="<%= @article.live_now %>" data-path="<%= @article.path %>" > + <% if @article.video_state == "PROGRESSING" %> +

⏳ Video Transcoding In Progress ⏳

+ <% end %>
diff --git a/app/views/articles/video_upload.js.erb b/app/views/articles/video_upload.js.erb deleted file mode 100644 index bcebe9d37..000000000 --- a/app/views/articles/video_upload.js.erb +++ /dev/null @@ -1 +0,0 @@ -location.reload(); \ No newline at end of file diff --git a/app/views/dashboards/show.html.erb b/app/views/dashboards/show.html.erb index 4ae9ed099..02beb5d54 100644 --- a/app/views/dashboards/show.html.erb +++ b/app/views/dashboards/show.html.erb @@ -57,6 +57,11 @@ ... <% end %> + <% if current_user.has_role?(:video_permission) %> + + Upload a Video (beta ❤️) + + <% end %> <% @articles.each do |article| %>
diff --git a/app/views/videos/js_response.js.erb b/app/views/videos/js_response.js.erb new file mode 100644 index 000000000..86c92e81b --- /dev/null +++ b/app/views/videos/js_response.js.erb @@ -0,0 +1 @@ +window.location.href = "<%= @article.path %>/edit" \ No newline at end of file diff --git a/app/views/videos/new.html.erb b/app/views/videos/new.html.erb new file mode 100644 index 000000000..9ef35ef72 --- /dev/null +++ b/app/views/videos/new.html.erb @@ -0,0 +1,48 @@ + + +
+ <%= stylesheet_link_tag 's3_direct_upload', media: 'all' %> +

🎥 Upload Video File 🙌

+ <%= s3_uploader_form callback_url: "/videos", + callback_method: "POST", + callback_param: "article[video]", + key: "video-upload__#{SecureRandom.hex}", + key_starts_with: "video-upload__", + acl: "public-read", + max_file_size: 500.megabytes, + id: "s3-uploader", + class: "upload-form", + data: {:key => :val} do %> + <%= file_field_tag :file %> + + <% end %> +
+

+ Video is beta. Max 500mb, email ben@dev.to if you have any problems. +

+
+
+ +<%= javascript_include_tag 's3_direct_upload' %> + diff --git a/config/initializers/reserved_words.rb b/config/initializers/reserved_words.rb index 7fb4aa369..c66682d1a 100644 --- a/config/initializers/reserved_words.rb +++ b/config/initializers/reserved_words.rb @@ -14,6 +14,8 @@ "features", "privacy", "terms", + "videos", + "video_states", "latest", "contact", "merch", diff --git a/config/routes.rb b/config/routes.rb index 70bd64247..c1c8545cb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -92,6 +92,7 @@ Rails.application.routes.draw do resources :buffered_articles, only: [:index] resources :events, only: [:index, :show] resources :additional_content_boxes, only: [:index] + resources :videos, only: [:create, :new] resources :video_states, only: [:create] get "/notifications/:username" => "notifications#index" patch "/onboarding_update" => "users#onboarding_update"