<div _="
on 'trix-paste'(paste)
if paste.string is not empty then set text to paste.string end
if paste.html is not empty
set div to document.createElement('div')
set innerHTML of div to paste.html
set text to textContent of div
end
set patterns to []
-- https://youtu.be/Ul-GsIzkjIY
js return /^https:\/\/youtu\.be\/([\w-]{11})$/ end
append { embed: 'youtubes', regex: it } to patterns
-- https://www.youtube.com/watch?v=Ul-GsIzkjIY
js return /^https:\/\/www.youtube\.com\/watch\?v=([\w-]{11})$/ end
append { embed: 'youtubes', regex: it } to patterns
-- more embed patterns like vimeo etc.
for pattern in patterns
get text.trim().match(pattern.regex)
if it exists
fetch `/trix_embeds/${pattern.embed}/${it[1]}` as Object
make a Trix.Attachment from result then set attachment to it
set editor to the editor of the first <trix-editor/> in me
tell editor
setSelectedRange(paste.range) on you
insertLineBreak() to you
insertAttachment(attachment) to you
insertLineBreak() to you
end
break
end
end
end">
<%= f.rich_text_area :text, placeholder: placeholder, class: "textarea trix-content min-h-[150px] max-h-[300px] sm:max-h-fit overflow-y-auto sm:overflow-y-hidden" %>
</div>
<%= form_for(@article, html: { class: "form" }) do |f| %>
<%= render 'shared/form_errors', object: f.object %>
<div>
<%= f.label :title, class: "label" %>
<%= f.text_field :title, class: 'input text-lg lg:text-xl font-semibold' %>
</div>
<%= render "shared/trix_editor", f: f, method: :text, placeholder: "Write your article here..." %>
<div>
<%= f.submit %>
</div>
<% end %>
class TrixEmbeds::Youtube
include ActiveModel::Model
include ActiveModel::Attributes
include GlobalID::Identification
include ActionText::Attachable
attribute :id
def self.find(id)
new(id: id)
end
def thumbnail_url
"https://i3.ytimg.com/vi/#{id}/maxresdefault.jpg"
end
def to_trix_content_attachment_partial_path
"trix_embeds/youtubes/thumbnail"
end
end
class TrixEmbeds::YoutubesController < ApplicationController
def show
@youtube = TrixEmbeds::Youtube.new(id: params[:id])
render json: {
sgid: @youtube.attachable_sgid,
contentType: 'application/youtube-video.html',
content: render_to_string(partial: "thumbnail", locals: { youtube: @youtube }, formats: [:html])
}
end
end
<div class="relative">
<%= image_tag youtube.thumbnail_url %>
<div class="absolute top-[50%] left-[50%] flex items-center space-x-1 bg-cream-100 bg-opacity-75 text-sm text-cream-700 pl-2.5 pr-4 py-2 rounded-full" style="transform: translate(-50%, -50%);">
<%= heroicon "play", variant: :solid, options: { class: "w-5 h-5 flex-shrink-0" } %>
<span class="whitespace-nowrap">Video will play when saved</span>
</div>
</div>
<div class="relative !aspect-w-16 !aspect-h-9 bg-white rounded-lg overflow-hidden">
<iframe class="absolute inset-0 w-full h-full"
src="https://www.youtube.com/embed/<%= youtube.id %>"
allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'
allowfullscreen
frameborder="0"></iframe>
</div>
Martin Sojka, Maker of CodeSnips