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

272 lines
10 KiB
TypeScript

// Metro module 8133 (f8134).
import { createElement, useCallback, useEffect, useRef, useId } from "react";
import { Image as Image2, Modal, StyleSheet, View } from "react-native";
import AppFreezeStore from "../../../panels/morphable/AppFreezeStore";
import AppStateStore from "../../../../stores/native/AppStateStore";
import { AppStates, Base64GIFPrefix, Base64JPEGPrefix } from "../../../../Constants";
import { MediaViewerSourcesStore } from "../useMediaViewerSources";
import { useMediaViewerSyncer } from "../useMediaViewerSyncer";
import { useVideoStateStore, setPausedState } from "../useVideoControls";
import { useStateFromStores } from "../../../../_bundle/Module589";
import { isIOS } from "../../../../utils/PlatformUtils";
import { getVideoSourceType, VideoSourceType, getSelectedMediaSource } from "../MediaSourceUtil";
import NativePortalView, { createPortalControls, isPortalExpired } from "../../../../components_native/common/NativePortalView";
import MediaModalTiktok, { createTiktokVideoControls } from "./MediaModalTiktok";
import MediaModalWebVideoFile, { createWebFileVideoControls } from "./MediaModalWebVideoFile";
import { createVideoControls, VideoComponent } from "../../../../components_native/common/Video";
import { clearCurrentFocusAndDismissKeyboard } from "../../../../utils/native/KeyboardManagerUtils";
import { unlockOrientation, lockOrientationForiOS } from "../../../device/native/DeviceOrientation";
import { triggerHapticFeedback } from "../../../haptics/HapticUtils.native";
import HapticFeedbackTypes from "../../../haptics/HapticFeedbackTypes";
import ActionSheetActionCreators from "../../../action_sheet/native/ActionSheetActionCreators";
import MediaModalOverlay from "./overlay/MediaModalOverlay";
import { useMediaPlayerMutedStore } from "../MediaPlayerMuteManager";
import MediaModalYoutube from "./MediaModalYoutube";
import MediaModalLoader from "./MediaModalLoader";
import FastImage from "../../../../components_native/common/FastImage";
import MediaViewer from "./MediaViewer";
export default function MediaModal(props) {
const { originLayout, initialIndex = 0 } = props;
let stateFromStores, ref, ref2, id, ref3, callback2, ref4, callback3, mediaPlayerMutedStore;
let c16279_0 = initialIndex;
const { initialIndexVideoStartTime, isRNModal = false, swipeVelocityThreshold = 1000, onClose, onCloseCallback, shareable: shareable2 = true } = props;
const shareable = shareable2;
const { disableDownload, disableMediaOverlayButton, disableMediaOverlayFooter, contextName, contextIcon, onEndReached, onEndReachedThreshold, onIndexChange } = props;
stateFromStores = void 0;
ref = void 0;
ref2 = void 0;
id = void 0;
ref3 = void 0;
callback2 = void 0;
ref4 = void 0;
callback3 = void 0;
mediaPlayerMutedStore = void 0;
const mediaViewerSyncer = useMediaViewerSyncer({
sources: MediaViewerSourcesStore.useField("sources"),
initialIndex,
onEndReached,
onEndReachedThreshold
});
const videoStateStore = useVideoStateStore((a0) => a0.paused);
const callback4 = useCallback(() => {
if (onClose != null) {
onClose();
}
if (onCloseCallback != null) {
onCloseCallback();
}
}, [onCloseCallback, onClose]);
useEffect(() => () => {
MediaViewerSourcesStore.resetState();
}, []);
stateFromStores = useStateFromStores([AppStateStore], () => AppStateStore.getState());
ref = useRef(stateFromStores);
ref2 = useRef(videoStateStore);
id = useId();
useEffect(() => {
AppFreezeStore.getState().requestFreezeLock({
lockEnabled: true,
key: id
});
return () => {
AppFreezeStore.getState().requestFreezeLock({
lockEnabled: false,
key: id
});
};
}, [id]);
useEffect(() => {
if (isIOS() && ref.current !== stateFromStores) {
L10: {
if (AppStates.BACKGROUND === stateFromStores) {
ref2.current = videoStateStore;
setPausedState(true);
} else {
if (AppStates.ACTIVE !== stateFromStores && AppStates.INACTIVE !== stateFromStores) {
break L10;
}
if (!(ref2.current || ref.current !== AppStates.BACKGROUND)) {
setPausedState(false);
}
}
}
ref2.current = videoStateStore;
ref.current = stateFromStores;
}
}, [stateFromStores, videoStateStore]);
ref3 = useRef({});
callback2 = useCallback((a0, a1) => {
const videoSourceType = getVideoSourceType(a1);
const r17 = `${a1}_${a0}`;
const r21 = ref3.current[r17];
if (r21 != null) {
return r21;
}
const r39 = VideoSourceType.PORTAL === videoSourceType ? createPortalControls(a1.portal) : VideoSourceType.TIKTOK_IFRAME === videoSourceType ? createTiktokVideoControls() : VideoSourceType.WEB_FILE_IFRAME === videoSourceType ? createWebFileVideoControls() : createVideoControls(setPausedState);
ref3.current[r17] = r39;
return r39;
}, []);
ref4 = useRef({});
callback3 = useCallback((a0, a1, a2) => {
let c26114_1;
if (a0 === c16279_0 && initialIndexVideoStartTime != null) {
const r11 = ref4.current[a0];
if (r11 != null && r11.oldOnLoad === a2) {
return r11.callback;
}
const callback = function callback() {
if (initialIndexVideoStartTime != null) {
c26114_1.seek(initialIndexVideoStartTime);
if (a2 != null) {
a2();
}
}
};
c26114_1 = callback2(a0, a1);
ref4.current[a0] = {
callback,
oldOnLoad: a2
};
return callback;
}
return a2;
}, [callback2, initialIndex, initialIndexVideoStartTime]);
useEffect(() => {
clearCurrentFocusAndDismissKeyboard();
unlockOrientation({
unlockAfterRotatingToPreviousLock: false
});
return () => lockOrientationForiOS();
}, []);
const callback5 = useCallback(() => {
if (shareable) {
const selectedMediaSource = getSelectedMediaSource(mediaViewerSyncer);
if (selectedMediaSource != null) {
triggerHapticFeedback(HapticFeedbackTypes.IMPACT_LIGHT);
ActionSheetActionCreators.openLazy(import("./MediaShareActions"), "MediaShareActionSheet", {
source: selectedMediaSource,
disableDownload,
shareable
});
}
}
}, [disableDownload, shareable, mediaViewerSyncer]);
const callback6 = useCallback((a0, a1) => <MediaModalOverlay syncer={mediaViewerSyncer} getVideoControls={callback2} onClose={a0} shareable={shareable} disableDownload={disableDownload} disableMediaOverlayButton={disableMediaOverlayButton} disableMediaOverlayFooter={disableMediaOverlayFooter} contextName={contextName} contextIcon={contextIcon} overlayEnabled={a1} onIndexChange={onIndexChange} />, [mediaViewerSyncer, callback2, shareable, disableDownload, disableMediaOverlayButton, disableMediaOverlayFooter, contextName, contextIcon, onIndexChange]);
mediaPlayerMutedStore = useMediaPlayerMutedStore((a0) => a0.isMuted);
const r110 = <MediaViewer originLayout={originLayout} swipeVelocityThreshold={swipeVelocityThreshold} onClose={callback4} onLongPress={callback5} syncer={mediaViewerSyncer} renderMedia={useCallback(({ source, index, key, visible, hasSpoiler, pointerEvents, ...rest }) => {
let r104;
const paused = (visible ? hasSpoiler : !visible) || videoStateStore;
let muted = mediaPlayerMutedStore;
if (!mediaPlayerMutedStore) {
muted = source.isGIFV === true;
}
if (getVideoSourceType(source) === VideoSourceType.WEB_FILE_IFRAME && source.videoURI != null) {
return createElement(MediaModalWebVideoFile, {
...rest,
key,
visible,
style: rest.style,
source: {
uri: source.videoURI,
width: source.width,
height: source.height
},
controls: callback2(index, source)
});
}
if (source.portal != null && !isPortalExpired(source.portal)) {
return createElement(NativePortalView, {
...rest,
key,
pointerEvents,
portal: source.portal,
paused,
muted
});
}
if (source.embedURI != null && !source.isGIFV) {
const embedProviderName = source.embedProviderName;
if (embedProviderName === "TikTok") {
return createElement(MediaModalTiktok, {
...rest,
key,
visible,
style: rest.style,
source: {
uri: source.embedURI,
width: source.width,
height: source.height
},
controls: callback2(index, source)
});
}
if (embedProviderName === "YouTube") {
return createElement(MediaModalYoutube, {
...rest,
key,
visible,
style: rest.style,
source: {
uri: source.embedURI,
width: source.width,
height: source.height
}
});
}
return null;
}
L26: {
if (source.videoURI != null) {
r104 = createElement(MediaModalLoader, {
Component: VideoComponent,
...rest,
key,
pointerEvents,
paused,
controls: callback2(index, source),
muted,
index,
onLoad: callback3(index, source, rest.onLoad),
source: {
uri: source.videoURI,
width: source.width,
height: source.height,
videoURI: source.videoURI,
messageId: source.messageId,
channelId: source.channelId,
mediaIndex: source.mediaIndex,
description: source.description,
obscure: source.obscure,
accessoryType: source.accessoryType,
attachmentId: source.attachmentId
}
});
} else {
if (!source.uri.startsWith("assets-library://") && !source.uri.startsWith(Base64JPEGPrefix) && !source.uri.startsWith(Base64GIFPrefix)) {
r104 = createElement(MediaModalLoader, {
Component: FastImage,
...rest,
key,
source,
index,
pointerEvents
});
break L26;
}
r104 = createElement(MediaModalLoader, {
Component: Image2,
...rest,
key,
source,
index,
pointerEvents
});
}
}
return r104;
}, [callback2, callback3, mediaPlayerMutedStore, videoStateStore])} renderOverlay={callback6} />;
return isRNModal ? <Modal transparent animationType="none" visible onRequestClose={callback4} statusBarTranslucent>
<View style={StyleSheet.absoluteFill}>{r110}</View>
</Modal> : r110;
};