Files
discord-decomp/modules/media_viewer/native/components/MediaModalYoutube.tsx
T
2026-11-01 12:12:55 +02:00

153 lines
5.0 KiB
TypeScript

// Metro module 12315 (f12316).
import { memo, useState, useRef, useEffect, useCallback } from "react";
import { YOUTUBE_EMBED_PAGE_TYPE } from "../../../../Constants";
import MediaModalWebView, { PlayerState } from "./MediaModalWebView";
import usePrevious from "../../../../hooks/usePrevious";
import { MediaViewerAnalytics } from "../../MediaViewerAnalyticsManager";
import { getYoutubeVideoIdFromURI, getYoutubeClipVideoIdFromURI } from "../MediaSourceUtil";
import MediaModalYoutubeEmbedError from "./MediaModalYoutubeEmbedError";
import { isAndroid } from "../../../../utils/PlatformUtils";
const baseUrl = `https:${window.GLOBAL_ENV.WEBAPP_ENDPOINT}`;
const r32 = memo(function({ visible, style, source, ...props }) {
const [state, setState] = useState(PlayerState.UNREADY);
const [state2, setState2] = useState(void 0);
const previous = usePrevious(state);
let c19788_4 = previous;
const previous2 = usePrevious(visible);
let c19788_5 = previous2;
const ref = useRef(null);
useEffect(() => {
MediaViewerAnalytics.trackMessageEmbedsActionCompleted({
platform: "youtube",
action: "attempted"
});
}, []);
const callback = useCallback((a0) => {
const r11 = JSON.parse(a0);
const { type, value } = r11;
if (type === "onReady") {
setState(value === "-1" ? PlayerState.ERRORED : PlayerState.READY);
} else if (type === "onError") {
let r62 = value;
if (typeof r62 === "number") {
r62 = value.toString();
}
const error = r62 === "2" ? "invalid_parameter" : r62 === "5" ? "html5_error" : r62 === "100" ? "video_not_found" : r62 !== "101" ? r62 !== "150" ? "unknown" : "embed_not_allowed" : "embed_not_allowed";
setState(PlayerState.ERRORED);
setState2(error);
MediaViewerAnalytics.trackMessageEmbedsActionCompleted({
platform: "youtube",
action: "errored",
error
});
} else if (type === "onStateChange") {
const r53 = ({
"-1": PlayerState.UNSTARTED,
0: PlayerState.ENDED,
1: PlayerState.PLAYING,
2: PlayerState.PAUSED,
3: PlayerState.BUFFERING,
5: PlayerState.VIDEO_CUED
})[value];
if (r53 != null && r53 in PlayerState) {
setState(r53);
}
}
}, []);
useEffect(() => {
if (ref.current != null && state !== PlayerState.UNREADY) {
if ((visible ? c19788_4 === PlayerState.UNREADY : visible) && state === PlayerState.READY) {
ref.current.injectJavaScript("window.player.playVideo(); true;");
}
if (visible ? !c19788_5 : visible) {
ref.current.injectJavaScript("window.player.playVideo(); true;");
}
if (visible ? !visible : c19788_5) {
ref.current.injectJavaScript("window.player.pauseVideo(); true;");
}
}
}, [ref, visible, previous2, previous, state]);
let r71 = getYoutubeVideoIdFromURI(source.uri);
if (r71 == null) {
r71 = getYoutubeClipVideoIdFromURI(source.uri);
}
if (r71 == null) {
return null;
}
if (state === PlayerState.ERRORED && state2 === "embed_not_allowed") {
return <MediaModalYoutubeEmbedError videoId={r71.videoId} />;
}
const props2 = isAndroid() ? {
nestedScrollEnabled: true,
overScrollMode: "never",
domStorageEnabled: true,
mixedContentMode: "compatibility"
} : {};
const r3 = r71.start == null;
let r27 = "";
const r26 = r3 ? "" : `'start': ${r71.start},`;
const r25 = r71.clip == null ? "" : `'clip': '${r71.clip}',`;
if (r71.clipt != null) {
r27 = `'clipt': '${r71.clipt}',`;
}
return <MediaModalWebView key={r71.videoId} ref={ref} style={style} source={{
html: `
<html>
<head>
<meta name="viewport" content="initial-scale=1">
<style>
* {
margin: 0;
padding: 0;
background-color: #000;
}
</style>
<script>${`
const tag = document.createElement('script');
tag.setAttribute('src', "https://www.youtube.com/iframe_api");
document.head.appendChild(tag);
function onYouTubeIframeAPIReady() {
window.player = new YT.Player('player', {
height: '100%',
width: '100%',
videoId: '${r71.videoId}',
playerVars: {
'playsinline': 1,
'fs': 0,
'pageType': ${YOUTUBE_EMBED_PAGE_TYPE},
${r27}
${r25}
${r26}
},
events: {
'onReady': (e) => {
window.ReactNativeWebView.postMessage(
JSON.stringify({type: 'onReady', value: window.player.getPlayerState()})
);
},
'onError': (e) => {
window.ReactNativeWebView.postMessage(
JSON.stringify({type: 'onError', value: e.data})
);
},
'onStateChange': (e) => {
window.ReactNativeWebView.postMessage(
JSON.stringify({type: 'onStateChange', value: e.data})
);
}
}
});
}
`}</script>
</head>
<body>
<div id="player"></div>
</body>
</html>
`,
baseUrl
}} baseURL={baseUrl} playerState={state} onDataReceived={callback} javaScriptEnabled javaScriptCanOpenWindowsAutomatically {...props2} {...props} />;
});
export default r32;