From 15fcff318b0d37092b3336e5b5ee64f813c710e8 Mon Sep 17 00:00:00 2001 From: Jocky Date: Thu, 7 May 2026 19:09:11 +0800 Subject: [PATCH] chore: lazy load historical changelog videos --- changelog-toc.js | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ en/changelog.mdx | 54 ++++++++++++++++++++--------------------- zh/changelog.mdx | 54 ++++++++++++++++++++--------------------- 3 files changed, 116 insertions(+), 54 deletions(-) diff --git a/changelog-toc.js b/changelog-toc.js index e8f3564..db3e30b 100644 --- a/changelog-toc.js +++ b/changelog-toc.js @@ -3,6 +3,7 @@ var activeId = null; var scrollScheduled = false; var refreshTimer = null; + var lazyVideoObserver = null; function isChangelogPage() { var currentPath = document.documentElement.getAttribute("data-current-path") || window.location.pathname; @@ -35,6 +36,8 @@ return; } + setupLazyVideos(); + var tocItems = Array.prototype.slice.call(document.querySelectorAll("#table-of-contents .toc-item")); var tocByHash = new Map(); @@ -55,6 +58,65 @@ updateActiveState(true); } + function hydrateLazyVideo(video) { + var src = video.getAttribute("data-src"); + + if (!src) { + return; + } + + video.setAttribute("src", src); + video.removeAttribute("data-src"); + video.setAttribute("data-changelog-lazy-loaded", "true"); + video.load(); + + if (video.hasAttribute("autoplay")) { + var playPromise = video.play(); + if (playPromise && typeof playPromise.catch === "function") { + playPromise.catch(function () {}); + } + } + } + + function setupLazyVideos() { + var lazyVideos = Array.prototype.slice.call( + document.querySelectorAll("video.changelog-lazy-video[data-src]:not([data-changelog-lazy-bound])") + ); + + if (!lazyVideos.length) { + return; + } + + if (!("IntersectionObserver" in window)) { + lazyVideos.forEach(hydrateLazyVideo); + return; + } + + if (!lazyVideoObserver) { + lazyVideoObserver = new IntersectionObserver( + function (entries) { + entries.forEach(function (entry) { + if (!entry.isIntersecting) { + return; + } + + hydrateLazyVideo(entry.target); + lazyVideoObserver.unobserve(entry.target); + }); + }, + { + rootMargin: "800px 0px", + threshold: 0.01, + } + ); + } + + lazyVideos.forEach(function (video) { + video.setAttribute("data-changelog-lazy-bound", "true"); + lazyVideoObserver.observe(video); + }); + } + function scheduleCollectPairs() { window.clearTimeout(refreshTimer); refreshTimer = window.setTimeout(collectPairs, 100); diff --git a/en/changelog.mdx b/en/changelog.mdx index 3ae8aac..a20a34d 100644 --- a/en/changelog.mdx +++ b/en/changelog.mdx @@ -131,7 +131,7 @@ When you open a linked record, Teable shows a visual connection line to make the A brand-new automation trigger: **When email received**. Connect any IMAP mailbox and automatically capture incoming emails into Teable — perfect for managing partnerships, customer support, and building a knowledge base. -