Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ GEM
rest-client (>= 2.0.0)
cocoon (1.2.15)
colorize (0.8.1)
concurrent-ruby (1.3.5)
concurrent-ruby (1.3.4)
countable-rails (0.0.1)
railties (>= 3.1)
crack (0.4.5)
Expand Down
20 changes: 20 additions & 0 deletions app/assets/stylesheets/osem-splash.scss
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,26 @@
color: white;
}
}

#video {
.video-wrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 aspect ratio */
padding-top: 25px;
height: 0;
max-width: 1080px;
margin: 0 auto;

iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
}
}
}
}

.publicorprivate {
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/admin/splashpages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ def splashpage_params
:include_venue, :include_registrations,
:include_tickets, :include_lodgings,
:include_sponsors, :include_social_media,
:include_booths, :include_past_editions)
:include_booths, :include_past_editions,
:video_url)
end
end
end
105 changes: 105 additions & 0 deletions app/models/splashpage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,109 @@ class Splashpage < ApplicationRecord
belongs_to :conference

has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }

validates :video_url,
format: { with: URI::regexp(%w(http https)), message: :invalid_url },
allow_blank: true

validate :video_url_is_supported_platform, if: :video_url?

# Configuration for supported video platforms
# To add a new platform: add an entry with patterns (regex) and embed_template
SUPPORTED_PLATFORMS = {
youtube: {
patterns: [
/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/|m\.youtube\.com\/watch\?v=)([a-zA-Z0-9_-]{11})/
],
embed_template: 'https://www.youtube.com/embed/%{video_id}',
autoplay_params: 'autoplay=1&loop=1&mute=1&controls=0&disablekb=1&fs=0&iv_load_policy=3&modestbranding=1&playsinline=1'
},
vimeo: {
patterns: [/vimeo\.com\/(?:video\/)?(\d+)/],
embed_template: 'https://player.vimeo.com/video/%{video_id}',
autoplay_params: 'autoplay=1&muted=1&loop=1&playsinline=1'
},
peertube: {
patterns: [
/(https?:\/\/[^\/]+)\/videos\/watch\/([a-zA-Z0-9-]+)/,
/(https?:\/\/[^\/]+)\/w\/([a-zA-Z0-9-]+)/
],
embed_template: '%{instance_url}/videos/embed/%{video_id}',
autoplay_params: 'autoplay=1&loop=1'
},
invidious: {
patterns: [/(https?:\/\/[^\/]+)\/watch\?v=([a-zA-Z0-9_-]{11})/],
embed_template: '%{instance_url}/embed/%{video_id}',
autoplay_params: 'autoplay=1&loop=1'
}
}.freeze

# Detect platform from video URL
def video_platform
return nil unless video_url.present?

SUPPORTED_PLATFORMS.find do |platform, config|
config[:patterns].any? { |pattern| video_url.match?(pattern) }
end&.first
end

# Extract video ID from URL
def video_id
match_data = url_match_data
return nil unless match_data

# For federated platforms (PeerTube, Invidious), video_id is the second capture
match_data.captures.length > 1 ? match_data[2] : match_data[1]
end

# Extract instance URL for federated platforms (PeerTube, Invidious)
def video_instance_url
return nil unless [:peertube, :invidious].include?(video_platform)

match_data = url_match_data
match_data&.captures&.length.to_i > 1 ? match_data[1] : nil
end

# Generate complete embed URL with autoplay parameters
def video_embed_url
return nil unless video_platform && video_id

config = SUPPORTED_PLATFORMS[video_platform]
base_url = build_base_url(config)

"#{base_url}?#{config[:autoplay_params]}"
end

private

# Get regex match data for the current video URL
def url_match_data
return nil unless video_url.present? && video_platform.present?

config = SUPPORTED_PLATFORMS[video_platform]
config[:patterns].each do |pattern|
match = video_url.match(pattern)
return match if match
end

nil
end

# Build base embed URL from template
def build_base_url(config)
template = config[:embed_template]

