Skip to content

Commit 6183b17

Browse files
committed
chore: better video autoplay
1 parent 6aac7a3 commit 6183b17

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

crates/rostra-web-ui/src/layout.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,42 @@ pub(crate) fn render_html_footer() -> Markup {
204204
"#))
205205
}
206206

207+
// Play/pause videos based on visibility
208+
script {
209+
(PreEscaped(r#"
210+
document.addEventListener('DOMContentLoaded', () => {
211+
const videoObserver = new IntersectionObserver((entries) => {
212+
entries.forEach(entry => {
213+
const video = entry.target;
214+
if (entry.isIntersecting) {
215+
video.play().catch(() => {});
216+
} else {
217+
video.pause();
218+
}
219+
});
220+
}, { threshold: 0.5 });
221+
222+
// Observe existing videos
223+
document.querySelectorAll('.m-rostraMedia__video').forEach(v => videoObserver.observe(v));
224+
225+
// Observe new videos added dynamically (for AJAX/htmx)
226+
const mutationObserver = new MutationObserver((mutations) => {
227+
mutations.forEach(mutation => {
228+
mutation.addedNodes.forEach(node => {
229+
if (node.nodeType === 1) {
230+
node.querySelectorAll?.('.m-rostraMedia__video').forEach(v => videoObserver.observe(v));
231+
if (node.classList?.contains('m-rostraMedia__video')) {
232+
videoObserver.observe(node);
233+
}
234+
}
235+
});
236+
});
237+
});
238+
mutationObserver.observe(document.body, { childList: true, subtree: true });
239+
});
240+
"#))
241+
}
242+
207243
// Alpine.js initialization
208244
script {
209245
(PreEscaped(r#"

crates/rostra-web-ui/src/routes/content/filters.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,10 @@ where
286286
r#"<span class="m-rostraMedia"><img src="{url_escaped}" alt="{alt_escaped}"/></span>"#
287287
)
288288
} else if media.mime.starts_with("video/") {
289-
// Render as video player
289+
// Render as video player - plays when visible via
290+
// IntersectionObserver
290291
format!(
291-
r#"<span class="m-rostraMedia"><video src="{url_escaped}" controls class="m-rostraMedia__video"></video></span>"#
292+
r#"<span class="m-rostraMedia"><video src="{url_escaped}" controls muted playsinline class="m-rostraMedia__video"></video></span>"#
292293
)
293294
} else {
294295
// Render as download link

crates/rostra-web-ui/src/routes/media.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,10 @@ pub async fn list(
236236
video
237237
src=(format!("/ui/media/{}/{}", author, media.event_id))
238238
."o-mediaList__videoThumbnail"
239-
preload="metadata"
239+
autoplay
240+
muted
241+
loop
242+
playsinline
240243
{}
241244
} @else {
242245
div ."o-mediaList__fileInfo" {

0 commit comments

Comments
 (0)