From 4a4e0daa1a8d1a78d4d1cb823ce310882317c8cd Mon Sep 17 00:00:00 2001 From: Chewbacca Date: Fri, 11 Nov 2022 09:57:39 -0500 Subject: [PATCH] Autoplay videos from Rumble --- app/soapbox/components/status-media.tsx | 3 +- .../features/status/components/card.tsx | 25 +--------------- app/soapbox/utils/__tests__/media.test.ts | 17 +++++++++++ app/soapbox/utils/media.ts | 30 ++++++++++++++++++- 4 files changed, 49 insertions(+), 26 deletions(-) create mode 100644 app/soapbox/utils/__tests__/media.test.ts diff --git a/app/soapbox/components/status-media.tsx b/app/soapbox/components/status-media.tsx index 4445e67b5..195e749f1 100644 --- a/app/soapbox/components/status-media.tsx +++ b/app/soapbox/components/status-media.tsx @@ -7,6 +7,7 @@ import Card from 'soapbox/features/status/components/card'; import Bundle from 'soapbox/features/ui/components/bundle'; import { MediaGallery, Video, Audio } from 'soapbox/features/ui/util/async-components'; import { useAppDispatch } from 'soapbox/hooks'; +import { addAutoPlay } from 'soapbox/utils/media'; import type { List as ImmutableList } from 'immutable'; import type { Status, Attachment } from 'soapbox/types/entities'; @@ -93,7 +94,7 @@ const StatusMedia: React.FC = ({ ref={setRef} className='status-card__image status-card-video' style={height ? { height } : undefined} - dangerouslySetInnerHTML={{ __html: status.card.html }} + dangerouslySetInnerHTML={{ __html: addAutoPlay(status.card.html) }} /> ); diff --git a/app/soapbox/features/status/components/card.tsx b/app/soapbox/features/status/components/card.tsx index 3d83020fe..7e976e5bb 100644 --- a/app/soapbox/features/status/components/card.tsx +++ b/app/soapbox/features/status/components/card.tsx @@ -6,6 +6,7 @@ import Blurhash from 'soapbox/components/blurhash'; import Icon from 'soapbox/components/icon'; import { HStack, Stack, Text } from 'soapbox/components/ui'; import { normalizeAttachment } from 'soapbox/normalizers'; +import { addAutoPlay } from 'soapbox/utils/media'; import type { Card as CardEntity, Attachment } from 'soapbox/types/entities'; @@ -19,30 +20,6 @@ const trim = (text: string, len: number): string => { return text.substring(0, cut) + (text.length > len ? '…' : ''); }; -const domParser = new DOMParser(); - -const addAutoPlay = (html: string): string => { - const document = domParser.parseFromString(html, 'text/html').documentElement; - const iframe = document.querySelector('iframe'); - - if (iframe) { - if (iframe.src.includes('?')) { - iframe.src += '&'; - } else { - iframe.src += '?'; - } - - iframe.src += 'autoplay=1&auto_play=1'; - iframe.allow = 'autoplay'; - - // 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; - } - - return html; -}; - interface ICard { card: CardEntity, maxTitle?: number, diff --git a/app/soapbox/utils/__tests__/media.test.ts b/app/soapbox/utils/__tests__/media.test.ts new file mode 100644 index 000000000..815b12321 --- /dev/null +++ b/app/soapbox/utils/__tests__/media.test.ts @@ -0,0 +1,17 @@ +import { addAutoPlay } from '../media'; + +describe('addAutoPlay()', () => { + describe('when the provider is Rumble', () => { + it('adds the correct query parameters to the src', () => { + const html = ''; + expect(addAutoPlay(html)).toEqual(''); + }); + }); + + describe('when the provider is not Rumble', () => { + it('adds the correct query parameters to the src', () => { + const html = ''; + expect(addAutoPlay(html)).toEqual(''); + }); + }); +}); diff --git a/app/soapbox/utils/media.ts b/app/soapbox/utils/media.ts index 7947ef91f..27a1f6ba0 100644 --- a/app/soapbox/utils/media.ts +++ b/app/soapbox/utils/media.ts @@ -51,4 +51,32 @@ const getVideoDuration = (file: File): Promise => { return promise; }; -export { getVideoDuration, formatBytes, truncateFilename }; +const domParser = new DOMParser(); + +const addAutoPlay = (html: string): string => { + const document = domParser.parseFromString(html, 'text/html').documentElement; + const iframe = document.querySelector('iframe'); + + if (iframe) { + if (iframe.src.includes('?')) { + iframe.src += '&'; + } else { + iframe.src += '?'; + } + + if (new URL(iframe.src).host === 'rumble.com') { + iframe.src += 'pub=7a20&autoplay=2'; + } else { + iframe.src += 'autoplay=1&auto_play=1'; + iframe.allow = 'autoplay'; + } + + // 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; + } + + return html; +}; + +export { getVideoDuration, formatBytes, truncateFilename, addAutoPlay };