mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-12 05:28:28 +09:00
fix(app): stop other youtube embeds when one starts playing (#2642)
This commit is contained in:
1 parent
01fd11fea9
commit
5fea319f4e
2 files changed
+40
-6
No files matched your search
@@ -5,6 +5,7 @@ import {YOUTUBE_PROVIDER_NAME} from '@app/features/app/config/I18nDisplayConstan
|
||||
import styles from '@app/features/channel/components/embeds/media/EmbedYouTube.module.css';
|
||||
import {OverlayActionButton, OverlayPlayButton} from '@app/features/channel/components/embeds/media/MediaButtons';
|
||||
import {useNearViewport} from '@app/features/messaging/hooks/useNearViewport';
|
||||
import ActiveIframeEmbed from '@app/features/messaging/state/ActiveIframeEmbed';
|
||||
import {openExternalUrlWithWarning} from '@app/features/messaging/utils/ExternalLinkUtils';
|
||||
import * as ImageCacheUtils from '@app/features/messaging/utils/ImageCacheUtils';
|
||||
import {
|
||||
@@ -21,7 +22,7 @@ import {useLingui} from '@lingui/react/macro';
|
||||
import {ArrowSquareOutIcon, PlayIcon} from '@phosphor-icons/react';
|
||||
import {AnimatePresence, motion} from 'framer-motion';
|
||||
import {observer} from 'mobx-react-lite';
|
||||
import {type FC, useCallback, useEffect, useMemo, useState} from 'react';
|
||||
import {type FC, useCallback, useEffect, useId, useMemo, useState} from 'react';
|
||||
|
||||
const PLAY_VIDEO_DESCRIPTOR = msg({
|
||||
message: 'Play video',
|
||||
@@ -147,7 +148,8 @@ const Thumbnail: FC<ThumbnailProps> = observer(
|
||||
);
|
||||
export const EmbedYouTube: FC<EmbedYouTubeProps> = observer(({embed, width = YOUTUBE_CONFIG.DEFAULT_WIDTH}) => {
|
||||
const {i18n} = useLingui();
|
||||
const [hasInteracted, setHasInteracted] = useState(false);
|
||||
const embedId = useId();
|
||||
const hasInteracted = ActiveIframeEmbed.isActive(embedId);
|
||||
const posterSrc = embed.thumbnail?.proxy_url || '';
|
||||
const {ref: visibilityRef, isNearViewport} = useNearViewport<HTMLDivElement>({rememberKey: posterSrc});
|
||||
const [posterCacheAtMount] = useState(() => ({src: posterSrc, cached: ImageCacheUtils.hasImage(posterSrc)}));
|
||||
@@ -171,10 +173,14 @@ export const EmbedYouTube: FC<EmbedYouTubeProps> = observer(({embed, width = YOU
|
||||
);
|
||||
return cleanup;
|
||||
}, [isNearViewport, loadedPosterSrc, posterSrc]);
|
||||
const handleInitialPlay = useCallback((event: React.MouseEvent | React.KeyboardEvent) => {
|
||||
event.stopPropagation();
|
||||
setHasInteracted(true);
|
||||
}, []);
|
||||
const handleInitialPlay = useCallback(
|
||||
(event: React.MouseEvent | React.KeyboardEvent) => {
|
||||
event.stopPropagation();
|
||||
ActiveIframeEmbed.claim(embedId);
|
||||
},
|
||||
[embedId],
|
||||
);
|
||||
useEffect(() => () => ActiveIframeEmbed.release(embedId), [embedId]);
|
||||
const handleOpenInNewTab = useCallback(
|
||||
(event: React.MouseEvent | React.KeyboardEvent) => {
|
||||
event.stopPropagation();
|
||||
@@ -250,6 +256,7 @@ export const EmbedYouTube: FC<EmbedYouTubeProps> = observer(({embed, width = YOU
|
||||
sandbox="allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"
|
||||
src={embedVideoUrl.toString()}
|
||||
className={styles.iframe}
|
||||
scrolling="no"
|
||||
data-embed-media="true"
|
||||
aria-label={embed.title || i18n._(VIDEO_DESCRIPTOR, {youtubeProviderName: YOUTUBE_PROVIDER_NAME})}
|
||||
data-flx="channel.embeds.media.embed-you-tube.iframe"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {makeAutoObservable} from 'mobx';
|
||||
|
||||
class ActiveIframeEmbed {
|
||||
activeId: string | null = null;
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this, {}, {autoBind: true});
|
||||
}
|
||||
|
||||
isActive(id: string): boolean {
|
||||
return this.activeId === id;
|
||||
}
|
||||
|
||||
claim(id: string): void {
|
||||
this.activeId = id;
|
||||
}
|
||||
|
||||
release(id: string): void {
|
||||
if (this.activeId === id) {
|
||||
this.activeId = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new ActiveIframeEmbed();
|
||||
Reference in new issue
Block a user