mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 19:36:56 -08:00
use JS IntersectionObserver to lazy load youtube videos
This commit is contained in:
parent
dba016e05e
commit
760477f00c
5 changed files with 97 additions and 4 deletions
|
@ -1072,13 +1072,14 @@ class Post(db.Model):
|
|||
file = File.query.get(self.image_id)
|
||||
file.delete_from_disk()
|
||||
|
||||
def youtube_embed(self) -> str:
|
||||
def youtube_embed(self, rel=True) -> str:
|
||||
if self.url:
|
||||
parsed_url = urlparse(self.url)
|
||||
query_params = parse_qs(parsed_url.query)
|
||||
|
||||
if 'v' in query_params:
|
||||
video_id = query_params.pop('v')[0]
|
||||
if rel:
|
||||
query_params['rel'] = '0'
|
||||
new_query = urlencode(query_params, doseq=True)
|
||||
return f'{video_id}?{new_query}'
|
||||
|
@ -1087,6 +1088,7 @@ class Post(db.Model):
|
|||
video_id = parsed_url.path.split('/shorts/')[1].split('/')[0]
|
||||
if 't' in query_params:
|
||||
query_params['start'] = query_params.pop('t')[0]
|
||||
if rel:
|
||||
query_params['rel'] = '0'
|
||||
new_query = urlencode(query_params, doseq=True)
|
||||
return f'{video_id}?{new_query}'
|
||||
|
|
|
@ -10,6 +10,7 @@ if(!setTheme) {
|
|||
|
||||
// fires after DOM is ready for manipulation
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
setupYouTubeLazyLoad();
|
||||
setupCommunityNameInput();
|
||||
setupShowMoreLinks();
|
||||
setupConfirmFirst();
|
||||
|
@ -27,6 +28,42 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
setupLightboxPostBody();
|
||||
});
|
||||
|
||||
function setupYouTubeLazyLoad() {
|
||||
const lazyVideos = document.querySelectorAll(".video-wrapper");
|
||||
|
||||
if ("IntersectionObserver" in window) {
|
||||
let videoObserver = new IntersectionObserver((entries, observer) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
let videoWrapper = entry.target;
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.src = videoWrapper.getAttribute("data-src");
|
||||
iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen";
|
||||
|
||||
videoWrapper.innerHTML = "";
|
||||
videoWrapper.appendChild(iframe);
|
||||
|
||||
videoObserver.unobserve(videoWrapper);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
lazyVideos.forEach((video) => {
|
||||
videoObserver.observe(video);
|
||||
});
|
||||
} else {
|
||||
// Fallback for older browsers
|
||||
lazyVideos.forEach((video) => {
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.src = video.getAttribute("data-src");
|
||||
iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen";
|
||||
|
||||
video.innerHTML = "";
|
||||
video.appendChild(iframe);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// All elements with the class "showElement" will show the DOM element referenced by the data-id attribute
|
||||
function setupShowElementLinks() {
|
||||
var elements = document.querySelectorAll('.showElement');
|
||||
|
|
|
@ -911,6 +911,31 @@ div.navbar {
|
|||
background-color: white;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.post_teaser_video_preview .video-wrapper {
|
||||
position: relative;
|
||||
padding-bottom: 56.25%;
|
||||
/* 16:9 aspect ratio */
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
background-color: #000;
|
||||
}
|
||||
.post_teaser_video_preview .video-wrapper img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
cursor: pointer;
|
||||
}
|
||||
.post_teaser_video_preview .video-wrapper iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.max_width_512 {
|
||||
max-width: 512px;
|
||||
|
|
|
@ -503,6 +503,33 @@ div.navbar {
|
|||
background-color: white;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.video-wrapper {
|
||||
position: relative;
|
||||
padding-bottom: 56.25%; /* 16:9 aspect ratio */
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.video-wrapper img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.video-wrapper iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.max_width_512 {
|
||||
|
|
|
@ -43,7 +43,9 @@
|
|||
<div style="padding-bottom: 56.25%; position: relative;"><iframe style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;" src="{{ post.url.replace('redgifs.com/watch/', 'redgifs.com/ifr/') }}" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; fullscreen" width="100%" height="100%" frameborder="0"></iframe></div>
|
||||
{% endif -%}
|
||||
{% if 'youtube.com' in post.url -%}
|
||||
<div style="padding-bottom: 56.25%; position: relative;"><iframe style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;" src="https://www.youtube.com/embed/{{ post.youtube_embed() }}" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; fullscreen" width="100%" height="100%" frameborder="0"></iframe></div>
|
||||
<div class="video-wrapper" data-src="https://www.youtube.com/embed/{{ post.youtube_embed() }}">
|
||||
<img src="https://img.youtube.com/vi/{{ post.youtube_embed(rel=False) }}/hqdefault.jpg" alt="Video Thumbnail">
|
||||
</div>
|
||||
{% endif -%}
|
||||
{% if 'videos/watch' in post.url -%}
|
||||
<div style="padding-bottom: 56.25%; position: relative;"><iframe style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;" src="{{ post.peertube_embed() }}" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; fullscreen" width="100%" height="100%" frameborder="0"></iframe></div>
|
||||
|
|
Loading…
Add table
Reference in a new issue