if [:peertube, :invidious].include?(video_platform)
template % { instance_url: video_instance_url, video_id: video_id }
else
template % { video_id: video_id }
end
end

# Validation: ensure URL is from a supported platform
def video_url_is_supported_platform
return if video_platform.present?

errors.add(:video_url, :unsupported_platform)
end
end
10 changes: 10 additions & 0 deletions app/views/admin/splashpages/_form.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@
%label
= f.check_box :include_social_media
Display the social media links?
%h4
= t('admin.splashpages.form.video.title')
%hr
.form-group
= f.label :video_url
= f.url_field :video_url,
class: 'form-control',
placeholder: t('admin.splashpages.form.video.placeholder')
%p.help-block
= t('admin.splashpages.form.video.help_html').html_safe
%h4
Access
%hr
Expand Down
14 changes: 14 additions & 0 deletions app/views/conferences/_video.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- cache [splashpage, splashpage.video_url, '#splash#video'] do
- if splashpage.video_embed_url.present?
%section#video
.container
.row
.col-md-8.col-md-offset-2
.video-wrapper
%iframe#video-iframe{
src: splashpage.video_embed_url,
frameborder: "0",
allowfullscreen: "",
allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",
title: "Conference Video"
}
3 changes: 3 additions & 0 deletions app/views/conferences/show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
-# header/description
= render 'header', conference: @conference, venue: @conference.venue

-# Video section
= render 'video', splashpage: @conference.splashpage

-# calls for content, or program
- if @conference.splashpage.include_cfp
= render 'call_for_content', conference: @conference,
Expand Down
9 changes: 9 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,12 @@ en:
nickname: Nickname
biography: Biography
affiliation: Affiliation
splashpage:
video_url: Video URL
errors:
models:
splashpage:
attributes:
video_url:
invalid_url: must be a valid URL
unsupported_platform: must be from a supported platform (Youtube, Vimeo, Peertube, Invidious)
9 changes: 9 additions & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,12 @@ es:
nickname: Nickname
biography: Biografía
affiliation: Afiliación
splashpage:
video_url: URL del vídeo
errors:
models:
splashpage:
attributes:
video_url:
invalid_url: debe ser una URL válida
unsupported_platform: debe ser de una plataforma soportada (Youtube, Vimeo, Peertube, Invidious)
12 changes: 12 additions & 0 deletions config/locales/views/splashpages/en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
en:
admin:
splashpages:
form:
video:
title: Video
label: Video URL
placeholder: "https://www.youtube.com/watch?v=..."
help_html: |
Video URL to display on the splash page (will autoplay muted).
<br>
Supported: <strong>YouTube, Vimeo, PeerTube, Invidious</strong>
12 changes: 12 additions & 0 deletions config/locales/views/splashpages/es.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
es:
admin:
splashpages:
form:
video:
title: Vídeo
label: URL del vídeo
placeholder: "https://www.youtube.com/watch?v=..."
help_html: |
URL del vídeo para mostrar en la página de inicio (se reproducirá automáticamente silenciado).
<br>
Soportados: <strong>YouTube, Vimeo, PeerTube, Invidious</strong>
5 changes: 5 additions & 0 deletions db/migrate/20260208190303_add_video_url_to_splashpages.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddVideoUrlToSplashpages < ActiveRecord::Migration[7.0]
def change
add_column :splashpages, :video_url, :string
end
end
16 changes: 16 additions & 0 deletions spec/factories/splashpages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@
include_sponsors { true }
include_lodgings { true }
include_cfp { true }
video_url { 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' }
end

factory :splashpage_with_youtube_video do
public { true }
video_url { 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' }
end

factory :splashpage_with_vimeo_video do
public { true }
video_url { 'https://vimeo.com/123456789' }
end

factory :splashpage_with_peertube_video do
public { true }
video_url { 'https://peertube.example.com/videos/watch/abc-123-def' }
end
end
end
Loading
Loading