From b9a41c5a69b0d6f7f2d11f9c0e8d49343ea7c6c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com>
Date: Thu, 9 Mar 2023 16:23:34 +0100
Subject: [PATCH] iframe video

---
 .../communication/block/template/video.rb     |  4 +++
 app/services/video/provider.rb                | 20 +++++++++++++
 app/services/video/provider/dailymotion.rb    | 15 ++++++++++
 app/services/video/provider/default.rb        | 29 +++++++++++++++++++
 app/services/video/provider/vimeo.rb          | 13 +++++++++
 app/services/video/provider/youtube.rb        | 15 ++++++++++
 .../blocks/templates/video/_static.html.erb   |  4 +++
 7 files changed, 100 insertions(+)
 create mode 100644 app/services/video/provider.rb
 create mode 100644 app/services/video/provider/dailymotion.rb
 create mode 100644 app/services/video/provider/default.rb
 create mode 100644 app/services/video/provider/vimeo.rb
 create mode 100644 app/services/video/provider/youtube.rb

diff --git a/app/models/communication/block/template/video.rb b/app/models/communication/block/template/video.rb
index de9b37875..0e0612d61 100644
--- a/app/models/communication/block/template/video.rb
+++ b/app/models/communication/block/template/video.rb
@@ -4,6 +4,10 @@ class Communication::Block::Template::Video < Communication::Block::Template::Ba
   has_component :video_title, :string
   has_component :transcription, :text
 
+  def video_iframe
+    Video::Provider.find(url).iframe_tag(title: video_title)
+  end
+
   protected
 
   def check_accessibility
diff --git a/app/services/video/provider.rb b/app/services/video/provider.rb
new file mode 100644
index 000000000..5b6f3fd68
--- /dev/null
+++ b/app/services/video/provider.rb
@@ -0,0 +1,20 @@
+class Video::Provider
+  PROVIDERS = [
+    Vimeo,
+    Youtube,
+    Dailymotion
+  ]
+
+  def self.find(video_url)
+    PROVIDERS.each do |provider|
+      return provider.new(video_url) if url_in_domains?(video_url, provider::DOMAINS)
+    end
+    Default.new(video_url)
+  end
+
+  protected
+
+  def self.url_in_domains?(url, domains)
+    domains.any? { |domain| url.include? domain }
+  end
+end
diff --git a/app/services/video/provider/dailymotion.rb b/app/services/video/provider/dailymotion.rb
new file mode 100644
index 000000000..3a66f5fa5
--- /dev/null
+++ b/app/services/video/provider/dailymotion.rb
@@ -0,0 +1,15 @@
+class Video::Provider::Dailymotion < Video::Provider::Default
+  DOMAINS = ['dailymotion.com', 'dai.ly']
+
+  # "https://www.dailymotion.com/video/x35l6b8"
+  # "https://dai.ly/x35l6b8"
+  def identifier
+    video_url.include?('dai.ly')  ? video_url.split('dai.ly/').last
+                                  : video_url.split('video/').last
+  end
+
+  # https://developer.dailymotion.com/player#player-parameters
+  def iframe_url
+    "https://www.dailymotion.com/embed/video/#{identifier}"
+  end
+end
diff --git a/app/services/video/provider/default.rb b/app/services/video/provider/default.rb
new file mode 100644
index 000000000..336e8e7aa
--- /dev/null
+++ b/app/services/video/provider/default.rb
@@ -0,0 +1,29 @@
+class Video::Provider::Default
+  attr_reader :video_url
+
+  include ActionView::Helpers::TagHelper
+
+  def initialize(video_url)
+    @video_url = video_url
+  end
+
+  def platform
+    self.class.name.demodulize.downcase.to_sym
+  end
+
+  def iframe_url
+    video_url
+  end
+
+  def iframe_tag(**iframe_options)
+    content_tag(:iframe, nil, default_iframe_options.merge(iframe_options))
+  end
+
+  def default_iframe_options
+    {
+      class: (platform == :default ? nil : platform),
+      loading: 'lazy',
+      src: iframe_url
+    }
+  end
+end
diff --git a/app/services/video/provider/vimeo.rb b/app/services/video/provider/vimeo.rb
new file mode 100644
index 000000000..3d10b8544
--- /dev/null
+++ b/app/services/video/provider/vimeo.rb
@@ -0,0 +1,13 @@
+class Video::Provider::Vimeo < Video::Provider::Default
+  DOMAINS = ['vimeo.com']
+
+  # "https://vimeo.com/248482251"
+  def identifier
+    video_url.chomp('/').split('/').last
+  end
+
+  # https://help.vimeo.com/hc/en-us/articles/360001494447-Using-Player-Parameters
+  def iframe_url
+    "https://player.vimeo.com/video/#{identifier}"
+  end
+end
diff --git a/app/services/video/provider/youtube.rb b/app/services/video/provider/youtube.rb
new file mode 100644
index 000000000..e9fa299e1
--- /dev/null
+++ b/app/services/video/provider/youtube.rb
@@ -0,0 +1,15 @@
+class Video::Provider::Youtube < Video::Provider::Default
+  DOMAINS = ['youtube.com', 'youtu.be']
+
+  # "https://www.youtube.com/watch?v=sN8Cq5HEBug"
+  # "https://youtu.be/sN8Cq5HEBug"
+  def identifier
+    video_url.include?('youtu.be')  ? video_url.split('youtu.be/').last
+                                    : video_url.split('v=').last
+  end
+
+  # https://developers.google.com/youtube/player_parameters
+  def iframe_url
+    "https://www.youtube.com/embed/#{identifier}"
+  end
+end
diff --git a/app/views/admin/communication/blocks/templates/video/_static.html.erb b/app/views/admin/communication/blocks/templates/video/_static.html.erb
index ca779a451..ad5aae354 100644
--- a/app/views/admin/communication/blocks/templates/video/_static.html.erb
+++ b/app/views/admin/communication/blocks/templates/video/_static.html.erb
@@ -1,3 +1,7 @@
 <%= block_component_static :url %>
 <%= block_component_static :video_title %>
+<% if block.template.url.present? %>
+      video_iframe: >-
+        <%= block.template.video_iframe %>
+<% end %>
 <%= block_component_static :transcription %>
-- 
GitLab