From 6df9a99c6e087c712c3bd32a18c7774800abb8d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Sun, 15 Feb 2026 15:10:32 +0100 Subject: [PATCH] nicolium: allow youtube embed start time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- .../pl-fe/src/components/preview-card.tsx | 31 +++++++++++++++++-- .../compose-event/tabs/edit-event.tsx | 2 +- packages/pl-fe/src/utils/media.ts | 30 +----------------- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/packages/pl-fe/src/components/preview-card.tsx b/packages/pl-fe/src/components/preview-card.tsx index cb0523c33..71344f9f2 100644 --- a/packages/pl-fe/src/components/preview-card.tsx +++ b/packages/pl-fe/src/components/preview-card.tsx @@ -15,7 +15,6 @@ import Icon from '@/components/ui/icon'; import Stack from '@/components/ui/stack'; import Text from '@/components/ui/text'; import Emojify from '@/features/emoji/emojify'; -import { addAutoPlay } from '@/utils/media'; import { getTextDirection } from '@/utils/rtl'; import HoverAccountWrapper from './hover-account-wrapper'; @@ -33,6 +32,34 @@ interface IPreviewCard { horizontal?: boolean; } +const domParser = new DOMParser(); + +const handleIframeUrl = (html: string, url: string, providerName: string) => { + const document = domParser.parseFromString(html, 'text/html').documentElement; + const iframe = document.querySelector('iframe'); + const startTime = new URL(url).searchParams.get('t'); + + if (iframe) { + const iframeUrl = new URL(iframe.src); + + iframeUrl.searchParams.set('autoplay', '1'); + iframeUrl.searchParams.set('auto_play', '1'); + + if (providerName === 'YouTube') { + iframeUrl.searchParams.set('start', startTime ?? ''); + iframe.referrerPolicy = 'strict-origin-when-cross-origin'; + } + + iframe.allow = 'autoplay'; + + iframe.src = iframeUrl.href; + + return iframe.outerHTML; + } + + return ''; +}; + /** Displays a Mastodon link preview. Similar to OEmbed. */ const PreviewCard: React.FC = ({ card, @@ -93,7 +120,7 @@ const PreviewCard: React.FC = ({ }; const renderVideo = () => { - const content = { __html: addAutoPlay(card.html) }; + const content = { __html: handleIframeUrl(card.html, card.url, card.provider_name) }; const ratio = getRatio(card); const height = width / ratio; diff --git a/packages/pl-fe/src/features/compose-event/tabs/edit-event.tsx b/packages/pl-fe/src/features/compose-event/tabs/edit-event.tsx index ac33cc6a4..05af13158 100644 --- a/packages/pl-fe/src/features/compose-event/tabs/edit-event.tsx +++ b/packages/pl-fe/src/features/compose-event/tabs/edit-event.tsx @@ -304,7 +304,7 @@ const EditEvent: React.FC = ({ statusId }) => { diff --git a/packages/pl-fe/src/utils/media.ts b/packages/pl-fe/src/utils/media.ts index 0254fa863..cf82c234c 100644 --- a/packages/pl-fe/src/utils/media.ts +++ b/packages/pl-fe/src/utils/media.ts @@ -52,32 +52,4 @@ const getVideoDuration = (file: File): Promise => { return promise; }; -const domParser = new DOMParser(); - -/** Try adding autoplay to an iframe embed for platforms such as YouTube. */ -const addAutoPlay = (html: string): string => { - try { - const document = domParser.parseFromString(html, 'text/html').documentElement; - const iframe = document.querySelector('iframe'); - - if (iframe) { - const url = new URL(iframe.src); - - url.searchParams.append('autoplay', '1'); - url.searchParams.append('auto_play', '1'); - iframe.allow = 'autoplay'; - - iframe.src = url.toString(); - - // DOM parser creates html/body elements around original HTML fragment, - // so we need to get innerHTML out of the body and not the entire document - return (document.querySelector('body') as HTMLBodyElement).innerHTML; - } - } catch (e) { - return html; - } - - return html; -}; - -export { getVideoDuration, formatBytes, truncateFilename, addAutoPlay }; +export { getVideoDuration, formatBytes, truncateFilename };