This commit is contained in:
janisslsm committed 2026-11-01 12:12:55 +02:00
1 parent 1781d25a15
commit 732c0ad767
33051 files changed
+2591613 -3019689

No files matched your search

@@ -0,0 +1,271 @@
// 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;
};
@@ -0,0 +1,90 @@
// Metro module 12317 (f12318).
import { memo, useState, useRef, useCallback, useEffect } from "react";
import { ActivityIndicator, View, StyleSheet } from "react-native";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { Text } from "../../../../design/components/Text/native/Text";
import { intl, t } from "../../../../intl/index.native";
import MediaModalSpoilerOverlay from "./MediaModalSpoilerOverlay";
const useStyles = createStyles({
loader: {
...StyleSheet.absoluteFillObject,
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: "rgba(0, 0, 0, 0.7)"
},
loaderIndicator: {
marginTop: Module712.space.PX_12
},
loaderText: {
textAlign: "center"
}
});
let c8512_10 = {
None: 0,
0: "None",
Loading: 1,
1: "Loading",
Loaded: 2,
2: "Loaded",
Error: 3,
3: "Error"
};
const r55 = memo(function MediaModalLoader(props) {
let r106;
const { Component, style, onLoadStart, onLoad, onError, index = 0, source, ...rest } = props;
const styles = useStyles();
const [state, setState] = useState(c8512_10.None);
const [state2, setState2] = useState(0);
const ref = useRef(null);
const callback2 = useCallback(() => {
const current = setTimeout(() => {
setState((prevState) => prevState === c8512_10.None ? c8512_10.Loading : c8512_10.None);
}, 1000);
ref.current = current;
return current;
}, []);
const callback = useCallback(({ nativeEvent }) => {
setState2(100 * nativeEvent.loaded / nativeEvent.total);
}, []);
const callback3 = useCallback(() => setState(c8512_10.Loaded), []);
const callback4 = useCallback(() => setState(c8512_10.Error), []);
useEffect(() => {
if (c8512_10.Loading === state) {
if (onLoadStart != null) {
onLoadStart();
}
} else if (c8512_10.Error === state) {
if (onError != null) {
onError();
}
} else if (c8512_10.Loaded === state && onLoad != null) {
onLoad();
}
}, [state, onLoadStart, onError, onLoad]);
useEffect(() => () => clearTimeout(ref.current));
if (state === c8512_10.Error) {
r106 = <View style={[styles.loader, style]}>
<Text style={styles.loaderText} variant="heading-md/semibold" color="text-overlay-light">
{intl.string(t["+ITMYX"])}
</Text>
</View>;
} else {
let description = source.description;
if (description == null) {
description = void 0;
}
r106 = <>
{[<Component {...rest} style={style} source={source} onLoadStart={callback2} onProgress={callback} onLoad={callback3} onError={callback4} accessibilityRole="image" accessibilityLabel={description} loop />, state === c8512_10.Loading ? <View style={[styles.loader, style]}>
{source.videoURI == null ? <Text style={styles.loaderText} variant="heading-md/semibold" color="text-overlay-light">
{Math.round(state2)}
%
</Text> : null}
<ActivityIndicator color="white" style={styles.loaderIndicator} size="large" />
</View> : null, <MediaModalSpoilerOverlay style={style} index={index} source={source} />]}
</>;
}
return r106;
});
export default r55;
@@ -0,0 +1,21 @@
// Metro module 8132 (f8133).
import { useContext, useEffect, useCallback } from "react";
import { MEDIA_MODAL_KEY } from "../../../../Constants";
import ActionSheetContext from "../../../action_sheet/native/ActionSheetContext";
import ActionSheetActionCreators from "../../../action_sheet/native/ActionSheetActionCreators";
import MediaModal from "./MediaModal";
export default function MediaModalSheetWrapper(props) {
const { onCloseCallback, ...props2 } = props;
const context = useContext(ActionSheetContext);
useEffect(() => {
if (context?.transitionState === "exiting") {
context.onLeave();
}
}, [context]);
return <MediaModal {...props2} onClose={useCallback(() => {
if (onCloseCallback != null) {
onCloseCallback();
}
ActionSheetActionCreators.hideActionSheet(MEDIA_MODAL_KEY);
}, [onCloseCallback])} />;
};
@@ -0,0 +1,69 @@
// Metro module 12318 (f12319).
import { memo } from "react";
import { StyleSheet, View } from "react-native";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { isAndroid } from "../../../../utils/PlatformUtils";
import { useToken } from "../../../../design/tokens/native/useToken";
import { useMediaItemSpoilerState } from "../useMediaItemSpoilerState";
import ReanimatedRexport from "../../../reanimated/ReanimatedRexport";
import VisualEffectView from "../../../visual_effect_view/native/VisualEffectView";
import { ImageWarningIcon } from "../../../../design/components/Icon/native/redesign/generated/ImageWarningIcon";
import { Text } from "../../../../design/components/Text/native/Text";
import { intl, t } from "../../../../intl/index.native";
const useStyles = createStyles({
spoilerOverlayContainer: {
justifyContent: "center",
alignContent: "center",
flex: 1
},
obscureContentContainer: {
gap: Module712.space.PX_4,
justifyContent: "center",
alignItems: "center",
alignSelf: "center"
},
spoilerOverlayBackground: {
paddingHorizontal: Module712.space.PX_16,
borderRadius: Module712.radii.lg,
height: Module712.space.PX_32,
backgroundColor: isAndroid() ? Module712.unsafe_rawColors.PRIMARY_800 : Module712.unsafe_rawColors.PRIMARY_600,
flexGrow: 0,
justifyContent: "center",
alignItems: "center",
alignSelf: "center"
}
});
const r59 = memo(function MediaModalSpoilerOverlay(props) {
let r72;
const { style, index, source } = props;
const styles = useStyles();
const token = useToken(Module712.colors.SPOILER_HIDDEN_BACKGROUND);
const [r31, r9] = useMediaItemSpoilerState(index);
let r32 = null;
if (r31) {
const r51 = [<VisualEffectView blurTheme={source.obscure ? "dark" : isAndroid() ? "dark" : "light"} android_fallbackColor={token} style={StyleSheet.absoluteFill} />, ,];
const obscure = source.obscure;
const props2 = {
style: null,
children: null
};
if (obscure) {
props2.style = styles.obscureContentContainer;
props2.children = [<ImageWarningIcon size="lg" color="white" />, <Text accessibilityRole="text" variant="heading-md/medium" color="text-overlay-light">
{intl.string(t.SpxcUR)}
</Text>];
r72 = <View {...props2} />;
} else {
props2.style = styles.spoilerOverlayBackground;
props2.children = <Text accessibilityRole="text" variant="heading-md/medium" color="text-overlay-light">
{intl.string(t["F+x38C"]).toUpperCase()}
</Text>;
r72 = <View {...props2} />;
}
r51[1] = <View style={styles.spoilerOverlayContainer}>{r72}</View>;
r32 = <ReanimatedRexport.View style={[style, StyleSheet.absoluteFill, r9]}>{r51}</ReanimatedRexport.View>;
}
return r32;
});
export default r59;
@@ -0,0 +1,255 @@
// Metro module 8139 (f8140).
import { memo, useState, useCallback, useEffect, useMemo, createRef, useLayoutEffect } from "react";
import MediaModalWebView, { PlayerState } from "./MediaModalWebView";
import usePrevious from "../../../../hooks/usePrevious";
import { MediaViewerAnalytics } from "../../MediaViewerAnalyticsManager";
import { setMuted } from "../useVideoControls";
import { useMediaPlayerMutedStore } from "../MediaPlayerMuteManager";
let c5169_6 = {
controls: 0,
enable_music_info: 0,
enable_timestamp: 0,
utm_source: "discord.gg"
};
let c5169_7 = {
"-1": PlayerState.UNSTARTED,
0: PlayerState.ENDED,
1: PlayerState.PLAYING,
2: PlayerState.PAUSED,
3: PlayerState.BUFFERING
};
const r44 = memo(function({ visible, style, source, controls, ...props }) {
let mediaPlayerMutedStore;
mediaPlayerMutedStore = void 0;
const [state, setState] = useState(PlayerState.UNREADY);
const previous = usePrevious(state);
let c16282_5 = previous;
const previous2 = usePrevious(visible);
let c16282_6 = previous2;
const ref = controls == null ? void 0 : controls.props?.ref;
const callback = useCallback((a0) => {
const r9 = JSON.parse(a0);
const type = r9.type;
if (type === "onPlayerReady") {
setState(PlayerState.READY);
} else if (type === "onStateChange") {
const r60 = c5169_7[r9.value];
if (r60 != null) {
if (controls != null) {
const props3 = controls.props;
if (props3 != null) {
props3.onPlayerStateChange(r60);
}
}
setState(r60);
}
} else if (type === "onError") {
setState(PlayerState.ERRORED);
const value = r9.value;
MediaViewerAnalytics.trackMessageEmbedsActionCompleted({
platform: "tiktok",
action: "errored",
error: value === "1" ? "MEDIA_ERR_ABORTED" : value === "2" ? "MEDIA_ERR_NETWORK" : value === "3" ? "MEDIA_ERR_DECODE" : value !== "4" ? "UNKNOWN" : "MEDIA_ERR_SRC_NOT_SUPPORTED"
});
} else if (type === "onCurrentTime") {
if (controls != null) {
const props = controls.props;
if (props != null) {
const onCurrentSecond2 = props.onCurrentSecond;
if (onCurrentSecond2 != null) {
onCurrentSecond2.call(props, r9.value.currentTime);
}
}
}
if (controls != null) {
const props2 = controls.props;
if (props2 != null) {
const onDuration2 = props2.onDuration;
if (onDuration2 != null) {
onDuration2.call(props2, r9.value.duration);
}
}
}
} else if (type === "onMute") {
setMuted(r9.value);
}
}, [controls?.props]);
mediaPlayerMutedStore = useMediaPlayerMutedStore((a0) => a0.isMuted);
useEffect(() => {
if (ref?.current != null && state !== PlayerState.UNREADY) {
if ((visible ? c16282_5 === PlayerState.UNREADY : visible) && state === PlayerState.READY) {
const r12 = JSON.stringify({
"x-tiktok-player": true,
...{
type: "play"
}
});
const current = ref.current;
if (current != null) {
current.injectJavaScript(`
window.postMessage(${r12}, '*')
`);
}
}
if (visible ? !c16282_6 : visible) {
const r59 = JSON.stringify({
"x-tiktok-player": true,
...{
type: "play"
}
});
const current2 = ref.current;
if (current2 != null) {
current2.injectJavaScript(`
window.postMessage(${r59}, '*')
`);
}
}
if (visible ? !visible : c16282_6) {
const r76 = JSON.stringify({
"x-tiktok-player": true,
...{
type: "pause"
}
});
const current3 = ref.current;
if (current3 != null) {
current3.injectJavaScript(`
window.postMessage(${r76}, '*')
`);
}
}
if (state === PlayerState.ENDED) {
const r100 = JSON.stringify({
"x-tiktok-player": true,
...{
type: "seekTo",
value: 0
}
});
const current4 = ref.current;
if (current4 != null) {
current4.injectJavaScript(`
window.postMessage(${r100}, '*')
`);
}
const r115 = JSON.stringify({
"x-tiktok-player": true,
...{
type: "play"
}
});
const current5 = ref.current;
if (current5 != null) {
current5.injectJavaScript(`
window.postMessage(${r115}, '*')
`);
}
}
const r134 = JSON.stringify({
"x-tiktok-player": true,
...{
type: mediaPlayerMutedStore ? "mute" : "unMute"
}
});
const current6 = ref.current;
if (current6 != null) {
current6.injectJavaScript(`
window.postMessage(${r134}, '*')
`);
}
}
}, [ref, visible, previous2, previous, state, mediaPlayerMutedStore]);
useEffect(() => {
MediaViewerAnalytics.trackMessageEmbedsActionCompleted({
platform: "tiktok",
action: "attempted"
});
}, []);
return <MediaModalWebView ref={ref} style={style} source={{
...source,
uri: useMemo(() => {
const uRL = new URL(source.uri);
let c26117_0 = uRL;
Object.entries(c5169_6).forEach((item) => {
const [r23, r7] = item;
c26117_0.searchParams.append(r23, r7.toString());
});
return uRL.toString();
}, [source.uri])
}} baseURL="https://www.tiktok.com/player/v1/" injectedJavaScript={"\n window.addEventListener('message', function(event) {\n if (!event.data[\"x-tiktok-player\"]) {\n return;\n }\n window.ReactNativeWebView.postMessage(JSON.stringify(event.data));\n }, true);\n"} onDataReceived={callback} playerState={state} {...props} />;
});
export default r44;
export function createTiktokVideoControls() {
let c16283_0, c16283_1;
const ref2 = createRef();
let c16283_3 = 0;
let c16283_4 = 0;
let c16283_5 = false;
return {
seek: (a0) => {
const r12 = JSON.stringify({
"x-tiktok-player": true,
...{
type: "seekTo",
value: a0
}
});
const current = ref2.current;
if (current != null) {
current.injectJavaScript(`
window.postMessage(${r12}, '*')
`);
}
},
pause: (a0) => {
if (c16283_5 !== a0) {
c16283_5 = a0;
const r14 = JSON.stringify({
"x-tiktok-player": true,
...{
type: a0 ? "pause" : "play"
}
});
const current = ref2.current;
if (current != null) {
current.injectJavaScript(`
window.postMessage(${r14}, '*')
`);
}
}
},
useSubscribe: (a0, a1, a2) => {
c16283_0 = a0;
c16283_1 = a1;
useLayoutEffect(() => {
if (c16283_0 != null) {
c16283_0(c16283_3, c16283_4);
}
if (c16283_1 != null) {
c16283_1(c16283_5);
}
}, []);
},
props: {
ref: ref2,
onPlayerStateChange: (a0) => {
if (c16283_1 != null) {
c16283_1(a0 === PlayerState.PAUSED || a0 === PlayerState.ENDED);
}
},
onCurrentSecond: (a0) => {
c16283_3 = a0;
if (c16283_0 != null) {
c16283_0(c16283_3, c16283_4);
}
},
onDuration: (a0) => {
c16283_4 = a0;
if (c16283_0 != null) {
c16283_0(c16283_3, c16283_4);
}
}
}
};
}
@@ -0,0 +1,289 @@
// Metro module 8141 (f8142).
import { memo, useState, useEffect, useCallback, createRef, useLayoutEffect } from "react";
import MediaModalWebView, { PlayerState } from "./MediaModalWebView";
import usePrevious from "../../../../hooks/usePrevious";
import { MediaViewerAnalytics } from "../../MediaViewerAnalyticsManager";
import { useMediaPlayerMutedStore } from "../MediaPlayerMuteManager";
const baseUrl = `https:${window.GLOBAL_ENV.WEBAPP_ENDPOINT}`;
const r29 = memo(function({ visible, style, source, controls, ...props }) {
let mediaPlayerMutedStore;
mediaPlayerMutedStore = void 0;
const [state, setState] = useState(PlayerState.UNREADY);
const previous = usePrevious(state);
let c16285_4 = previous;
const previous2 = usePrevious(visible);
let c16285_5 = previous2;
const ref = controls == null ? void 0 : controls.props?.ref;
useEffect(() => {
MediaViewerAnalytics.trackMessageEmbedsActionCompleted({
platform: "file",
action: "attempted"
});
}, []);
const callback = useCallback((a0) => {
L38: {
const r8 = (function(a0) {
let r4;
try {
r4 = JSON.parse(a0);
} catch ($e) {
return {};
}
return r4;
})(a0);
const { type, value } = r8;
switch (type) {
case "loaded":
setState(PlayerState.READY);
break L38;
case "canplay":
if (controls != null) {
const props8 = controls.props;
if (props8 != null) {
props8.onPlayerStateChange(PlayerState.VIDEO_CUED);
}
}
setState(PlayerState.VIDEO_CUED);
break L38;
case "error":
setState(PlayerState.ERRORED);
MediaViewerAnalytics.trackMessageEmbedsActionCompleted({
platform: "file",
action: "errored",
error: "unknown"
});
break L38;
case "ended":
if (controls != null) {
const props7 = controls.props;
if (props7 != null) {
props7.onPlayerStateChange(PlayerState.ENDED);
}
}
setState(PlayerState.ENDED);
break L38;
case "play":
if (controls != null) {
const props6 = controls.props;
if (props6 != null) {
props6.onPlayerStateChange(PlayerState.PLAYING);
}
}
setState(PlayerState.PLAYING);
break L38;
case "pause":
if (controls != null) {
const props5 = controls.props;
if (props5 != null) {
props5.onPlayerStateChange(PlayerState.PAUSED);
}
}
setState(PlayerState.PAUSED);
break L38;
case "stalled":
if (controls != null) {
const props4 = controls.props;
if (props4 != null) {
props4.onPlayerStateChange(PlayerState.BUFFERING);
}
}
setState(PlayerState.BUFFERING);
break L38;
case "durationchange":
if (value == null) {
break L38;
}
if (controls == null) {
break L38;
}
const props3 = controls.props;
if (props3 == null) {
break L38;
}
const onDuration2 = props3.onDuration;
if (onDuration2 == null) {
break L38;
}
onDuration2.call(props3, value);
break L38;
case "progress":
if (value == null) {
break L38;
}
if (controls == null) {
break L38;
}
const props2 = controls.props;
if (props2 == null) {
break L38;
}
const onDownloadProgress2 = props2.onDownloadProgress;
if (onDownloadProgress2 == null) {
break L38;
}
onDownloadProgress2.call(props2, value);
break L38;
case "timeupdate":
if (value == null) {
break L38;
}
if (controls == null) {
break L38;
}
const props = controls.props;
if (props == null) {
break L38;
}
const onCurrentSecond2 = props.onCurrentSecond;
if (onCurrentSecond2 == null) {
break L38;
}
onCurrentSecond2.call(props, value);
break L38;
default:
}
}
}, [controls?.props]);
mediaPlayerMutedStore = useMediaPlayerMutedStore((a0) => a0.isMuted);
useEffect(() => {
if (ref?.current != null && state !== PlayerState.UNREADY) {
ref.current.injectJavaScript(`window.player.muted = ${JSON.stringify(mediaPlayerMutedStore)}; true;`);
if ((visible ? c16285_4 === PlayerState.UNREADY : visible) && state === PlayerState.READY) {
ref.current.injectJavaScript("window.player.play(); true;");
}
if (visible ? !c16285_5 : visible) {
ref.current.injectJavaScript("window.player.play(); true;");
}
if (visible ? !visible : c16285_5) {
ref.current.injectJavaScript("window.player.pause(); true;");
}
}
}, [ref, visible, previous2, previous, state, mediaPlayerMutedStore]);
return <MediaModalWebView key={source.uri} ref={ref} style={style} source={{
html: `
<html>
<head>
<meta name="viewport" content="initial-scale=1">
<style>
* {
margin: 0;
padding: 0;
inset: 0;
width: 100%;
height: 100%;
background-color: #000;
object-fit: contain;
}
</style>
<script>${`
function onReady() {
const player = window.player = document.createElement('video');
player.controls = false;
player.autoplay = false;
player.playsInline = true;
player.disablePictureInPicture = true;
const addEvent = (name, func) => {
player.addEventListener(name, (e) => {
window.ReactNativeWebView.postMessage(
JSON.stringify({type: name, value: func ? func() : undefined})
);
});
};
addEvent('error', () => player.error);
addEvent('canplay');
addEvent('ended');
addEvent('pause');
addEvent('play');
addEvent('stalled');
addEvent('durationchange', () => player.duration);
addEvent('timeupdate', () => player.currentTime);
addEvent('progress', () => {
const ranges = player.buffered;
let total = 0;
for (let i = 0; i < ranges.length; i++) {
total += (ranges.end(i) - ranges.start(i));
}
return total;
});
player.src = ${JSON.stringify(source.uri)};
document.body.appendChild(player);
player.load();
window.ReactNativeWebView.postMessage(JSON.stringify({type: 'loaded'}));
}
window.addEventListener('load', onReady);
`}</script>
</head>
<body>
</body>
</html>
`,
baseUrl
}} baseURL={baseUrl} playerState={state} onDataReceived={callback} javaScriptEnabled javaScriptCanOpenWindowsAutomatically {...props} />;
});
export default r29;
export function createWebFileVideoControls() {
let c16286_0, c16286_1, c16286_2;
const ref2 = createRef();
let c16286_4 = 0;
let c16286_5 = 0;
let c16286_6 = 0;
return {
seek: (a0) => {
const current = ref2.current;
if (current != null) {
current.injectJavaScript(`window.player.currentTime = ${JSON.stringify(a0)}; true;`);
}
},
pause: (a0) => {
const current = ref2.current;
if (current != null) {
current.injectJavaScript(`window.player.${a0 ? "pause" : "play"}(); true;`);
}
},
useSubscribe: (a0, a1, a2) => {
c16286_0 = a0;
c16286_1 = a1;
c16286_2 = a2;
useLayoutEffect(() => {
if (c16286_0 != null) {
c16286_0(c16286_4, c16286_5);
}
}, []);
},
props: {
ref: ref2,
onPlayerStateChange: (a0) => {
if (c16286_1 != null) {
c16286_1(a0 === PlayerState.PAUSED || a0 === PlayerState.ENDED);
}
},
onCurrentSecond: (a0) => {
c16286_4 = a0;
if (c16286_0 != null) {
c16286_0(c16286_4, c16286_5);
}
},
onDuration: (a0) => {
c16286_5 = a0;
if (c16286_0 != null) {
c16286_0(c16286_4, c16286_5);
}
if (c16286_5 > 0) {
const r12 = c16286_6 / c16286_5;
if (c16286_2 != null) {
c16286_2(r12);
}
}
},
onDownloadProgress: (a0) => {
c16286_6 = a0;
if (c16286_5 > 0) {
const r7 = c16286_6 / c16286_5;
if (c16286_2 != null) {
c16286_2(r7);
}
}
}
}
};
}
@@ -0,0 +1,110 @@
// Metro module 8140 (f8141).
import { memo, forwardRef, useEffect, useCallback } from "react";
import { ActivityIndicator, View } from "react-native";
import { isIOS } from "../../../../utils/PlatformUtils";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import ReanimatedRexport, { useSharedValue, useAnimatedStyle } from "../../../reanimated/ReanimatedRexport";
import * as _timing from "../../../../design/animation/reanimated/timing/timing";
import Linking from "../../../../lib/native/Linking";
import Module6759 from "../../../../_bundle/Module6759";
let c5170_8 = isIOS() ? "\n window.addEventListener('click', function(event) {\n window.ReactNativeWebView.postMessage(JSON.stringify({event: 'click'}));\n });\n" : "";
let c5170_9 = {
UNREADY: 0,
0: "UNREADY",
READY: 1,
1: "READY",
ERRORED: 2,
2: "ERRORED",
UNSTARTED: 3,
3: "UNSTARTED",
ENDED: 4,
4: "ENDED",
PLAYING: 5,
5: "PLAYING",
PAUSED: 6,
6: "PAUSED",
BUFFERING: 7,
7: "BUFFERING",
VIDEO_CUED: 8,
8: "VIDEO_CUED"
};
const useStyles = createStyles({
loading: {
top: 0,
left: 0,
right: 0,
bottom: 0,
position: "absolute",
alignItems: "center",
justifyContent: "center"
}
});
const __initData = {
code: "function MediaModalWebViewTsx1(){const{withTiming,webviewOpacity}=this.__closure;return{opacity:withTiming(webviewOpacity.get())};}"
};
const __initData2 = {
code: "function MediaModalWebViewTsx2(){const{withTiming,loaderOpacity}=this.__closure;return{opacity:withTiming(loaderOpacity.get())};}"
};
const r59 = memo(forwardRef(function({ style, playerState, onDataReceived, baseURL, injectedJavaScript, panGestureConfig, ...props }, a1) {
const styles = useStyles();
const sharedValue = useSharedValue(1);
const sharedValue2 = useSharedValue(0);
const f = function f() {
return {
opacity: _timing.withTiming(sharedValue2.get())
};
};
f.__closure = {
withTiming: _timing.withTiming,
webviewOpacity: sharedValue2
};
f.__workletHash = 2179142865986;
f.__initData = __initData;
const animatedStyle = useAnimatedStyle(f);
const S = function S() {
return {
opacity: _timing.withTiming(sharedValue.get())
};
};
S.__closure = {
withTiming: _timing.withTiming,
loaderOpacity: sharedValue
};
S.__workletHash = 7752174298017;
S.__initData = __initData2;
const animatedStyle2 = useAnimatedStyle(S);
useEffect(() => {
if (!(playerState !== c5170_9.BUFFERING && playerState !== c5170_9.PLAYING && playerState !== c5170_9.ERRORED)) {
sharedValue.set(0);
sharedValue2.set(1);
}
}, [playerState, sharedValue, sharedValue2]);
return <View style={style}>
<ReanimatedRexport.View style={[animatedStyle, {
flex: 1
}]}>
<Module6759 {...props} injectedJavaScript={`${injectedJavaScript}
${c5170_8}`} bounces={false} ref={a1} scrollEnabled={false} javaScriptEnabled onMessage={useCallback((a0) => {
const r8 = JSON.parse(a0.nativeEvent.data);
if (r8 != null && r8.event === "click") {
panGestureConfig.overlayEnabled.set(!panGestureConfig.overlayEnabled.get());
} else {
onDataReceived(a0.nativeEvent.data);
}
}, [onDataReceived, panGestureConfig])} allowsInlineMediaPlayback mediaPlaybackRequiresUserAction={false} onShouldStartLoadWithRequest={useCallback((a0) => {
const r7 = a0.url !== "about:blank" && !a0.url.startsWith(baseURL) && (a0.isTopFrame == null || a0.isTopFrame);
let r13 = !r7;
if (r7) {
Linking.openURL(a0.url);
r13 = false;
}
return r13;
}, [baseURL])} />
</ReanimatedRexport.View>
{playerState !== c5170_9.PLAYING && playerState !== c5170_9.PAUSED && <ReanimatedRexport.View style={[animatedStyle2, styles.loading]}>
<ActivityIndicator color="white" size="large" />
</ReanimatedRexport.View>}
</View>;
}));
export default r59;
export { c5170_9 as PlayerState };
@@ -0,0 +1,152 @@
// 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;
@@ -0,0 +1,37 @@
// Metro module 12316 (f12317).
import { memo } from "react";
import { View } from "react-native";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { StreamFailed } from "../../../../design/components/Illustration/native/redesign/generated/StreamFailed";
import { Text } from "../../../../design/components/Text/native/Text";
import { intl, t } from "../../../../intl/index.native";
import { Button } from "../../../../design/components/Button/native/Button.native";
import Linking from "../../../../lib/native/Linking";
const useStyles = createStyles({
container: {
backgroundColor: Module712.colors.VOICE_VIDEO_VIDEO_TILE_BACKGROUND,
padding: Module712.space.PX_32,
justifyContent: "center",
alignItems: "center",
flex: 1
},
text: {
marginBottom: Module712.space.PX_8,
marginTop: Module712.space.PX_16
}
});
const r47 = memo(function MediaModalYoutubeEmbedError(props) {
const videoId = props.videoId;
const styles = useStyles();
return <View style={styles.container}>
<StreamFailed resizeMode="contain" />
<Text style={styles.text} variant="text-md/semibold" color="text-overlay-light">
{intl.string(t.u7vKPs)}
</Text>
<Button text={intl.string(t.LLpxJ5)} variant="primary-overlay" shrink grow={false} onPress={() => {
Linking.openURL(`https://youtube.com/watch?v=${videoId}`);
}} />
</View>;
});
export default r47;
@@ -0,0 +1,203 @@
// Metro module 8169 (f8170).
import { useCallback, useMemo } from "react";
import ICYMIStore from "../../../icymi/ICYMIStore";
import ChannelStore from "../../../../stores/ChannelStore";
import MessageStore from "../../../../stores/MessageStore";
import MessagePreviewStore from "../../../../stores/native/MessagePreviewStore";
import { AnalyticsSections, GIF_RE_IOS, MediaType } from "../../../../Constants";
import { EXPLICIT_MEDIA_FALSE_POSITIVE_ACTION_SHEET_KEY } from "../../../explicit_media_redaction/ExplicitMediaRedactionConstants";
import { useStateFromStores } from "../../../../_bundle/defaultAreStatesEqual";
import { shouldAgeVerifyForExplicitMedia } from "../../../explicit_media_redaction/ExplicitMediaRedactionUtils";
import { getAttachmentObscurityProps } from "../../../messages/native/renderer/ExplicitMediaUtils";
import ActionSheetActionCreators from "../../../action_sheet/native/ActionSheetActionCreators";
import { downloadMediaAssetWithContentType, getVideoSourceType, VideoSourceType } from "../MediaSourceUtil";
import { urlMatchesFileExtension } from "../../../messages/MediaFormatTesters";
import { showShareActionSheet } from "../../../action_sheet/native/showShareActionSheet";
import { MediaViewerAnalytics } from "../../MediaViewerAnalyticsManager";
import { handleClick } from "../../../../utils/MaskedLinkUtils";
import Linking from "../../../../lib/native/Linking";
import { openForwardModal } from "../../../forwarding/native/ForwardModalUtils";
import { transitionToMessage } from "../../../routing/transitionToChannel";
import { getChatLayout } from "../../../chat/native/useChatLayout";
import { useCanForwardMessage } from "../../../forwarding/canForwardMessage";
import { DownloadIcon } from "../../../../design/components/Icon/native/redesign/generated/DownloadIcon";
import { intl, t } from "../../../../intl/index.native";
import ForwardingIcon from "../../../forwarding/native/ForwardingIcon";
import { ShareIcon } from "../../../../design/components/Icon/native/redesign/generated/ShareIcon";
import { WindowLaunchIcon } from "../../../../design/components/Icon/native/redesign/generated/WindowLaunchIcon";
import { ChatArrowRightIcon } from "../../../../design/components/Icon/native/redesign/generated/ChatArrowRightIcon";
import { ImageWarningIcon } from "../../../../design/components/Icon/native/redesign/generated/ImageWarningIcon";
import { ActionSheet } from "../../../../design/components/Sheet/native/ActionSheet.native";
import { ActionSheetRow } from "../../../../design/components/Sheet/native/ActionSheetRow.native";
const useMediaShareActions = function useMediaShareActions({ source, disableDownload, shareable }) {
let obscure, callback, callback2, callback3, callback4, callback5, callback6, c16300_13, videoSourceType;
obscure = void 0;
callback = void 0;
callback2 = void 0;
callback3 = void 0;
callback4 = void 0;
callback5 = void 0;
callback6 = void 0;
c16300_13 = void 0;
videoSourceType = void 0;
const { channelId, messageId } = source;
const stateFromStores = useStateFromStores([MessageStore, ICYMIStore, MessagePreviewStore], () => {
const r1 = channelId == null;
let r2 = null;
if (!r1) {
const r8 = messageId == null;
r2 = null;
if (!r8) {
let r10 = MessageStore.getMessage(channelId, messageId);
if (r10 == null) {
r10 = MessagePreviewStore.getMessage(messageId);
}
if (r10 == null) {
r10 = ICYMIStore.getMessage(messageId);
}
r2 = r10;
}
}
return r2;
}, [channelId, messageId]);
obscure = getAttachmentObscurityProps({
attachment: source,
shouldObscureSpoiler: true,
enabledContentHarmTypeFlags: 0,
shouldAgeVerify: shouldAgeVerifyForExplicitMedia()
}).obscure;
callback = useCallback(() => {
ActionSheetActionCreators.hideActionSheet();
if (source.videoURI != null) {
downloadMediaAssetWithContentType(source.videoURI, MediaType.VIDEO, source.contentType);
} else if (source.sourceURI != null) {
downloadMediaAssetWithContentType(source.sourceURI, urlMatchesFileExtension(source.sourceURI, GIF_RE_IOS) ? MediaType.GIF : MediaType.IMAGE, source.contentType);
}
}, [source]);
callback2 = useCallback(() => {
ActionSheetActionCreators.hideActionSheet();
showShareActionSheet({
source
}, AnalyticsSections.MEDIA_VIEWER);
MediaViewerAnalytics.trackMediaViewerShareButtonTapped();
}, [source]);
callback3 = useCallback(() => {
ActionSheetActionCreators.hideActionSheet();
if (source.sourceURI != null) {
handleClick({
href: source.sourceURI,
onConfirm: () => {
Linking.openURL(source.sourceURI);
}
});
}
}, [source]);
callback4 = useCallback(() => {
ActionSheetActionCreators.hideActionSheet();
if (stateFromStores != null) {
if (source.accessoryType !== "embed") {
const attachmentId = source.attachmentId;
if (attachmentId != null) {
openForwardModal({
message: stateFromStores,
source: "media-viewer",
initialSelectedDestinations: void 0,
forwardOptions: {
onlyAttachmentIds: [attachmentId]
}
});
}
} else {
openForwardModal({
message: stateFromStores,
source: "media-viewer",
initialSelectedDestinations: void 0,
forwardOptions: {
onlyEmbedIndices: [source.mediaIndex]
}
});
}
}
}, [stateFromStores, source]);
callback5 = useCallback(() => {
ActionSheetActionCreators.hideActionSheet();
if (ChannelStore.getChannel(source.channelId) != null && source.channelId != null && source.messageId != null) {
const { channelId: channelId2, messageId: messageId2 } = source;
const isChatLockedOpen = getChatLayout().isChatLockedOpen;
transitionToMessage(channelId2, messageId2, {
navigationReplace: isChatLockedOpen ? void 0 : !isChatLockedOpen
});
}
}, [source]);
callback6 = useCallback(() => {
ActionSheetActionCreators.hideActionSheet();
const attachmentId = source.attachmentId;
if (attachmentId != null && source.channelId != null && source.messageId != null) {
ActionSheetActionCreators.openLazy(import("../../../explicit_media_redaction/native/false_positive_reporting/ExplicitMediaObscuredFalsePositiveActionSheet"), EXPLICIT_MEDIA_FALSE_POSITIVE_ACTION_SHEET_KEY, {
messageId: source.messageId,
channelId: source.channelId,
attachmentId
});
}
}, [source]);
const r61 = useCanForwardMessage(stateFromStores) && (source.attachmentId != null || source.accessoryType === "embed");
c16300_13 = r61;
videoSourceType = getVideoSourceType(source);
return useMemo(() => {
const r12 = disableDownload !== true && videoSourceType !== VideoSourceType.WEB_FILE_IFRAME;
const r19 = [];
if (r12) {
r19.push({
IconComponent: DownloadIcon,
label: intl.string(t["R3BPH+"]),
action: callback
});
}
if (c16300_13) {
r19.push({
IconComponent: ForwardingIcon,
label: intl.string(t.I3ltXO),
action: callback4
});
}
if (shareable) {
r19.push({
IconComponent: ShareIcon,
label: intl.string(t.RDE0Sc),
action: callback2
});
}
r19.push({
IconComponent: WindowLaunchIcon,
label: intl.string(t.q5jLJB),
action: callback3
});
if (source.channelId != null && source.messageId != null) {
r19.push({
IconComponent: ChatArrowRightIcon,
label: intl.string(t["+TSRGD"]),
action: callback5
});
}
if (obscure) {
r19.push({
IconComponent: ImageWarningIcon,
label: intl.string(t.ZH7P2h),
action: callback6
});
}
return r19;
}, [disableDownload, callback4, callback5, callback3, callback6, callback, callback2, obscure, shareable, r61, videoSourceType, source.channelId, source.messageId]);
};
export default function MediaShareActionSheet(props) {
return <ActionSheet>
<ActionSheetRow.Group hasIcons>
{useMediaShareActions({
source: props.source,
disableDownload: props.disableDownload,
shareable: props.shareable
}).map((item, index) => <ActionSheetRow key={index} icon={<ActionSheetRow.Icon IconComponent={item.IconComponent} />} onPress={item.action} label={item.label} />)}
</ActionSheetRow.Group>
</ActionSheet>;
};
export { useMediaShareActions };
@@ -0,0 +1,137 @@
// Metro module 8126 (f8127).
import { useRef, useState, useEffect, useCallback } from "react";
import { View } from "react-native";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import { isAndroid } from "../../../../utils/PlatformUtils";
import useInitialValue from "../../../../hooks/useInitialValue";
import Module12 from "../../../../_bundle/Module12";
import Module689 from "../../../../_bundle/Module689";
import { getTimeFormat } from "../../../../utils/native/TimeUtils";
import { PressableOpacity } from "../../../../design/void/Pressables/native/Pressables";
import { intl, t } from "../../../../intl/index.native";
import { PlayIcon } from "../../../../design/components/Icon/native/redesign/generated/PlayIcon";
import { PauseIcon } from "../../../../design/components/Icon/native/redesign/generated/PauseIcon";
import { Text } from "../../../../design/components/Text/native/Text";
import Module7659 from "../../../../_bundle/Module7659";
import Module8131 from "../../../../_bundle/Module8131";
import Module712 from "../../../../_bundle/Module712";
const useStyles = createStyles({
container: {
flex: 1,
marginHorizontal: 12,
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between"
},
icon: {
marginRight: 16
},
centerText: {
lineHeight: isAndroid() ? 12 : void 0
},
sliderContainer: {
position: "relative",
flex: 1,
marginHorizontal: isAndroid() ? 0 : 16,
justifyContent: "center"
},
progressSliderContainer: {
position: "relative",
flex: 1,
marginHorizontal: 0,
justifyContent: "center"
},
timelineBackgroundSlider: {
position: "absolute",
width: "100%",
backgroundColor: "transparent",
zIndex: 0
},
downloadProgressSlider: {
position: "absolute",
width: "100%",
backgroundColor: "transparent",
zIndex: 1
},
playbackSlider: {
position: "absolute",
width: "100%",
zIndex: 2
}
});
export default function MediaSlider(props) {
let c16277_10, c16277_11;
const { style, controls, paused, setPaused, onPlayPress } = props;
c16277_10 = void 0;
c16277_11 = void 0;
const styles = useStyles();
const ref = useRef(false);
const [value, setState] = useState(0);
const [value2, setState2] = useState(0);
const [maximumTrackTintColor, setState3] = useState("transparent");
const ref2 = useRef(0);
const [width, setState4] = useState(0);
const initialValue = useInitialValue(() => Module12.throttle((a0) => {
setState(a0);
}, 100));
c16277_10 = initialValue;
c16277_11 = useInitialValue(() => Module12.throttle((a0) => {
setState2(a0);
setState3(a0 === 1 ? Module689("#FFFFFF").alpha(0.2).hex() : "transparent");
}, 100));
useEffect(() => () => {
c16277_10.cancel();
}, [initialValue]);
controls.useSubscribe((a0, a1) => {
c16277_10(a0);
ref2.current = a1;
}, (a0) => {
setPaused(a0);
}, (a0) => {
c16277_11(a0);
});
const callback2 = useCallback(() => {
if (!paused) {
controls.pause(true);
ref.current = true;
}
}, [controls, paused]);
const callback = useCallback((a0) => {
controls.seek(a0);
if (ref.current) {
controls.pause(false);
ref.current = false;
}
}, [controls]);
const timeFormat = getTimeFormat(value);
return <View style={[styles.container, style]}>
<PressableOpacity style={styles.icon} accessibilityRole="button" accessibilityLabel={paused ? intl.string(t.RscU7I) : intl.string(t.ZcgDJX)} onPress={() => {
if (paused) {
onPlayPress();
}
controls.pause(!paused);
}} hitSlop={{
top: 8,
right: 8,
bottom: 8,
left: 8
}}>
{paused ? <PlayIcon size="md" color="white" /> : <PauseIcon size="md" color="white" />}
</PressableOpacity>
<Text style={[styles.centerText, {
width
}]} tabularNumbers lineClamp={1} color="text-overlay-light" variant="text-xs/medium">{timeFormat}</Text>
<View style={styles.sliderContainer}>
<View pointerEvents="none" style={styles.progressSliderContainer}>
<Module7659 style={styles.timelineBackgroundSlider} value={1} minimumValue={0} maximumValue={1} thumbTintColor={Module689("#FFFFFF").alpha(0).hex()} minimumTrackTintColor={Module689("#FFFFFF").alpha(0.1).hex()} maximumTrackTintColor={Module689("#FFFFFF").alpha(0.1).hex()} />
<Module7659 style={styles.downloadProgressSlider} value={value2} minimumValue={0} maximumValue={1} thumbTintColor={Module689("#FFFFFF").alpha(0).hex()} minimumTrackTintColor={Module689("#FFFFFF").alpha(0.2).hex()} maximumTrackTintColor={maximumTrackTintColor} />
</View>
<Module7659 style={styles.playbackSlider} value={value} thumbImage={Module8131} minimumValue={0} maximumValue={ref2.current} minimumTrackTintColor={Module712.unsafe_rawColors.WHITE} maximumTrackTintColor="transparent" onValueChange={initialValue} onSlidingStart={callback2} onSlidingComplete={callback} />
</View>
<Text style={styles.centerText} variant="text-xs/medium" color="text-overlay-light" tabularNumbers lineClamp={1} onLayout={(event) => {
setState4(event.nativeEvent.layout.width);
}}>
{getTimeFormat(ref2.current)}
</Text>
</View>;
};
@@ -0,0 +1,268 @@
// Metro module 12319 (f12320).
import { useState, useRef, useCallback, useEffect, memo } from "react";
import { StyleSheet, View } from "react-native";
import * as _PlatformUtils from "../../../../utils/PlatformUtils";
import * as _ReanimatedRexport from "../../../reanimated/ReanimatedRexport";
import ReanimatedRexport, { useSharedValue, useAnimatedRef, useAnimatedStyle, useDerivedValue, useAnimatedProps } from "../../../reanimated/ReanimatedRexport";
import { useMediaViewerPanGestureConfig, useMediaViewerPanGesture } from "../useMediaViewerPanGesture";
import { MediaViewerItem } from "./MediaViewerItem";
import useStateFromSharedValue from "../../../reanimated/native/useStateFromSharedValue";
import { GestureDetector } from "../../../../_bundle/Module5273";
import { AnimatedFastList } from "../../../../lib/native/FastList";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../../app_analytics/useAnalyticsLocations";
import AnalyticsLocation from "../../../app_analytics/AnalyticsLocation";
import { useMediaViewerDimensions, MediaViewerDimensionsProvider } from "../MediaViewerDimensionsContext";
import useMediaViewerClosePosition from "../useMediaViewerClosePosition";
import * as _timing from "../../../../design/animation/reanimated/timing/timing";
import { unpauseCurrentVideoIfNeeded } from "../useVideoControls";
import { useOrientationListener } from "../../../device/native/DeviceOrientation";
import StatusBar_android from "../../../status_bar/native/components/StatusBar.android";
import REAWorkaroundView from "../../../reanimated/native/REAWorkaroundView";
import HomeIndicator from "../../../voice_panel/native/HomeIndicator";
let isAndroid, __initData, __initData2, Component, __initData3, __initData4, __initData5, __initData6, __initData7;
const MediaViewer = function MediaViewer(props) {
let ref, callback, ref2;
const { onClose, onLongPress: onLongPress2, originLayout: originLayout2, renderMedia: renderMedia2, renderOverlay, swipeVelocityThreshold, syncer } = props;
const { index, sources: sources2, useViewerProps, zoomed: zoomed2 } = syncer;
ref = void 0;
callback = void 0;
ref2 = void 0;
const analyticsLocations = useAnalyticsLocations([AnalyticsLocation.MEDIA_VIEWER]).analyticsLocations;
const [state, setState] = useState(true);
const mediaViewerDimensions = useMediaViewerDimensions();
const { width, height } = mediaViewerDimensions;
const mediaViewerClosePosition = useMediaViewerClosePosition({
index,
onClose,
sources: sources2,
windowHeight: height,
windowWidth: width
});
let c19791_2 = mediaViewerClosePosition;
const sharedValue = useSharedValue(0);
const sharedValue2 = useSharedValue(false);
const animatedRef = useAnimatedRef();
const r5 = sources2.length > 1;
let c19791_6 = r5;
const r79 = useViewerProps();
const { ref: ref3, onScroll, onContentSizeChange, useItemVisible: useItemVisible2 } = r79;
const mediaViewerPanGestureConfig = useMediaViewerPanGestureConfig(mediaViewerClosePosition, swipeVelocityThreshold, onClose);
const { dismiss, translatePos, isClosing, isInteracting, overlayEnabled } = mediaViewerPanGestureConfig;
const absoluteFillObject = StyleSheet.absoluteFillObject;
const M = () => {
const r6 = Math;
const r19 = sharedValue.get();
const r25 = translatePos.get();
return {
...absoluteFillObject,
height,
backgroundColor: "black",
opacity: r6.min(r19, _ReanimatedRexport.interpolate(r25, [-c19791_2, 0, c19791_2], [0, 1, 0]))
};
};
M.__closure = {
absoluteFillObject,
windowHeight: height,
entranceAnimationDriver: sharedValue,
interpolate: _ReanimatedRexport.interpolate,
translatePos,
closePosition: mediaViewerClosePosition
};
M.__workletHash = 10332062530694;
M.__initData = __initData3;
const animatedStyle = useAnimatedStyle(M);
const [r99] = useState({
...StyleSheet.absoluteFillObject,
backgroundColor: "transparent"
});
const P = () => {
let r39;
const r19 = isClosing.get();
let opacity = 0;
if (!r19) {
const r22 = sharedValue2.get();
opacity = 0;
if (!r22) {
if (overlayEnabled.get() && !isInteracting.get()) {
r39 = _timing.withTiming(1, {
easing: _ReanimatedRexport.Easing.linear,
duration: 150
});
} else {
const r51 = {
easing: _ReanimatedRexport.Easing.linear,
duration: 75
};
const n = function n() {
_ReanimatedRexport.runOnJS(setState)(false);
};
n.__closure = {
runOnJS: _ReanimatedRexport.runOnJS,
setShowHeader: setState
};
n.__workletHash = 11572173694016;
n.__initData = __initData5;
r39 = _timing.withTiming(0, r51, "respect-motion-settings", n);
}
opacity = r39;
}
}
return {
opacity
};
};
P.__closure = {
isClosing,
hideRelayoutSharedValue: sharedValue2,
overlayEnabled,
isInteracting,
withTiming: _timing.withTiming,
Easing: _ReanimatedRexport.Easing,
runOnJS: _ReanimatedRexport.runOnJS,
setShowHeader: setState
};
P.__workletHash = 14874736878670;
P.__initData = __initData4;
const animatedStyle2 = useAnimatedStyle(P);
const x = function x() {
if (overlayEnabled.get() && !isInteracting.get()) {
_ReanimatedRexport.runOnJS(setState)(true);
}
};
x.__closure = {
overlayEnabled,
isInteracting,
runOnJS: _ReanimatedRexport.runOnJS,
setShowHeader: setState
};
x.__workletHash = 2199049578465;
x.__initData = __initData6;
useDerivedValue(x);
const le = () => ({
...absoluteFillObject,
alignItems: "center",
justifyContent: "center",
transform: [{
translateY: translatePos.get()
}],
opacity: sharedValue2.get() ? 0 : _timing.withTiming(1, {
easing: _ReanimatedRexport.Easing.linear,
duration: 75
})
});
le.__closure = {
absoluteFillObject,
translatePos,
hideRelayoutSharedValue: sharedValue2,
withTiming: _timing.withTiming,
Easing: _ReanimatedRexport.Easing
};
le.__workletHash = 8244409104374;
le.__initData = __initData7;
const animatedStyle3 = useAnimatedStyle(le);
ref = useRef(null);
callback = useCallback(() => {
if (c19791_6 && animatedRef.current != null) {
sharedValue2.set(true);
clearTimeout(ref.current);
ref.current = setTimeout(() => {
sharedValue2.set(false);
}, 250);
}
}, [r5, animatedRef, sharedValue2]);
const callback2 = useCallback(() => {
sharedValue2.set(false);
}, [sharedValue2]);
ref2 = useRef(false);
useEffect(() => {
if (ref2.current) {
callback();
} else {
ref2.current = true;
}
}, [width, height, callback]);
useOrientationListener(useCallback((a0, a1) => {
if (a0.orientation !== a1.orientation) {
callback();
}
if (isAndroid) {
unpauseCurrentVideoIfNeeded();
}
}, [callback]));
return <AnalyticsLocationProvider value={analyticsLocations}>
<View style={StyleSheet.absoluteFill} onAccessibilityEscape={dismiss} onLayout={callback2}>
<StatusBar_android barStyle="light-content" hidden={!state} />
<ReanimatedRexport.View style={animatedStyle} />
<REAWorkaroundView ref={animatedRef} style={animatedStyle3}>
<Component entranceAnimationDriver={sharedValue} onContentSizeChange={onContentSizeChange} onScroll={onScroll} onLongPress={onLongPress2} originLayout={originLayout2} panGestureConfig={mediaViewerPanGestureConfig} ref={ref3} renderMedia={renderMedia2} sources={sources2} useItemVisible={useItemVisible2} windowHeight={height} windowWidth={width} index={index} zoomed={zoomed2} />
</REAWorkaroundView>
<REAWorkaroundView style={[r99, animatedStyle2]} pointerEvents={state ? "box-none" : "none"}>
{renderOverlay(dismiss, overlayEnabled)}
</REAWorkaroundView>
<HomeIndicator />
</View>
</AnalyticsLocationProvider>;
};
isAndroid = _PlatformUtils.isAndroid();
__initData = {
code: "function MediaViewerTsx1(){const{zoomed,pinching}=this.__closure;return!zoomed.get()&&!pinching.get();}"
};
__initData2 = {
code: "function MediaViewerTsx2(){const{scrollEnabled}=this.__closure;return{scrollEnabled:scrollEnabled.get()};}"
};
Component = memo(function({ entranceAnimationDriver, onContentSizeChange, onLongPress, onScroll, originLayout, panGestureConfig, renderMedia, sources, useItemVisible, windowWidth, windowHeight, ref: ref3, index, zoomed }) {
let derivedValue, panGestureGenerator;
derivedValue = void 0;
panGestureGenerator = void 0;
const sharedValue3 = useSharedValue(false);
const T = () => {
const r5 = zoomed.get();
return r5 ? !r5 : !sharedValue3.get();
};
T.__closure = {
zoomed,
pinching: sharedValue3
};
T.__workletHash = 9157951736691;
T.__initData = __initData;
derivedValue = useDerivedValue(T);
const callback2 = useCallback((a0) => sharedValue3.set(a0.nativeEvent.touches.length === 2), [sharedValue3]);
const callback3 = useCallback(() => sharedValue3.set(false), [sharedValue3]);
const mediaViewerPanGesture = useMediaViewerPanGesture(panGestureConfig, derivedValue);
panGestureGenerator = mediaViewerPanGesture.panGestureGenerator;
const nativeGesture = mediaViewerPanGesture.nativeGesture;
const callback4 = useCallback((a0, a1) => <MediaViewerItem originLayout={originLayout} renderMedia={renderMedia} onLongPress={onLongPress} windowWidth={windowWidth} windowHeight={windowHeight} panGestureConfig={panGestureConfig} entranceAnimationDriver={entranceAnimationDriver} source={sources[a1]} index={a1} zoomed={zoomed} panGesture={panGestureGenerator(a1)} useItemVisible={useItemVisible} />, [entranceAnimationDriver, onLongPress, originLayout, panGestureConfig, panGestureGenerator, renderMedia, sources, useItemVisible, windowHeight, windowWidth, zoomed]);
const H = () => ({
scrollEnabled: derivedValue.get()
});
H.__closure = {
scrollEnabled: derivedValue
};
H.__workletHash = 13550782123441;
H.__initData = __initData2;
const animatedProps = useAnimatedProps(H);
return <GestureDetector gesture={nativeGesture}>
<AnimatedFastList ref={ref3} style={StyleSheet.absoluteFill} sections={[sources.length]} onTouchStart={callback2} onTouchEnd={callback3} onTouchCancel={callback3} initialScrollItem={useStateFromSharedValue(index)} automaticallyAdjustContentInsets={false} showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false} itemSize={windowWidth} renderItem={callback4} onContentSizeChange={onContentSizeChange} pagingEnabled onScroll={onScroll} scrollEventThrottle={16} animatedProps={animatedProps} disableLegacyGestureHandling chunkBase={windowWidth} horizontal />
</GestureDetector>;
});
__initData3 = {
code: "function MediaViewerTsx3(){const{absoluteFillObject,windowHeight,entranceAnimationDriver,interpolate,translatePos,closePosition}=this.__closure;return{...absoluteFillObject,height:windowHeight,backgroundColor:'black',opacity:Math.min(entranceAnimationDriver.get(),interpolate(translatePos.get(),[-closePosition,0,closePosition],[0,1,0]))};}"
};
__initData4 = {
code: "function MediaViewerTsx4(){const{isClosing,hideRelayoutSharedValue,overlayEnabled,isInteracting,withTiming,Easing,runOnJS,setShowHeader}=this.__closure;return{opacity:isClosing.get()||hideRelayoutSharedValue.get()?0:overlayEnabled.get()&&!isInteracting.get()?withTiming(1,{easing:Easing.linear,duration:150}):withTiming(0,{easing:Easing.linear,duration:75},'respect-motion-settings',function(){runOnJS(setShowHeader)(false);})};}"
};
__initData5 = {
code: "function MediaViewerTsx5(){const{runOnJS,setShowHeader}=this.__closure;runOnJS(setShowHeader)(false);}"
};
__initData6 = {
code: "function MediaViewerTsx6(){const{overlayEnabled,isInteracting,runOnJS,setShowHeader}=this.__closure;if(overlayEnabled.get()&&!isInteracting.get()){runOnJS(setShowHeader)(true);}}"
};
__initData7 = {
code: "function MediaViewerTsx7(){const{absoluteFillObject,translatePos,hideRelayoutSharedValue,withTiming,Easing}=this.__closure;return{...absoluteFillObject,alignItems:'center',justifyContent:'center',transform:[{translateY:translatePos.get()}],opacity:hideRelayoutSharedValue.get()?0:withTiming(1,{easing:Easing.linear,duration:75})};}"
};
const r42 = memo(function(a0) {
return <MediaViewerDimensionsProvider>
<MediaViewer {...a0} />
</MediaViewerDimensionsProvider>;
});
export default r42;
@@ -0,0 +1,172 @@
// Metro module 12321 (f12322).
import * as Module19 from "react";
import { useRef, useState, useEffect, useCallback, useMemo } from "react";
import { ScrollView } from "react-native";
import * as _PlatformUtils from "../../../../utils/PlatformUtils";
import { dismissKeyboard } from "../../../../utils/native/ChatInputUtils";
import getMediaViewerStateForScreen from "../getMediaViewerStateForScreen";
import { useEntranceAnimationState } from "../useEntranceAnimation";
import { flattenSource } from "../MediaSourceUtil";
import { MediaViewerSourcesStore, removeSpoiler } from "../useMediaViewerSources";
import useShouldHideMediaOptions from "../../../media_channel/useShouldHideMediaOptions";
import { Gesture, GestureDetector } from "../../../../_bundle/Module5273";
import MediaViewerItemPresenter from "./MediaViewerItemPresenter";
import ZoomLayout_android from "../../../zoom_layout/ZoomLayout.android";
const isAndroid = _PlatformUtils.isAndroid();
const r29 = Module19.memo(function({ entranceAnimationDriver, index, onLongPress, originLayout, panGestureConfig, panGesture, renderMedia, source, useItemVisible, zoomed, windowWidth, windowHeight }) {
let ref3, ref4, setState3, callback, callback2, obscure, field, memo, c19795_19, callback3, callback4, callback5, callback6, ref5;
ref3 = void 0;
ref4 = void 0;
setState3 = void 0;
callback = void 0;
callback2 = void 0;
obscure = void 0;
field = void 0;
memo = void 0;
c19795_19 = void 0;
callback3 = void 0;
callback4 = void 0;
callback5 = void 0;
callback6 = void 0;
ref5 = void 0;
const ref = useRef(windowWidth);
const ref2 = useRef(windowHeight);
const [windowWidth2, setState] = useState(windowWidth);
const [windowHeight2, setState2] = useState(windowHeight);
useEffect(() => dismissKeyboard(), []);
useEffect(() => {
let c27287_0 = setTimeout(() => {
setState(windowWidth);
setState2(windowHeight);
ref.current = windowWidth;
ref2.current = windowHeight;
}, 20);
return () => clearTimeout(c27287_0);
}, [windowWidth, windowHeight]);
const maximumZoomScale = getMediaViewerStateForScreen(windowWidth2, windowHeight2, source).maximumZoomScale;
ref3 = useRef(null);
ref4 = useRef(null);
let state;
[state, setState3] = useState(false);
callback = useCallback((a0, a1) => {
if (ref3.current != null) {
const current2 = ref.current;
const current3 = ref2.current;
const width = current2 / 2;
const height = current3 / 2;
ref3.current.getScrollResponder().scrollResponderZoomTo({
x: a0 - width / 2,
y: a1 - height / 2,
width,
height,
animated: true
});
} else if (ref4.current !== null) {
const current = ref4.current;
if (current != null) {
current.zoomTo({
x: a0,
y: a1
});
}
}
}, []);
callback2 = useCallback(function(animated = true) {
if (ref3.current != null) {
const current = ref.current;
const current2 = ref2.current;
ref3.current.getScrollResponder().scrollResponderZoomTo({
x: 0,
y: 0,
width: current,
height: current2,
animated
});
} else if (ref4.current !== null) {
ref4.current.unzoom({
animated
});
}
}, []);
const callback7 = useCallback((a0) => {
const r1 = a0.nativeEvent.zoomScale > 1;
zoomed.set(r1);
panGestureConfig.isInteracting.set(r1);
let r16 = isAndroid;
if (!isAndroid) {
r16 = !useEntranceAnimationState.getState().isComplete;
}
if (!r16) {
r16 = r1;
}
if (!r16) {
setState3(true);
setTimeout(() => {
setState3(false);
}, 500);
}
}, [zoomed, panGestureConfig]);
let r77 = flattenSource(source);
if (r77 == null) {
r77 = {};
}
obscure = r77.obscure;
const channelId = r77.channelId;
field = MediaViewerSourcesStore.useField("spoilerIndexes");
memo = useMemo(() => field.has(index), [index, field]);
const shouldHideMediaOptions = useShouldHideMediaOptions(channelId);
c19795_19 = shouldHideMediaOptions;
callback3 = useCallback(() => {
if (memo) {
removeSpoiler(index);
} else if (!c19795_19 && onLongPress != null) {
onLongPress();
}
}, [memo, index, onLongPress, shouldHideMediaOptions]);
callback4 = useCallback(() => {
if (!zoomed.get()) {
panGestureConfig.overlayEnabled.set(!panGestureConfig.overlayEnabled.get());
}
}, [zoomed, panGestureConfig]);
callback5 = useCallback(({ absoluteX, absoluteY }) => {
if (zoomed.get()) {
callback2();
} else if (!zoomed.get()) {
callback(absoluteX, absoluteY);
}
}, [callback2, callback, zoomed]);
callback6 = useCallback(() => {
removeSpoiler(index);
}, [index]);
const memo2 = useMemo(() => {
const r26 = Gesture.Tap().runOnJS(true).enabled(!memo).numberOfTaps(2);
const isAndroid2 = _PlatformUtils.isAndroid();
let r30 = 10;
const r15 = r26.maxDistance(isAndroid2 ? 20 : 10).onStart(callback5);
const r55 = Gesture.Tap().runOnJS(true).enabled(!memo).numberOfTaps(1).maxDistance(_PlatformUtils.isAndroid() ? 20 : 10).onStart(callback4);
const r67 = Gesture.Tap().runOnJS(true).enabled(memo ? !obscure : memo).numberOfTaps(1);
if (_PlatformUtils.isAndroid()) {
r30 = 20;
}
return Gesture.Simultaneous(Gesture.Exclusive(r67.maxDistance(r30).onStart(callback6), r15, r55), Gesture.LongPress().runOnJS(true).enabled(!memo).onStart(callback3), panGesture);
}, [callback5, callback3, callback6, memo, obscure, panGesture, callback4]);
ref5 = useRef(false);
useEffect(() => {
if (ref5.current) {
callback2(false);
} else {
ref5.current = true;
}
}, [callback2, windowWidth2, windowHeight2]);
const r125 = <GestureDetector gesture={memo2}>
<MediaViewerItemPresenter entranceAnimationDriver={entranceAnimationDriver} index={index} originLayout={originLayout} panGestureConfig={panGestureConfig} renderMedia={renderMedia} source={source} windowWidth={windowWidth2} windowHeight={windowHeight2} useItemVisible={useItemVisible} />
</GestureDetector>;
return isAndroid ? <ZoomLayout_android ref={ref4} style={{
width: windowWidth2,
height: windowHeight2
}} minimumZoomScale={1} maximumZoomScale={maximumZoomScale} onZoomChanged={callback7}>{r125}</ZoomLayout_android> : <ScrollView ref={ref3} style={{
width: windowWidth2,
height: windowHeight2
}} automaticallyAdjustContentInsets={false} showsHorizontalScrollIndicator={false} showsVerticalScrollIndicator={false} minimumZoomScale={1} maximumZoomScale={maximumZoomScale} centerContent scrollEventThrottle={16} onScroll={callback7} pointerEvents={state ? "none" : "auto"}>{r125}</ScrollView>;
});
export { r29 as MediaViewerItem };
@@ -0,0 +1,167 @@
// Metro module 12324 (f12325).
import { useMemo } from "react";
import { StyleSheet, View } from "react-native";
import { useEntranceAnimation } from "../useEntranceAnimation";
import { MediaViewerSourcesStore } from "../useMediaViewerSources";
import getMediaViewerStateForScreen from "../getMediaViewerStateForScreen";
import * as _ReanimatedRexport from "../../../reanimated/ReanimatedRexport";
import { useAnimatedStyle } from "../../../reanimated/ReanimatedRexport";
import REAWorkaroundView from "../../../reanimated/native/REAWorkaroundView";
let c8519_7 = {
platformStyles: {
position: "absolute",
width: "100%",
height: "100%"
}
};
const __initData = {
code: "function MediaViewerItemPresenterTsx1(){const{entranceAnimationDriver,interpolate,Extrapolation,startHeight,sourceHeight,startWidth,sourceWidth,startTranslateY,startTranslateX,startScale}=this.__closure;const entranceValue=entranceAnimationDriver.get();function interpolateProxy(from,to){return interpolate(entranceValue,from,to,Extrapolation.CLAMP);}return{height:interpolateProxy([0,1],[startHeight,sourceHeight]),width:interpolateProxy([0,1],[startWidth,sourceWidth]),top:interpolateProxy([0,1],[startTranslateY,0]),left:interpolateProxy([0,1],[startTranslateX,0]),borderRadius:interpolateProxy([0,0.25],[16,0]),transform:[{scale:interpolateProxy([0,1],[startScale,1])}]};}"
};
export default function MediaViewerItemPresenter(props) {
let startHeight, startScale, startWidth;
let width, height, c19798_7, c19798_8, c19798_9, width2, height2;
const { source, originLayout, renderMedia, windowWidth, windowHeight, entranceAnimationDriver, index, useItemVisible, panGestureConfig } = props;
width = void 0;
height = void 0;
c19798_7 = void 0;
c19798_8 = void 0;
c19798_9 = void 0;
width2 = void 0;
height2 = void 0;
const entranceAnimation = useEntranceAnimation(entranceAnimationDriver);
const { loads, handleLoad, handleError, handleLoadStart } = entranceAnimation;
const field = MediaViewerSourcesStore.useField("spoilerIndexes");
const memo = useMemo(() => field.has(index), [index, field]);
const mediaViewerStateForScreen = getMediaViewerStateForScreen(windowWidth, windowHeight, source);
width = mediaViewerStateForScreen.width;
height = mediaViewerStateForScreen.height;
const visible = useItemVisible(index);
const r53 = [];
if (Array.isArray(source)) {
const r6 = loads <= 1;
if (r6) {
r53.push(renderMedia({
key: `0:${index}:${source[0].uri}`,
onLoadStart: handleLoadStart,
onLoad: handleLoad,
onError: handleError,
source: source[0],
style: c8519_7.platformStyles,
index,
hasSpoiler: memo,
visible,
panGestureConfig
}));
}
if (loads >= 1) {
r53.push(renderMedia({
key: `1:${index}:${source[0].uri}`,
source: source[1],
style: c8519_7.platformStyles,
onLoad: handleLoad,
onError: handleError,
pointerEvents: r6 ? "none" : "auto",
fadeDuration: 0,
fade: false,
index,
hasSpoiler: memo,
visible,
panGestureConfig
}));
}
} else {
r53.push(renderMedia({
key: `0:${index}:${source.uri}`,
onLoadStart: handleLoadStart,
onLoad: handleLoad,
onError: handleError,
source,
style: c8519_7.platformStyles,
index,
hasSpoiler: memo,
visible,
panGestureConfig
}));
}
const r93 = width / height;
const r96 = originLayout.width / originLayout.height;
let startTranslateX = originLayout.x - (width - originLayout.width) / 2 - (windowWidth - width) / 2;
c19798_8 = startTranslateX;
const r106 = (height - originLayout.height) / 2;
const r3 = (windowHeight - height) / 2;
let startTranslateY = originLayout.y - r106 - r3;
c19798_9 = startTranslateY;
width2 = width;
height2 = height;
if (originLayout.resizeMode === "cover") {
const width3 = originLayout.width;
width2 = width3;
const height3 = originLayout.height;
height2 = height3;
const r124 = originLayout.x - (windowWidth - width) / 2;
c19798_8 = r124;
const r4 = originLayout.y - r3;
c19798_9 = r4;
c19798_7 = 1;
startHeight = height3;
startWidth = width3;
startTranslateY = r4;
startTranslateX = r124;
startScale = 1;
} else {
startScale = originLayout.width / width * (r93 > r96 ? r93 : 1);
c19798_7 = startScale;
startHeight = height;
startWidth = width;
}
const O = function O() {
const r10 = entranceAnimationDriver.get();
return {
height: _ReanimatedRexport.interpolate(r10, [0, 1], [height2, height], _ReanimatedRexport.Extrapolation.CLAMP),
width: _ReanimatedRexport.interpolate(r10, [0, 1], [width2, width], _ReanimatedRexport.Extrapolation.CLAMP),
top: _ReanimatedRexport.interpolate(r10, [0, 1], [c19798_9, 0], _ReanimatedRexport.Extrapolation.CLAMP),
left: _ReanimatedRexport.interpolate(r10, [0, 1], [c19798_8, 0], _ReanimatedRexport.Extrapolation.CLAMP),
borderRadius: _ReanimatedRexport.interpolate(r10, [0, 0.25], [16, 0], _ReanimatedRexport.Extrapolation.CLAMP),
transform: [{
scale: _ReanimatedRexport.interpolate(r10, [0, 1], [c19798_7, 1], _ReanimatedRexport.Extrapolation.CLAMP)
}]
};
};
O.__closure = {
entranceAnimationDriver,
interpolate: _ReanimatedRexport.interpolate,
Extrapolation: _ReanimatedRexport.Extrapolation,
startHeight,
sourceHeight: height,
startWidth,
sourceWidth: width,
startTranslateY,
startTranslateX,
startScale
};
O.__workletHash = 15052076990644;
O.__initData = __initData;
const animatedStyle = useAnimatedStyle(O);
const memo2 = useMemo(() => StyleSheet.create({
container: {
width: windowWidth,
height: windowHeight,
alignItems: "center",
justifyContent: "center"
},
child: {
width,
height
},
presenter: {
position: "relative",
overflow: "hidden",
opacity: 1
}
}), [windowWidth, windowHeight, width, height]);
return <View collapsable={false} style={memo2.container}>
<View style={memo2.child}>
<REAWorkaroundView style={[memo2.presenter, animatedStyle]}>{r53}</REAWorkaroundView>
</View>
</View>;
};
@@ -0,0 +1,125 @@
// Metro module 12302 (f12303).
import _slicedToArray from "../../../../_bundle/_slicedToArray";
import * as Module19 from "react";
import { useCallback, useMemo } from "react";
import { Pressable, StyleSheet } from "react-native";
import * as _Constants from "../Constants";
import { THUMBNAIL_WIDTH_MARGIN } from "../Constants";
import { useMediaItemSpoilerState } from "../useMediaItemSpoilerState";
import { useToken } from "../../../../design/tokens/native/useToken";
import Module712 from "../../../../_bundle/Module712";
import ReanimatedRexport, { useAnimatedProps } from "../../../reanimated/ReanimatedRexport";
import VisualEffectView from "../../../visual_effect_view/native/VisualEffectView";
import { isAndroid } from "../../../../utils/PlatformUtils";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import FastImage from "../../../../components_native/common/FastImage";
import { useSelectedMediaSource } from "../MediaSourceUtil";
import REAWorkaroundView from "../../../reanimated/native/REAWorkaroundView";
import { AnimatedFastList } from "../../../../lib/native/FastList";
let useStyles, Component, __initData;
const ObscuredView = function ObscuredView(props) {
let r28;
L6: {
const source = props.source;
const [r20, r13] = useMediaItemSpoilerState(props.index);
const token = useToken(Module712.colors.SPOILER_HIDDEN_BACKGROUND);
r28 = null;
if (r20) {
if (!source.spoiler) {
const obscure = source.obscure;
r28 = null;
if (!obscure) {
break L6;
}
}
r28 = <ReanimatedRexport.View style={[StyleSheet.absoluteFill, r13]}>
<VisualEffectView blurTheme={isAndroid() ? "dark" : "light"} style={StyleSheet.absoluteFill} android_fallbackColor={token} />
</ReanimatedRexport.View>;
}
}
return r28;
};
const { THUMBNAIL_MARGIN, THUMBNAIL_HEIGHT } = _Constants;
useStyles = createStyles({
containerPortrait: {
height: 60
},
thumbnailButtonPortrait: {
overflow: "hidden",
marginHorizontal: THUMBNAIL_MARGIN,
borderRadius: 2
},
thumbnailImagePortrait: {
height: THUMBNAIL_HEIGHT,
width: "100%"
}
});
Component = Module19.memo(function({ source, numSources, selectedIndex: selectedIndex2, index, onSelect, useThumbnailStyle: useThumbnailStyle2 }) {
const styles = useStyles();
const source2 = Array.isArray(source) ? source[0] : source;
const r25 = useThumbnailStyle2(source2, index);
const props = {
needsOffscreenAlphaCompositing: true,
renderToHardwareTextureAndroid: true,
accessibilityRole: "imagebutton",
accessibilityLabel: `Thumbnail preview, ${index + 1} of ${numSources}`,
accessibilityHint: "Double tap to focus",
accessibilityState: {
selected: selectedIndex2 === index
},
onPress: useCallback(() => onSelect(index), [onSelect, index]),
children: null
};
let thumbnail = source2.thumbnail;
if (thumbnail == null) {
thumbnail = source2;
}
props.children = [<FastImage style={styles.thumbnailImagePortrait} source={thumbnail} enableAnimation={false} />, <ObscuredView source={source2} index={index} />];
return <ReanimatedRexport.View style={[styles.thumbnailButtonPortrait, r25]}>
<Pressable {...props} />
</ReanimatedRexport.View>;
});
__initData = {
code: "function MediaViewerThumbnailsTsx1(){const{scrollEnabled}=this.__closure;return{scrollEnabled:scrollEnabled.get()};}"
};
export default function MediaViewerThumbnails(props) {
let selectedIndex;
const syncer = props.syncer;
selectedIndex = void 0;
const styles = useStyles();
const { sources, useThumbnailsProps, index: index2, onEndReached, onEndReachedThreshold, variableWidthThumbnailsEnabled, thumbnailScrollPositions } = syncer;
const r30 = useThumbnailsProps(THUMBNAIL_WIDTH_MARGIN, sources.length - 1);
const { ref, headerBufferSize, headerBufferStyle, footerBufferSize, footerBufferStyle, scrollEnabled, onScroll, onSelect: onSelect2, useThumbnailStyle, screenWidth, itemSize } = r30;
const memo = useMemo(() => {
const r5 = [];
const length = thumbnailScrollPositions.length;
let r0 = 0;
if (0 < length) {
do {
const r1 = r0;
if (variableWidthThumbnailsEnabled) {
r5.push(thumbnailScrollPositions[r1].scrollStart);
} else {
r5.push(r1 * THUMBNAIL_WIDTH_MARGIN);
}
r0 = r1 + 1;
} while (r0 < thumbnailScrollPositions.length);
}
return r5;
}, [thumbnailScrollPositions, variableWidthThumbnailsEnabled]);
selectedIndex = _slicedToArray(useSelectedMediaSource(syncer), 1)[0];
const callback = useCallback((a0, a1) => <Component index={a1} source={sources[a1]} numSources={sources.length} selectedIndex={selectedIndex} onSelect={onSelect2} useThumbnailStyle={useThumbnailStyle} />, [sources, selectedIndex, onSelect2, useThumbnailStyle]);
const memo2 = useMemo(() => [sources.length], [sources.length]);
const n = () => ({
scrollEnabled: scrollEnabled.get()
});
n.__closure = {
scrollEnabled
};
n.__workletHash = 13439565264141;
n.__initData = __initData;
const animatedProps = useAnimatedProps(n);
const callback2 = useCallback(() => <REAWorkaroundView style={headerBufferStyle} />, [headerBufferStyle]);
const callback3 = useCallback(() => <REAWorkaroundView style={footerBufferStyle} />, [footerBufferStyle]);
return <AnimatedFastList ref={ref} style={styles.containerPortrait} sections={memo2} stickyHeaderFooter disableContentWrappers automaticallyAdjustContentInsets={false} showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false} initialScrollOrientation="center" initialScrollItem={useMemo(() => index2.get(), [index2])} itemSize={itemSize} renderItem={callback} onScroll={onScroll} horizontal headerSize={headerBufferSize} footerSize={footerBufferSize} renderHeader={callback2} renderFooter={callback3} onEndReached={onEndReached} endReachedThreshold={onEndReachedThreshold} chunkBase={screenWidth} snapToOffsets={memo} animatedProps={animatedProps} />;
};
@@ -0,0 +1,309 @@
// Metro module 12312 (f12313).
import { useMemo, useState, useRef, useEffect, useCallback } from "react";
import { findNodeHandle, ScrollView } from "react-native";
import ForumPostMessagesStore from "../../../../forums/ForumPostMessagesStore";
import SearchMessageStore from "../../../../search/SearchMessageStore";
import ChannelStore from "../../../../../stores/ChannelStore";
import MessageStore from "../../../../../stores/MessageStore";
import MessagePreviewStore from "../../../../../stores/native/MessagePreviewStore";
import { ThemeTypes } from "../../../../../Constants";
import RowGenerator from "../../../../messages/native/renderer/RowGenerator";
import { MessageContextType } from "../../../../messages/native/renderer/RowGeneratorTypes";
import { createStyles, createNativeStyleProperties } from "../../../../../design/components/Styles/native/createStyles";
import { useMediaViewerDimensions } from "../../MediaViewerDimensionsContext";
import ChatItem from "../../../../../components_native/chat/ChatItem";
import Module712 from "../../../../../_bundle/Module712";
import { useStateFromStores } from "../../../../../_bundle/Module589";
import useReactionPermissions from "../../../../messages/useReactionPermissions";
import { intl, t } from "../../../../../intl/index.native";
import SnowflakeUtils from "../../../../../utils/SnowflakeUtils";
import showMediaMessagePreviewActionSheet from "./showMediaMessagePreviewActionSheet";
import { getNativeSyntheticEventData } from "../../../../messages/native/snowflake/MessageDataSnowflakeUtils";
import { handleAddOrRemoveReaction } from "../../../../messages/native/MessagesUtils";
import { ReactionLocations } from "../../../../reactions/ReactionActionCreators";
import showLongPressURLActionSheet from "../../../../links/native/showLongPressURLActionSheet";
import { Gesture, GestureDetector } from "../../../../../_bundle/Module5273";
import Chat_android from "../../../../chat/native/Chat.android";
import { handleMessagesTapLink } from "../../../../messages/native/handlers/handleMessagesTapLink";
import { transitionToThread } from "../../../../routing/transitionToChannel";
import { HermesBuiltin } from "../../../../../_hermes/prelude";
function $mk116394($env) {
return (a0) => {
const r5 = Math;
const height = a0.nativeEvent.layout.height;
const r9 = $env.$parent;
const r10 = r5.min(height, r9[5]);
if (r10 !== 0) {
if ($env[0]) {
(0, r9[2])(r10);
} else {
(0, r9[1])(r10);
}
}
};
}
function $mk116395($env) {
return (a0) => {
const r2 = $env.$parent.$parent;
a0.canAddNewReactions = !$env.$parent[3];
a0.contextType = (0, r2[0])(r2[2][11]).MessageContextType.MEDIA_VIEWER;
if ($env[0]) {
a0.truncation = {
numberOfLines: 3,
expandable: false,
seeMoreLabel: ""
};
}
};
}
let c8507_16, useStyles, c8507_19, c8507_20;
let env8507 = {};
const MeasureMessage = function MeasureMessage(props) {
let env19785 = {
$parent: env8507
};
const message = props.message;
env19785[0] = message;
const onMeasure = props.onMeasure;
env19785[1] = onMeasure;
const onMeasureTruncated = props.onMeasureTruncated;
env19785[2] = onMeasureTruncated;
const disableReactionCreates2 = props.disableReactionCreates;
env19785[3] = disableReactionCreates2;
env19785[4] = void 0;
env19785[5] = void 0;
const styles = useStyles();
env19785[4] = styles;
const r21 = 0.5 * useMediaViewerDimensions().height;
env19785[5] = r21;
const memo = useMemo(() => {
let env27284;
let env27285;
const r4 = env27284 = {
$parent: env19785
};
env27284[0] = false;
const rowGenerator = c8507_16;
const full2 = {
onLayout: $mk116394(r4),
modifyRow: $mk116395(r4),
rowGenerator,
message: null,
style: null
};
const message = env19785[0];
full2.message = message;
const r12 = env19785[4];
full2.style = r12.dummyLayout;
const r13 = env27285 = {
$parent: env19785
};
env27285[0] = true;
return {
full: full2,
truncated: {
onLayout: $mk116394(r13),
modifyRow: $mk116395(r13),
rowGenerator,
message,
style: r12.dummyLayout
}
};
}, [disableReactionCreates2, r21, message, onMeasureTruncated, onMeasure, styles.dummyLayout]);
return <>
<ChatItem {...memo.full} />
<ChatItem {...memo.truncated} />
</>;
};
const rowGenerator = new RowGenerator();
c8507_16 = rowGenerator;
rowGenerator.setOptions({
renderCodedLinks: false,
renderGiftCode: false,
renderActivityInstanceEmbed: false,
renderActivityInviteEmbed: false,
renderComponents: false,
renderEmbeds: false,
ignoreMentioned: true,
inlineAttachmentMedia: false,
inlineEmbedMedia: false,
renderReactions: true,
renderAttachments: false,
renderReplies: false,
renderThreadEmbeds: false,
renderPolls: false,
renderForumPostActions: false,
forcedTheme: ThemeTypes.DARK,
forceHideSimpleEmbedContent: true
});
useStyles = createStyles({
dummyLayout: {
position: "absolute",
top: 0,
left: -9999,
bottom: 0,
width: "100%",
opacity: 0
}
});
c8507_19 = createNativeStyleProperties({
reactionBackgroundColor: Module712.colors.REACTION_BACKGROUND_DEFAULT,
reactionBorderColor: Module712.colors.REACTION_BORDER_DEFAULT,
reactionTextColor: Module712.colors.REACTION_TEXT_DEFAULT,
activeReactionBackgroundColor: Module712.colors.REACTION_BACKGROUND_REACTED_DEFAULT,
activeReactionBorderColor: Module712.colors.REACTION_BORDER_REACTED_DEFAULT,
activeReactionTextColor: Module712.colors.REACTION_TEXT_REACTED_DEFAULT
});
c8507_20 = createNativeStyleProperties({
editedColor: Module712.colors.TEXT_MUTED,
seeMoreLabelColor: Module712.colors.TEXT_DEFAULT
});
export default function MediaMessagePreview(props) {
let disableReactionCreates, setState, setState2, ref, state, setState3, reactionsTheme, editedColor, seeMoreLabelColor, stateFromStores2, state2, setState4;
const { channelId, messageId, onClose, onTapMessage, onMeasureFullHeight, onMeasureCollapsedHeight, full, canExpand, setScrollViewIsAtTop, flingUpRef, flingDownRef, animationDriver } = props;
disableReactionCreates = void 0;
setState = void 0;
setState2 = void 0;
ref = void 0;
state = void 0;
setState3 = void 0;
reactionsTheme = void 0;
editedColor = void 0;
seeMoreLabelColor = void 0;
stateFromStores2 = void 0;
state2 = void 0;
setState4 = void 0;
const stateFromStores = useStateFromStores([ChannelStore], () => channelId != null ? ChannelStore.getChannel(channelId) : void 0);
disableReactionCreates = useReactionPermissions(stateFromStores).disableReactionCreates;
let bounces;
[bounces, setState] = useState(false);
let state3;
[state3, setState2] = useState(false);
ref = useRef(null);
[state, setState3] = useState(null);
useEffect(() => {
setState3((0, findNodeHandle)(ref.current));
}, []);
reactionsTheme = c8507_19(ThemeTypes.MIDNIGHT);
const r67 = c8507_20(ThemeTypes.MIDNIGHT);
editedColor = r67.editedColor;
seeMoreLabelColor = r67.seeMoreLabelColor;
const callback = useCallback((a0) => {
a0.canAddNewReactions = !disableReactionCreates;
a0.contextType = MessageContextType.MEDIA_VIEWER;
a0.reactTag = state;
a0.canAddNewReactions = !disableReactionCreates;
a0.message.feedbackColor = void 0;
a0.message.editedColor = editedColor;
a0.reactionsTheme = reactionsTheme;
if (!full) {
a0.truncation = {
numberOfLines: 3,
expandable: true,
seeMoreLabel: ` ${intl.string(t["7qbp3B"])}`,
seeMoreLabelColor,
outAnimationDuration: Math.min(0.25 * animationDriver.get(), 0.1),
outAnimation: "fade"
};
}
}, [state, disableReactionCreates, editedColor, seeMoreLabelColor, reactionsTheme, full, animationDriver]);
stateFromStores2 = useStateFromStores([SearchMessageStore, MessageStore, MessagePreviewStore, ForumPostMessagesStore], () => {
if (channelId != null && messageId != null) {
let r11 = MessageStore.getMessage(channelId, messageId);
if (r11 == null) {
r11 = MessagePreviewStore.getMessage(messageId);
}
if (r11 == null) {
r11 = ForumPostMessagesStore.getMessage(SnowflakeUtils.castMessageIdAsChannelId(messageId))?.firstMessage;
}
if (r11 == null) {
r11 = SearchMessageStore.getMessage(messageId);
}
return r11;
}
}, [channelId, messageId]);
[state2, setState4] = useState(0);
const callback2 = useCallback((a0, a1) => {
setState4(a1);
}, []);
const callback3 = useCallback((a0) => {
setState2(true);
setState(state2 > a0.nativeEvent.layout.height && full);
}, [full, state2]);
const callback4 = useCallback((a0) => {
showMediaMessagePreviewActionSheet({
channelId: getNativeSyntheticEventData(a0).channelId,
message: stateFromStores2,
closeMediaModal: onClose
});
}, [stateFromStores2, onClose]);
const callback5 = useCallback((a0) => {
if (a0 == null) {
HermesBuiltin.throwTypeError("Cannot destructure 'undefined' or 'null'.");
throw new Error("unreachable");
}
}, [stateFromStores2]);
const callback6 = useCallback(({ nativeEvent }) => {
const { reaction, isBurst } = nativeEvent;
if (stateFromStores2 != null) {
const channel = ChannelStore.getChannel(channelId);
if (channel != null && messageId != null) {
handleAddOrRemoveReaction(messageId, channel, reaction != null ? {
...reaction,
emoji: reaction.emoji
} : null, isBurst, ReactionLocations.MOBILE_MEDIA_VIEWER);
}
}
}, [channelId, stateFromStores2, messageId]);
const callback7 = useCallback((a0) => {
const url = a0.nativeEvent.url;
if (url != null && url !== "") {
showLongPressURLActionSheet({
urlString: url
});
}
}, []);
const memo = useMemo(() => Gesture.Native().requireExternalGestureToFail(flingUpRef, flingDownRef), [flingDownRef, flingUpRef]);
return stateFromStores2 == null ? null : stateFromStores == null ? null : <>
<GestureDetector gesture={memo}>
<ScrollView scrollEventThrottle={16} onScroll={({ nativeEvent }) => {
const { contentOffset, velocity } = nativeEvent;
let r1 = contentOffset.y === 0;
if (r1) {
let r11 = velocity?.y;
if (r11 == null) {
r11 = 0;
}
r1 = r11 === 0;
}
setScrollViewIsAtTop(r1);
}} onLayout={callback3} onContentSizeChange={callback2} showsVerticalScrollIndicator={full} bounces={bounces}>
<Chat_android ref={ref} onLongPressLink={callback7} onLongPressMessage={callback4} onTapMessage={onTapMessage} onTapReaction={callback6} onTapSeeMore={onTapMessage} onTapTag={callback5} onTapLink={function onTapLink(event) {
if (canExpand && !full) {
onTapMessage();
} else {
handleMessagesTapLink({
allowWithinModal: true,
chatInputRef: void 0,
handleTransitionToThread: (a0, a1, a2) => {
const channel = ChannelStore.getChannel(a1);
if (channel != null) {
transitionToThread(channel, {
source: a2,
navigationReplace: false
});
}
},
message: stateFromStores2,
messageChannel: stateFromStores,
selectedChannelId: channelId,
tapLinkData: event.nativeEvent
});
}
}} inverted={false} />
<ChatItem rowGenerator={c8507_16} modifyRow={callback} message={stateFromStores2} />
</ScrollView>
</GestureDetector>
{state3 ? <MeasureMessage disableReactionCreates={disableReactionCreates} message={stateFromStores2} onMeasure={onMeasureFullHeight} onMeasureTruncated={onMeasureCollapsedHeight} /> : null}
</>;
};
@@ -0,0 +1,52 @@
// Metro module 12314 (f12315).
import { memo, useCallback } from "react";
import { DeveloperMode } from "../../../../user_settings/UserSettings";
import { canReportUser, canReportMessage } from "../../../../../utils/ReportUtils";
import ActionSheetActionCreators from "../../../../action_sheet/native/ActionSheetActionCreators";
import { transitionToGuild } from "../../../../routing/router_utils";
import { copy } from "../../../../../utils/ClipboardUtils.native";
import { presentIdCopied } from "../../../../toast/native/ToastUtils";
import { showReportModalForMessage } from "../../../../in_app_reports/ReportModals";
import { ActionSheet } from "../../../../../design/components/Sheet/native/ActionSheet.native";
import { ActionSheetRow } from "../../../../../design/components/Sheet/native/ActionSheetRow.native";
import { ChatArrowRightIcon } from "../../../../../design/components/Icon/native/redesign/generated/ChatArrowRightIcon";
import { intl, t } from "../../../../../intl/index.native";
import { IdIcon } from "../../../../../design/components/Icon/native/redesign/generated/IdIcon";
import { FlagIcon } from "../../../../../design/components/Icon/native/redesign/generated/FlagIcon";
const r21 = memo(function MediaMessagePreviewActionSheet(props) {
const { channel, message, user, closeMediaModal } = props;
let r20 = DeveloperMode.useSetting();
const isNonUserBot = user.isNonUserBot();
let r8 = (isNonUserBot ? !isNonUserBot : canReportUser(user)) && canReportMessage(message);
const callback = useCallback(() => {
ActionSheetActionCreators.hideActionSheet();
}, []);
const callback2 = useCallback(() => {
callback();
closeMediaModal();
transitionToGuild(channel.guild_id, channel.id, message.id);
}, [callback, closeMediaModal, channel.guild_id, channel.id, message.id]);
const callback3 = useCallback(() => {
callback();
copy(message.id);
presentIdCopied();
}, [message.id, callback]);
const callback4 = useCallback(() => {
callback();
showReportModalForMessage(message, "mobile_media_message_preview_action_sheet");
}, [message, callback]);
const Group = ActionSheetRow.Group;
const children = [<ActionSheetRow icon={<ActionSheetRow.Icon IconComponent={ChatArrowRightIcon} />} label={intl.string(t["+TSRGD"])} onPress={callback2} />, , ,];
if (r20) {
r20 = <ActionSheetRow icon={<ActionSheetRow.Icon IconComponent={IdIcon} />} label={intl.string(t.zBoHlf)} onPress={callback3} />;
}
children[1] = r20;
if (r8) {
r8 = <ActionSheetRow icon={<ActionSheetRow.Icon IconComponent={FlagIcon} />} label={intl.string(t["+78Pfm"])} onPress={callback4} variant="danger" />;
}
children[2] = r8;
return <ActionSheet>
<Group hasIcons>{children}</Group>
</ActionSheet>;
});
export default r21;
@@ -0,0 +1,18 @@
// Metro module 12313 (f12314).
import ChannelStore from "../../../../../stores/ChannelStore";
import UserStore from "../../../../../stores/UserStore";
import ActionSheetActionCreators from "../../../../action_sheet/native/ActionSheetActionCreators";
export default function showMediaMessagePreviewActionSheet({ channelId, closeMediaModal, message }) {
const channel = ChannelStore.getChannel(channelId);
if (channel != null && message != null) {
const user = UserStore.getUser(message.author.id);
if (user != null) {
ActionSheetActionCreators.openLazy(import("./MediaMessagePreviewActionSheet"), "MediaMessagePreviewActionSheet", {
channel,
message,
user,
closeMediaModal
});
}
}
};
@@ -0,0 +1,150 @@
// Metro module 8115 (f8116).
import _slicedToArray from "../../../../_bundle/_slicedToArray";
import ActionSheetStore from "../../../action_sheet/native/ActionSheetStore";
import { MEDIA_MODAL_KEY } from "../../../../Constants";
import * as _asyncRequire from "../../../../_bundle/asyncRequire";
import Module38 from "../../../../_bundle/Module38";
import ActionSheetActionCreators from "../../../action_sheet/native/ActionSheetActionCreators";
import ModalActionCreators from "../../../../actions/ModalActionCreators";
function $mk115104($env) {
return function getMeasureInWindowFunction(a0) {
let env31443 = {
$parent: $env
};
env31443[0] = a0;
return a0 != null && "measureInWindow" in a0 ? a0.measureInWindow.bind(a0) : (a0) => {
let r13 = env31443[0];
if (r13 == null) {
const r3 = env31443.$parent;
const r4 = r3[0];
const r14 = r3[2];
r13 = {
x: 0,
y: 0,
width: r4(r14[4]).getWindowDimensions().width,
height: r4(r14[4]).getWindowDimensions().height
};
}
a0(r13.x, r13.y, r13.width, r13.height, r13.resizeMode);
};
};
}
function $mk115105($env) {
return (a0, a1, a2, a3, a4) => {
let initialIndex;
const r1 = $env;
if (r1[6] === "action-sheet") {
Module38(ActionSheetStore.isOpen(), "An action sheet must be open to open the media modal as an action sheet");
const r61 = _asyncRequire(dependencyMap[11], dependencyMap.paths);
const initialIndex2 = r1[1];
ActionSheetActionCreators.openLazy(r61, MEDIA_MODAL_KEY, {
...r1[7],
initialIndex: initialIndex2,
originLayout: {
x: a0,
y: a1,
width: a2,
height: a3,
resizeMode: a4
},
onCloseCallback: r1[5],
disableHapticOnOpen: true
}, "stack");
initialIndex = initialIndex2;
} else {
const r6 = _asyncRequire(dependencyMap[13], dependencyMap.paths);
initialIndex = r1[1];
ModalActionCreators.pushLazy(r6, {
...r1[7],
initialIndex,
originLayout: {
x: a0,
y: a1,
width: a2,
height: a3,
resizeMode: a4
},
onCloseCallback: r1[5]
}, MEDIA_MODAL_KEY, {
animation: "none"
});
}
const r77 = r1[10];
const sources = r1[2];
r77({
sources,
initialIndex
});
r1[11].markSessionStarted({
channelId: r1[4],
numMediaItems: sources.length,
source: r1[3]
});
(0, r1[12])();
};
}
let env5151 = {};
export async function openMediaModal(c26108_0) {
let r13, openAs;
let c26108_1, c26108_2;
let env29892;
L10: {
const r31 = env5151;
c26108_2 = r31;
const r10 = env29892 = {
$parent: r31
};
c26108_1 = r10;
env29892[0] = void 0;
env29892[1] = void 0;
env29892[2] = void 0;
env29892[3] = void 0;
env29892[4] = void 0;
env29892[5] = void 0;
env29892[6] = void 0;
env29892[7] = void 0;
r13 = c26108_0;
env29892[0] = r13.originViewOrOriginLayout;
const initialIndex = r13.initialIndex;
if (initialIndex !== void 0) {
env29892[1] = initialIndex;
env29892[2] = r13.initialSources;
env29892[3] = r13.analyticsSource;
env29892[4] = r13.channelId;
env29892[5] = r13.onClose;
openAs = r13.openAs;
if (openAs !== void 0) {
break L10;
}
} else {
env29892[1] = 0;
env29892[2] = r13.initialSources;
env29892[3] = r13.analyticsSource;
env29892[4] = r13.channelId;
env29892[5] = r13.onClose;
openAs = r13.openAs;
if (openAs !== void 0) {
break L10;
}
}
openAs = "modal";
}
env29892[6] = openAs;
const { originViewOrOriginLayout, initialIndex: _initialIndex, initialSources, analyticsSource, channelId, onClose, openAs: _openAs, ...rest } = r13;
env29892[7] = rest;
env29892[8] = void 0;
env29892[9] = void 0;
env29892[10] = void 0;
env29892[11] = void 0;
env29892[12] = void 0;
await void 0;
const r83 = await Promise.all([import("../useMediaViewerSources"), import("../../MediaViewerAnalyticsManager"), import("../useVideoControls")]);
const r91 = c26108_1;
env29892[8] = r83;
env29892[9] = (0, _slicedToArray)(env29892[8], 3);
env29892[10] = env29892[9][0].setMediaViewerSources;
env29892[11] = env29892[9][1].MediaViewerAnalytics;
env29892[12] = env29892[9][2].initVideoStateStore;
const r106 = env29892[0];
$mk115104(env5151)(r106)($mk115105(r91));
}
@@ -0,0 +1,153 @@
// Metro module 12297 (f12298).
import { useCallback, useEffect, memo, useState } from "react";
import { StyleSheet, View } from "react-native";
import { createStyles } from "../../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../../_bundle/Module712";
import * as _SafeAreaView from "../../../../../components_native/common/SafeAreaView";
import TouchableHitBox from "../../../../../design/void/TouchableHitBox/native/TouchableHitBox";
import { intl, t } from "../../../../../intl/index.native";
import Module12298 from "../../../../../_bundle/Module12298";
import Module10805 from "../../../../../_bundle/Module10805";
import Module12299 from "../../../../../_bundle/Module12299";
import Module12300 from "../../../../../_bundle/Module12300";
import { useOverlayLayoutDriver, useFooterLayoutAnimation } from "../../useOverlayLayoutDriver";
import { useMediaPlayerMutedStore } from "../../MediaPlayerMuteManager";
import { isIOS } from "../../../../../utils/PlatformUtils";
import VisualEffectView from "../../../../visual_effect_view/native/VisualEffectView";
import MediaViewerThumbnails from "../MediaViewerThumbnails";
import { useMediaViewerDimensions } from "../../MediaViewerDimensionsContext";
import { MediaModalOverlayHeader } from "./MediaModalOverlayHeader";
import ReanimatedRexport from "../../../../reanimated/ReanimatedRexport";
import MediaModalOverlayAltText from "./MediaModalOverlayAltText";
import useVideoControls, { setVideoStateControls, toggleMuted } from "../../useVideoControls";
import { MediaModalOverlayFooter } from "./MediaModalOverlayFooter";
import { useMediaItemSpoilerState } from "../../useMediaItemSpoilerState";
import { toggleSpoiler } from "../../useMediaViewerSources";
import { useSelectedMediaSource } from "../../MediaSourceUtil";
import { HermesBuiltin } from "../../../../../_hermes/prelude";
let useStyles, OverlayObscureToggleButton, Component, MediaModalOverlay;
const OverlayMuteButton = function OverlayMuteButton(props) {
const { isMuted, onToggleMute } = props;
const styles = useStyles();
return <_SafeAreaView.SafeAreaPaddingView left right>
<TouchableHitBox accessibilityRole="button" accessibilityLabel={intl.string(t.w4m945)} source={isMuted ? Module12298 : Module10805} color={Module712.unsafe_rawColors.WHITE} onPress={onToggleMute} style={styles.overlayButton} iconStyle={styles.overlayButtonIcon} />
</_SafeAreaView.SafeAreaPaddingView>;
};
OverlayObscureToggleButton = function OverlayObscureToggleButton(props) {
const { spoilerActive, onToggleObscure } = props;
const styles = useStyles();
return <_SafeAreaView.SafeAreaPaddingView left right>
<TouchableHitBox accessibilityRole="button" accessibilityLabel={intl.string(t.UIsxUw)} source={spoilerActive ? Module12299 : Module12300} color={Module712.unsafe_rawColors.WHITE} onPress={onToggleObscure} style={styles.overlayButton} iconStyle={styles.overlayButtonIcon} />
</_SafeAreaView.SafeAreaPaddingView>;
};
MediaModalOverlay = function MediaModalOverlay(props) {
const { getVideoControls, source, index } = props;
const videoControls = getVideoControls(index, source);
const videoControls2 = useVideoControls(index, source, videoControls);
const [spoilerActive] = useMediaItemSpoilerState(index);
const callback = useCallback(() => toggleSpoiler(index), [index]);
useEffect(() => {
setVideoStateControls(videoControls);
}, [videoControls]);
let obscure = source.obscure;
if (obscure == null) {
obscure = false;
}
return <Component {...props} slider={videoControls2} source={source} obscure={obscure} spoilerActive={spoilerActive} toggleObscure={callback} />;
};
useStyles = createStyles({
portraitFooterButtons: {
...StyleSheet.absoluteFillObject,
top: void 0,
backgroundColor: "transparent"
},
invisibleFooter: {
paddingBottom: Module712.space.PX_8
},
overlayIcons: {
position: "absolute",
top: -40,
right: 8,
display: "flex",
flexDirection: "row",
gap: Module712.space.PX_4
},
overlayButtonIcon: {
width: 20,
height: 20
},
overlayButton: {
width: 32,
height: 32,
backgroundColor: "rgba(0, 0, 0, 0.7)",
borderRadius: 16
}
});
Component = memo(function({ slider, onClose, overlayEnabled, syncer, disableDownload, disableMediaOverlayButton, disableMediaOverlayFooter, shareable, contextName, contextIcon, source, obscure, spoilerActive, toggleObscure }) {
let r10, SafeAreaPaddingView;
const styles = useStyles();
const overlayLayoutDriver = useOverlayLayoutDriver();
const footerLayoutAnimation = useFooterLayoutAnimation(overlayLayoutDriver);
const [state, onFullViewToggled] = useState(false);
const mediaPlayerMutedStore = useMediaPlayerMutedStore((a0) => a0.isMuted);
if (slider == null) {
const r53 = syncer.sources.length > 1;
r10 = null;
if (r53) {
SafeAreaPaddingView = _SafeAreaView.SafeAreaPaddingView;
r10 = <SafeAreaPaddingView bottom left right style={{
paddingTop: 8
}}>
{isIOS() && <VisualEffectView blurTheme="dark" style={StyleSheet.absoluteFill} />}
{slider}
{syncer.sources.length > 1 ? <MediaViewerThumbnails syncer={syncer} /> : null}
</SafeAreaPaddingView>;
}
} else {
SafeAreaPaddingView = _SafeAreaView.SafeAreaPaddingView;
r10 = <SafeAreaPaddingView bottom left right style={{
paddingTop: 8
}}>
{isIOS() && <VisualEffectView blurTheme="dark" style={StyleSheet.absoluteFill} />}
{slider}
{syncer.sources.length > 1 ? <MediaViewerThumbnails syncer={syncer} /> : null}
</SafeAreaPaddingView>;
}
const height = useMediaViewerDimensions().height;
const r91 = [<MediaModalOverlayHeader animationDriver={overlayLayoutDriver} disableDownload={disableDownload} disableMediaOverlayButton={disableMediaOverlayButton} source={source} shareable={shareable} contextName={contextName} contextIcon={contextIcon} onClose={onClose} channelId={source.channelId} />, ,];
const r104 = [state ? !state : <MediaModalOverlayAltText description={source.description} />, slider == null ? obscure ? <View style={styles.overlayIcons}>
{slider != null && <OverlayMuteButton isMuted={mediaPlayerMutedStore} onToggleMute={toggleMuted} />}
{obscure ? <OverlayObscureToggleButton spoilerActive={spoilerActive} onToggleObscure={toggleObscure} /> : null}
</View> : null : <View style={styles.overlayIcons}>
{slider != null && <OverlayMuteButton isMuted={mediaPlayerMutedStore} onToggleMute={toggleMuted} />}
{obscure ? <OverlayObscureToggleButton spoilerActive={spoilerActive} onToggleObscure={toggleObscure} /> : null}
</View>, ,];
if (disableMediaOverlayFooter) {
r10 = <_SafeAreaView.SafeAreaPaddingView bottom style={styles.invisibleFooter} />;
} else if (!(height < 600)) {
r10 = <MediaModalOverlayFooter sliderElement={slider} syncer={syncer} guildId={source.guildId} channelId={source.channelId} messageId={source.messageId} onClose={onClose} onFullViewToggled={onFullViewToggled} overlayEnabled={overlayEnabled} />;
}
r104[2] = r10;
r91[1] = <ReanimatedRexport.View style={[styles.portraitFooterButtons, footerLayoutAnimation]}>{r104}</ReanimatedRexport.View>;
return <>{r91}</>;
});
export default function MediaModalOverlayGuard(props) {
const onIndexChange = props.onIndexChange;
const r15 = {};
let r3 = null;
const props2 = HermesBuiltin.copyDataProperties(r15, props, {
__proto__: null,
onIndexChange: 0
});
const [index2, source] = useSelectedMediaSource(props2.syncer);
let c19775_1 = index2;
useEffect(() => {
if (onIndexChange != null) {
onIndexChange(c19775_1);
}
}, [index2, onIndexChange]);
if (source != null) {
r3 = <MediaModalOverlay {...props2} source={source} index={index2} />;
}
return r3;
};
@@ -0,0 +1,49 @@
// Metro module 12309 (f12310).
import { memo } from "react";
import { createStyles } from "../../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../../_bundle/Module712";
import useSafeAreaInsets_native from "../../../../safe_area/useSafeAreaInsets.native";
import { ViewImageDescriptions } from "../../../../user_settings/UserSettings";
import { PressableOpacity } from "../../../../../design/void/Pressables/native/Pressables";
import openMediaModalOverlayAltTextSheet from "./openMediaModalOverlayAltTextSheet";
import { Text } from "../../../../../design/components/Text/native/Text";
import { intl, t } from "../../../../../intl/index.native";
const useStyles = createStyles((a0) => ({
container: {
backgroundColor: Module712.colors.CONTROL_OVERLAY_SECONDARY_BACKGROUND_ACTIVE,
marginVertical: Module712.space.PX_8,
marginHorizontal: Module712.space.PX_8,
marginRight: Module712.space.PX_8 + a0,
paddingHorizontal: Module712.space.PX_8,
paddingVertical: Module712.space.PX_4,
borderRadius: Module712.radii.sm,
alignSelf: "flex-end"
}
}));
const r25 = memo(function MediaModalOverlayAltTextButton(props) {
let description = props.description;
const styles = useStyles(useSafeAreaInsets_native().right);
if (description == null) {
description = "";
}
let c19783_0 = description;
return ViewImageDescriptions.useSetting() ? description.length !== 0 ? <PressableOpacity style={styles.container} onPress={() => {
let description = c19783_0;
if (description == null) {
description = "";
}
openMediaModalOverlayAltTextSheet({
description
});
}} hitSlop={{
top: 6,
bottom: 6,
left: 6,
right: 6
}}>
<Text variant="text-xs/semibold" color="text-overlay-light">
{intl.string(t.Q5VqrN)}
</Text>
</PressableOpacity> : null : null;
});
export default r25;
@@ -0,0 +1,25 @@
// Metro module 10899 (f10900).
import { createStyles } from "../../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../../_bundle/Module712";
import { useMessagePreviewCollapsedheight } from "../../useMessagePreviewHeight";
import { useIsScreenLandscape } from "../../../../screen/useIsScreenLandscape.native";
import { BottomSheet } from "../../../../../design/components/Sheet/native/BottomSheet.native";
import { BottomSheetTitleHeader } from "../../../../../design/components/Sheet/native/BottomSheetTitleHeader.native";
import { intl, t } from "../../../../../intl/index.native";
import { Text } from "../../../../../design/components/Text/native/Text";
const useStyles = createStyles({
container: {
padding: Module712.space.PX_16
}
});
export default function MediaViewerAltTextSheet(props) {
const description = props.description;
const styles = useStyles();
const messagePreviewCollapsedheight = useMessagePreviewCollapsedheight();
const minHeight = useIsScreenLandscape() ? 70 : messagePreviewCollapsedheight + 20 + 50;
return <BottomSheet header={<BottomSheetTitleHeader title={intl.string(t.J3IOO1)} />} contentStyles={[styles.container, {
minHeight
}]}>
<Text accessibilityRole="text" variant="text-md/normal">{description}</Text>
</BottomSheet>;
};
@@ -0,0 +1,468 @@
// Metro module 12310 (f12311).
import { useState, useEffect, useCallback, useRef, useMemo } from "react";
import { View } from "react-native";
import { createStyles } from "../../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../../_bundle/Module712";
import * as _ReanimatedRexport from "../../../../reanimated/ReanimatedRexport";
import { useSharedValue, useAnimatedStyle, useAnimatedReaction } from "../../../../reanimated/ReanimatedRexport";
import { setMesssagePreviewHeight } from "../../useMessagePreviewHeight";
import * as _timing from "../../../../../design/animation/reanimated/timing/timing";
import * as _native from "../../../../../design/void/native";
import useMediaModalFooterBackground_android from "./useMediaModalFooterBackground.android";
import { Gesture, Directions, GestureDetector } from "../../../../../_bundle/Module5273";
import REAWorkaroundView from "../../../../reanimated/native/REAWorkaroundView";
import { SafeAreaPaddingView } from "../../../../../components_native/common/SafeAreaView";
import { ActionSheetHeaderBar } from "../../../../../design/components/Sheet/native/ActionSheetHeaderBar.native";
import MediaMessagePreview from "../message_preview/MediaMessagePreview";
import MediaViewerThumbnails from "../MediaViewerThumbnails";
let clamp, __initData, __initData2, __initData3, __initData4, __initData5, __initData6, __initData7, __initData8, __initData9, __initData10, __initData11, __initData12, __initData13, __initData14, __initData15;
const useStyles = createStyles({
drawerContainer: {
overflow: "hidden",
backgroundColor: void 0
},
drawerHeaderTab: {
width: 40,
backgroundColor: Module712.unsafe_rawColors.PRIMARY_600
},
drawerHeader: {
backgroundColor: void 0
},
messagePreviewContainer: {
marginLeft: 6
},
thumbnailsContainer: {
paddingTop: 8
}
});
const NONE = -1;
const clamp2 = function clamp(a0, a1, a2) {
return Math.max(Math.min(a0, a2), a1);
};
clamp2.__closure = {};
clamp2.__workletHash = 10219548303807;
clamp2.__initData = {
code: "function clamp_MediaModalOverlayFooterTsx1(value,min,max){return Math.max(Math.min(value,max),min);}"
};
clamp = clamp2;
__initData = {
code: "function MediaModalOverlayFooterTsx2(){const{animationState,NONE,isCollapsed}=this.__closure;animationState.set(NONE);isCollapsed.set(false);}"
};
__initData2 = {
code: "function MediaModalOverlayFooterTsx3(){const{animationState,NONE,isCollapsed}=this.__closure;animationState.set(NONE);isCollapsed.set(true);}"
};
__initData3 = {
code: "function MediaModalOverlayFooterTsx4(){const{minFooterHeight,animationState,DRAWER_PANNING,animationDriver,COLLAPSED,interpolate,EXPANDED,EXPANDED_MORE,expandedHeight,MAX_DRAWER_VERTICAL_DRAG}=this.__closure;return{height:minFooterHeight>0&&(animationState.get()===DRAWER_PANNING||animationDriver.get()!==COLLAPSED)?interpolate(animationDriver.get(),[COLLAPSED,EXPANDED,EXPANDED_MORE],[minFooterHeight,Math.max(expandedHeight,minFooterHeight),Math.max(expandedHeight,minFooterHeight)+MAX_DRAWER_VERTICAL_DRAG],'clamp'):undefined,justifyContent:'flex-start'};}"
};
__initData4 = {
code: "function MediaModalOverlayFooterTsx5(){const{interpolate,animationDriver,COLLAPSED,EXPANDED,thumbnailsElementHeight}=this.__closure;return{opacity:interpolate(animationDriver.get(),[COLLAPSED,EXPANDED],[1,0],'clamp'),height:interpolate(animationDriver.get(),[EXPANDED,COLLAPSED],[0,thumbnailsElementHeight],'clamp')};}"
};
__initData5 = {
code: "function MediaModalOverlayFooterTsx6(){const{interpolate,animationDriver,COLLAPSED,EXPANDED}=this.__closure;return{height:interpolate(animationDriver.get(),[COLLAPSED,EXPANDED],[0,24],'clamp')};}"
};
__initData6 = {
code: "function MediaModalOverlayFooterTsx7(){const{r,g,b,interpolate,animationDriver,COLLAPSED,EXPANDED,a,DISMISSED}=this.__closure;return{backgroundColor:\"rgba(\"+r+\", \"+g+\", \"+b+\", \"+interpolate(animationDriver.get(),[COLLAPSED,EXPANDED],[a,1],'clamp')+\")\",paddingVertical:interpolate(animationDriver.get(),[COLLAPSED,EXPANDED],[8,0],'clamp'),transform:[{translateY:interpolate(animationDriver.get(),[DISMISSED,COLLAPSED],[100,0],'clamp')}]};}"
};
__initData7 = {
code: "function MediaModalOverlayFooterTsx8(){const{runOnJS,onFullViewToggled}=this.__closure;runOnJS(onFullViewToggled)();}"
};
__initData8 = {
code: "function MediaModalOverlayFooterTsx9(){const{full,animationDriver,withTiming,DISMISSED,STANDARD_EASING,COLLAPSED,runOnJS,onFullViewToggled}=this.__closure;if(!full){animationDriver.set(withTiming(DISMISSED,{duration:350,easing:STANDARD_EASING},'respect-motion-settings',function(){animationDriver.set(COLLAPSED);}));}else{runOnJS(onFullViewToggled)();}}"
};
__initData9 = {
code: "function MediaModalOverlayFooterTsx10(){const{animationDriver,COLLAPSED}=this.__closure;animationDriver.set(COLLAPSED);}"
};
__initData10 = {
code: "function MediaModalOverlayFooterTsx11(){const{animationDriver,COLLAPSE_DRAWER_ON_RELEASE,runOnJS,setFull,isCollapsed,COLLAPSED,animationState,withDelay,withTiming,NONE,STANDARD_EASING,EXPANDED}=this.__closure;if(animationDriver.get()<COLLAPSE_DRAWER_ON_RELEASE){runOnJS(setFull)(false);isCollapsed.set(true);if(animationDriver.get()===COLLAPSED){animationState.set(withDelay(150,withTiming(NONE,{duration:0})));}else{animationDriver.set(withTiming(COLLAPSED,{duration:150,easing:STANDARD_EASING},'respect-motion-settings',function(){animationState.set(NONE);}));}}else{runOnJS(setFull)(true);animationDriver.set(withTiming(EXPANDED,{duration:150,easing:STANDARD_EASING},'respect-motion-settings',function(){isCollapsed.set(false);animationState.set(NONE);}));}}"
};
__initData11 = {
code: "function MediaModalOverlayFooterTsx12({translationY:translationY}){const{animationState,DRAWER_PANNING,clamp,expandedHeight,thumbnailsElementHeight,collapsedHeight,COLLAPSED,EXPANDED,animationDriver,COLLAPSE_DRAWER_DURING_DRAG,runOnJS,setFull,DRAWER_VERTICAL_DRAG_RESISTANCE,MAX_DRAWER_VERTICAL_DRAG,EXPANDED_MORE}=this.__closure;animationState.set(DRAWER_PANNING);if(translationY>0){const animValue=clamp(1-translationY/Math.abs(expandedHeight-(thumbnailsElementHeight+collapsedHeight)),COLLAPSED,EXPANDED);animationDriver.set(animValue);if(animValue<COLLAPSE_DRAWER_DURING_DRAG){runOnJS(setFull)(false);}}else{const scrollAmount=clamp(-translationY/DRAWER_VERTICAL_DRAG_RESISTANCE,0,MAX_DRAWER_VERTICAL_DRAG);animationDriver.set(EXPANDED+(EXPANDED_MORE-EXPANDED)*scrollAmount/MAX_DRAWER_VERTICAL_DRAG);}}"
};
__initData12 = {
code: "function MediaModalOverlayFooterTsx13(){const{animationState,NONE}=this.__closure;animationState.set(NONE);}"
};
__initData13 = {
code: "function MediaModalOverlayFooterTsx14(){const{isCollapsed,animationState,NONE}=this.__closure;isCollapsed.set(false);animationState.set(NONE);}"
};
__initData14 = {
code: "function MediaModalOverlayFooterTsx15(){const{overlayEnabled,animationDriver}=this.__closure;return[overlayEnabled.get(),animationDriver.get()];}"
};
__initData15 = {
code: "function MediaModalOverlayFooterTsx16([overlayEnabledValue,animationDriverValue]){const{DISMISSED_HIDE_OVERLAY,overlayEnabled}=this.__closure;if(overlayEnabledValue&&animationDriverValue<DISMISSED_HIDE_OVERLAY){overlayEnabled.set(false);}}"
};
export function MediaModalOverlayFooter(props) {
let sharedValue3, callback, callback2, callback3, c19784_18, c19784_19, c19784_20, c19784_21, ref, ref2, memo, memo2, memo3;
const styles = useStyles();
const { sliderElement, onFullViewToggled, overlayEnabled, syncer } = props;
let r20 = syncer.sources.length > 1;
const r0 = r20 ? 60 : 20;
let c19784_2 = r0;
const thumbnailsElementHeight = r20 ? 60 : 0;
const sharedValue = useSharedValue(true);
const sharedValue2 = useSharedValue(NONE);
const [state, setState] = useState(false);
const [state2, setState2] = useState(0);
const [state3, setState3] = useState(0);
const [state4, setState4] = useState(0);
useEffect(() => {
setMesssagePreviewHeight({
collapsedHeight: state4,
expandedHeight: state3
});
}, [state4, state3]);
useEffect(() => {
onFullViewToggled(state);
}, [state, onFullViewToggled]);
sharedValue3 = useSharedValue(0);
callback = useCallback(() => {
sharedValue2.set(1);
setState(true);
const r26 = {
duration: 250,
easing: _native.STANDARD_EASING
};
const r27 = function t() {
sharedValue2.set(NONE);
sharedValue.set(false);
};
r27.__closure = {
animationState: sharedValue2,
NONE,
isCollapsed: sharedValue
};
r27.__workletHash = 8443967716862;
r27.__initData = __initData;
sharedValue3.set(_timing.withTiming(1, r26, "respect-motion-settings", r27));
}, [sharedValue3, sharedValue2, sharedValue]);
callback2 = useCallback(() => {
sharedValue2.set(0);
setState(false);
const r26 = {
duration: 250,
easing: _native.STANDARD_EASING
};
const r27 = function t() {
sharedValue2.set(NONE);
sharedValue.set(true);
};
r27.__closure = {
animationState: sharedValue2,
NONE,
isCollapsed: sharedValue
};
r27.__workletHash = 12593758327764;
r27.__initData = __initData2;
sharedValue3.set(_timing.withTiming(0, r26, "respect-motion-settings", r27));
}, [sharedValue3, sharedValue2, sharedValue]);
callback3 = useCallback(() => {
if (sharedValue2.get() === NONE && !(sharedValue.get() && state3 === state2)) {
if (sharedValue.get()) {
callback();
} else {
callback2();
}
}
}, [sharedValue2, sharedValue, state3, state2, callback, callback2]);
const callback5 = useCallback((a0) => {
setState3(a0 + 17);
}, [setState3]);
const callback4 = useCallback((a0) => {
setState2(a0 + 17);
}, [setState2]);
const ee = function ee() {
let height;
L4: {
const r3 = state4 > 0;
height = void 0;
if (r3) {
if (sharedValue2.get() !== 2) {
const r22 = sharedValue3.get();
height = void 0;
if (r22 === 0) {
break L4;
}
}
height = _ReanimatedRexport.interpolate(sharedValue3.get(), [0, 1, 2], [state4, Math.max(state3, state4), Math.max(state3, state4) + 40], "clamp");
}
}
return {
height,
justifyContent: "flex-start"
};
};
ee.__closure = {
minFooterHeight: state4,
animationState: sharedValue2,
DRAWER_PANNING: 2,
animationDriver: sharedValue3,
COLLAPSED: 0,
interpolate: _ReanimatedRexport.interpolate,
EXPANDED: 1,
EXPANDED_MORE: 2,
expandedHeight: state3,
MAX_DRAWER_VERTICAL_DRAG: 40
};
ee.__workletHash = 10727625692479;
ee.__initData = __initData3;
const animatedStyle3 = useAnimatedStyle(ee);
const te = function te() {
return {
opacity: _ReanimatedRexport.interpolate(sharedValue3.get(), [0, 1], [1, 0], "clamp"),
height: _ReanimatedRexport.interpolate(sharedValue3.get(), [1, 0], [0, thumbnailsElementHeight], "clamp")
};
};
te.__closure = {
interpolate: _ReanimatedRexport.interpolate,
animationDriver: sharedValue3,
COLLAPSED: 0,
EXPANDED: 1,
thumbnailsElementHeight
};
te.__workletHash = 9896169174287;
te.__initData = __initData4;
const animatedStyle = useAnimatedStyle(te);
const callback6 = useCallback((a0) => {
const height = a0.nativeEvent.layout.height;
if (height > c19784_2 && sharedValue.get() && sharedValue2.get() === NONE) {
setState4(height);
}
}, [setState4, r0, sharedValue, sharedValue2]);
const ae = function ae() {
return {
height: _ReanimatedRexport.interpolate(sharedValue3.get(), [0, 1], [0, 24], "clamp")
};
};
ae.__closure = {
interpolate: _ReanimatedRexport.interpolate,
animationDriver: sharedValue3,
COLLAPSED: 0,
EXPANDED: 1
};
ae.__workletHash = 13288648164744;
ae.__initData = __initData5;
const animatedStyle2 = useAnimatedStyle(ae);
const mediaModalFooterBackground_android = useMediaModalFooterBackground_android();
const mediaModalFooterBackgroundColorRgba = mediaModalFooterBackground_android.mediaModalFooterBackgroundColorRgba;
const r31 = mediaModalFooterBackgroundColorRgba.r;
c19784_18 = r31;
const r30 = mediaModalFooterBackgroundColorRgba.g;
c19784_19 = r30;
const r29 = mediaModalFooterBackgroundColorRgba.b;
c19784_20 = r29;
const r25 = mediaModalFooterBackgroundColorRgba.a;
c19784_21 = r25;
const MediaModalFooterUnderlay = mediaModalFooterBackground_android.MediaModalFooterUnderlay;
const ie = function ie() {
return {
backgroundColor: `rgba(${c19784_18}, ${c19784_19}, ${c19784_20}, ${_ReanimatedRexport.interpolate(sharedValue3.get(), [0, 1], [c19784_21, 1], "clamp")})`,
paddingVertical: _ReanimatedRexport.interpolate(sharedValue3.get(), [0, 1], [8, 0], "clamp"),
transform: [{
translateY: _ReanimatedRexport.interpolate(sharedValue3.get(), [-1, 0], [100, 0], "clamp")
}]
};
};
ie.__closure = {
r: r31,
g: r30,
b: r29,
interpolate: _ReanimatedRexport.interpolate,
animationDriver: sharedValue3,
COLLAPSED: 0,
EXPANDED: 1,
a: r25,
DISMISSED: -1
};
ie.__workletHash = 1645059598385;
ie.__initData = __initData6;
const animatedStyle4 = useAnimatedStyle(ie);
ref = useRef(void 0);
ref2 = useRef(void 0);
const [state5, setScrollViewIsAtTop] = useState(true);
memo = useMemo(() => {
const r18 = Gesture.Fling().direction(Directions.UP);
const r20 = function t() {
_ReanimatedRexport.runOnJS(callback3)();
};
r20.__closure = {
runOnJS: _ReanimatedRexport.runOnJS,
onFullViewToggled: callback3
};
r20.__workletHash = 1612404502942;
r20.__initData = __initData7;
return r18.onStart(r20).withRef(ref).enabled(state ? !state : state3 > state2);
}, [state2, state3, state, callback3]);
memo2 = useMemo(() => {
const r18 = Gesture.Fling().direction(Directions.DOWN);
const r20 = function t() {
if (state) {
_ReanimatedRexport.runOnJS(callback3)();
} else {
const r8 = {
duration: 350,
easing: _native.STANDARD_EASING
};
const r23 = function t() {
sharedValue3.set(0);
};
r23.__closure = {
animationDriver: sharedValue3,
COLLAPSED: 0
};
r23.__workletHash = 15839049590506;
r23.__initData = __initData9;
sharedValue3.set(_timing.withTiming(-1, r8, "respect-motion-settings", r23));
}
};
r20.__closure = {
full: state,
animationDriver: sharedValue3,
withTiming: _timing.withTiming,
DISMISSED: -1,
STANDARD_EASING: _native.STANDARD_EASING,
COLLAPSED: 0,
runOnJS: _ReanimatedRexport.runOnJS,
onFullViewToggled: callback3
};
r20.__workletHash = 16686210274151;
r20.__initData = __initData8;
return r18.onStart(r20).withRef(ref2).enabled(state5);
}, [sharedValue3, state, callback3, state5]);
memo3 = useMemo(() => {
const r20 = Gesture.Pan().maxPointers(1).activeOffsetY([-10, 10]);
const r22 = function a({ translationY }) {
sharedValue2.set(2);
if (translationY > 0) {
const r53 = Math.max(Math.min(1 - translationY / Math.abs(state3 - (thumbnailsElementHeight + state2)), 1), 0);
sharedValue3.set(r53);
if (r53 < 0.4) {
_ReanimatedRexport.runOnJS(setState)(false);
}
} else {
sharedValue3.set(1 + 1 * Math.max(Math.min(-translationY / 3, 40), 0) / 40);
}
};
r22.__closure = {
animationState: sharedValue2,
DRAWER_PANNING: 2,
clamp,
expandedHeight: state3,
thumbnailsElementHeight,
collapsedHeight: state2,
COLLAPSED: 0,
EXPANDED: 1,
animationDriver: sharedValue3,
COLLAPSE_DRAWER_DURING_DRAG: 0.4,
runOnJS: _ReanimatedRexport.runOnJS,
setFull: setState,
DRAWER_VERTICAL_DRAG_RESISTANCE: 3,
MAX_DRAWER_VERTICAL_DRAG: 40,
EXPANDED_MORE: 2
};
r22.__workletHash = 7012168718409;
r22.__initData = __initData11;
const r31 = r20.onUpdate(r22);
const r33 = function t() {
if (sharedValue3.get() < 0.75) {
_ReanimatedRexport.runOnJS(setState)(false);
sharedValue.set(true);
if (sharedValue3.get() === 0) {
sharedValue2.set(_ReanimatedRexport.withDelay(150, _timing.withTiming(NONE, {
duration: 0
})));
} else {
const r72 = {
duration: 150,
easing: _native.STANDARD_EASING
};
const r73 = function a() {
sharedValue2.set(NONE);
};
r73.__closure = {
animationState: sharedValue2,
NONE
};
r73.__workletHash = 15486611138793;
r73.__initData = __initData12;
sharedValue3.set(_timing.withTiming(0, r72, "respect-motion-settings", r73));
}
} else {
_ReanimatedRexport.runOnJS(setState)(true);
const r34 = {
duration: 150,
easing: _native.STANDARD_EASING
};
const r35 = function t() {
sharedValue.set(false);
sharedValue2.set(NONE);
};
r35.__closure = {
isCollapsed: sharedValue,
animationState: sharedValue2,
NONE
};
r35.__workletHash = 8502240261161;
r35.__initData = __initData13;
sharedValue3.set(_timing.withTiming(1, r34, "respect-motion-settings", r35));
}
};
r33.__closure = {
animationDriver: sharedValue3,
COLLAPSE_DRAWER_ON_RELEASE: 0.75,
runOnJS: _ReanimatedRexport.runOnJS,
setFull: setState,
isCollapsed: sharedValue,
COLLAPSED: 0,
animationState: sharedValue2,
withDelay: _ReanimatedRexport.withDelay,
withTiming: _timing.withTiming,
NONE,
STANDARD_EASING: _native.STANDARD_EASING,
EXPANDED: 1
};
r33.__workletHash = 16268892990477;
r33.__initData = __initData10;
return r31.onEnd(r33).enabled(state);
}, [sharedValue3, sharedValue2, state2, state3, state, sharedValue, thumbnailsElementHeight]);
const oe = () => [overlayEnabled.get(), sharedValue3.get()];
oe.__closure = {
overlayEnabled,
animationDriver: sharedValue3
};
oe.__workletHash = 12659996728578;
oe.__initData = __initData14;
const ne = function ne(a0) {
let [r23, r24] = a0;
if (r23) {
r23 = r24 < -0.25;
}
if (r23) {
overlayEnabled.set(false);
}
};
ne.__closure = {
DISMISSED_HIDE_OVERLAY: -0.25,
overlayEnabled
};
ne.__workletHash = 11470550406895;
ne.__initData = __initData15;
useAnimatedReaction(oe, ne);
const memo4 = useMemo(() => Gesture.Exclusive(memo, memo3, memo2), [memo3, memo2, memo]);
const r189 = [MediaModalFooterUnderlay, ,];
const r206 = [<REAWorkaroundView style={[animatedStyle2, styles.drawerContainer]}>
<ActionSheetHeaderBar tabStyle={styles.drawerHeaderTab} style={styles.drawerHeader} />
</REAWorkaroundView>, sliderElement, ,];
const r222 = [<View style={styles.messagePreviewContainer}>
<MediaMessagePreview channelId={props.channelId} messageId={props.messageId} onClose={props.onClose} onTapMessage={callback3} onMeasureFullHeight={callback5} onMeasureCollapsedHeight={callback4} full={state} canExpand={state3 > state2} setScrollViewIsAtTop={setScrollViewIsAtTop} flingUpRef={ref} flingDownRef={ref2} animationDriver={sharedValue3} />
</View>, ,];
if (r20) {
r20 = <REAWorkaroundView style={[animatedStyle, styles.thumbnailsContainer]}>
<MediaViewerThumbnails syncer={syncer} />
</REAWorkaroundView>;
}
r222[1] = r20;
r206[2] = <REAWorkaroundView onLayout={callback6} style={animatedStyle3}>{r222}</REAWorkaroundView>;
r189[1] = <SafeAreaPaddingView bottom left right>{r206}</SafeAreaPaddingView>;
return <GestureDetector gesture={memo4}>
<REAWorkaroundView style={animatedStyle4}>{r189}</REAWorkaroundView>
</GestureDetector>;
}
@@ -0,0 +1,101 @@
// Metro module 12304 (f12305).
import { StyleSheet, View } from "react-native";
import { createStyles } from "../../../../../design/components/Styles/native/createStyles";
import { NAV_BAR_HEIGHT } from "../../../../../design/components/Navigator/native/NavigatorConstants.native";
import { useHeaderLayoutAnimation } from "../../useOverlayLayoutDriver";
import { useMediaShareActions } from "../MediaShareActions";
import useShouldHideMediaOptions from "../../../../media_channel/useShouldHideMediaOptions";
import ReanimatedRexport from "../../../../reanimated/ReanimatedRexport";
import { SafeAreaPaddingView } from "../../../../../components_native/common/SafeAreaView";
import MediaViewerOverlayButton from "./MediaViewerOverlayButton";
import { intl, t } from "../../../../../intl/index.native";
import { XSmallIcon } from "../../../../../design/components/Icon/native/redesign/generated/XSmallIcon";
import { Icon } from "../../../../../design/void/native";
import Module712 from "../../../../../_bundle/Module712";
import { Text } from "../../../../../design/components/Text/native/Text";
import MediaViewerOverlayButtonFavoriteGIF from "./MediaViewerOverlayButtonFavoriteGIF";
import { ContextMenu } from "../../../../../design/components/ContextMenu/native/ContextMenu.native";
import { isAndroid } from "../../../../../utils/PlatformUtils";
import { MoreVerticalIcon } from "../../../../../design/components/Icon/native/redesign/generated/MoreVerticalIcon";
import { MoreHorizontalIcon } from "../../../../../design/components/Icon/native/redesign/generated/MoreHorizontalIcon";
const useStyles = createStyles({
navbarInner: {
flex: 1,
alignItems: "center",
flexDirection: "row",
height: NAV_BAR_HEIGHT,
paddingHorizontal: 6,
justifyContent: "space-between"
},
navbarLeft: {
flexShrink: 1,
flexDirection: "row",
marginRight: 8
},
navbarRight: {
flexShrink: 0,
justifyContent: "flex-end",
flexDirection: "row",
gap: 8
},
navbarName: {
flexShrink: 1,
alignItems: "center",
height: 40,
marginLeft: 8
},
navbarNameInner: {
borderRadius: 20,
justifyContent: "center",
alignItems: "center",
backgroundColor: "rgba(0, 0, 0, 0.7)",
flex: 1,
flexDirection: "row",
paddingHorizontal: 18
},
navbarNameShrinkWrapper: {
flexShrink: 1
},
contextIcon: {
width: 18,
height: 18,
marginRight: 6
}
});
export function MediaModalOverlayHeader(props) {
const { onClose, source, disableDownload, disableMediaOverlayButton, shareable, contextName, contextIcon, animationDriver, channelId } = props;
const styles = useStyles();
const headerLayoutAnimation = useHeaderLayoutAnimation(animationDriver);
const mediaShareActions = useMediaShareActions({
source,
disableDownload,
shareable
});
const shouldHideMediaOptions = useShouldHideMediaOptions(channelId);
return <ReanimatedRexport.View style={[{
...StyleSheet.absoluteFillObject,
bottom: void 0
}, headerLayoutAnimation]}>
<SafeAreaPaddingView top left right pointerEvents="box-none">
<View style={styles.navbarInner} pointerEvents="box-none">
<View style={styles.navbarLeft}>
<MediaViewerOverlayButton accessibilityLabel={intl.string(t.cpT0Cq)} icon={<XSmallIcon size="md" color="interactive-text-active" />} onPress={onClose} />
{contextName != null && <View style={styles.navbarName}>
<View style={styles.navbarNameInner}>
{contextIcon != null && <Icon source={contextIcon} color={Module712.unsafe_rawColors.PRIMARY_345} size={Icon.Sizes.CUSTOM} style={styles.contextIcon} />}
<View style={styles.navbarNameShrinkWrapper}>
<Text accessibilityRole="header" variant="heading-md/medium" lineClamp={1} ellipsizeMode="tail" color="text-overlay-light">{contextName}</Text>
</View>
</View>
</View>}
</View>
{shouldHideMediaOptions ? !shouldHideMediaOptions : <View style={styles.navbarRight}>
<MediaViewerOverlayButtonFavoriteGIF source={source} />
{disableMediaOverlayButton ? null : <ContextMenu items={mediaShareActions}>
{({ ref, ...props }) => <MediaViewerOverlayButton accessibilityLabel={intl.string(t.PdRCRg)} icon={isAndroid() ? <MoreVerticalIcon size="md" color="interactive-text-active" /> : <MoreHorizontalIcon size="md" color="interactive-text-active" />} ref={ref} {...props} />}
</ContextMenu>}
</View>}
</View>
</SafeAreaPaddingView>
</ReanimatedRexport.View>;
}
@@ -0,0 +1,7 @@
// Metro module 12305 (f12306).
import { forwardRef } from "react";
import { IconButton } from "../../../../../design/components/Button/native/IconButton.native";
const r19 = forwardRef(function(a0, a1) {
return <IconButton ref={a1} size="md" variant="secondary-overlay" {...a0} />;
});
export default r19;
@@ -0,0 +1,66 @@
// Metro module 12306 (f12307).
import { memo, useCallback } from "react";
import { useIsFavoriteGIF } from "../../../../gif_picker/FavoriteGIFHooks";
import { gifUrlKey, removeFavoriteGIF, addFavoriteGIF } from "../../../../../actions/GIFPickerActionCreators";
import ToastActionCreators from "../../../../toast/native/ToastActionCreators";
import { intl, t } from "../../../../../intl/index.native";
import { GifIcon } from "../../../../../design/components/Icon/native/redesign/generated/GifIcon";
import { getGIFThumbnailForFavorite } from "../../../../../utils/GIFPickerUtils";
import { GIFType } from "../../../../../_bundle/Module1341";
import { isAnimatedImageSource } from "../../MediaSourceUtil";
import MediaViewerOverlayButton from "./MediaViewerOverlayButton";
import { StarIcon } from "../../../../../design/components/Icon/native/redesign/generated/StarIcon";
import Module712 from "../../../../../_bundle/Module712";
import { StarOutlineIcon } from "../../../../../design/components/Icon/native/redesign/generated/StarOutlineIcon";
const r20 = memo(function GIFFavButton(props) {
let r34;
let uri, isFavoriteGIF;
const source = props.source;
uri = void 0;
isFavoriteGIF = void 0;
let r11 = source.isGIFV ? source.embedURI : source.sourceURI;
if (r11 == null) {
r11 = source.uri;
}
L14: {
uri = r11;
isFavoriteGIF = useIsFavoriteGIF(gifUrlKey(uri));
const callback = useCallback(() => {
if (isFavoriteGIF) {
removeFavoriteGIF(uri);
ToastActionCreators.open({
key: "REMOVED_FROM_FAVORITES",
content: intl.string(t.in1rga),
IconComponent: GifIcon
});
} else {
addFavoriteGIF({
url: uri,
src: source.uri,
gifSrc: getGIFThumbnailForFavorite({
providerName: source.embedProviderName,
thumbnail: source.thumbnail
}),
width: source.width,
height: source.height,
format: source.isGIFV ? GIFType.VIDEO : GIFType.IMAGE
});
ToastActionCreators.open({
key: "ADDED_TO_FAVORITES",
content: intl.string(t.okQonm),
IconComponent: GifIcon
});
}
}, [isFavoriteGIF, source.embedProviderName, source.height, source.isGIFV, source.thumbnail, source.uri, source.width, uri]);
if (!isAnimatedImageSource(source)) {
const isGIFV = source.isGIFV;
r34 = null;
if (!isGIFV) {
break L14;
}
}
r34 = <MediaViewerOverlayButton accessibilityLabel={isFavoriteGIF ? intl.string(t["5/NS74"]) : intl.string(t.nIH0v8)} onPress={callback} icon={isFavoriteGIF ? <StarIcon color={Module712.unsafe_rawColors.YELLOW_300} size="md" /> : <StarOutlineIcon color="interactive-text-default" size="md" />} />;
}
return r34;
});
export default r20;
@@ -0,0 +1,7 @@
// Metro module 10898 (f10899).
import ActionSheetActionCreators from "../../../../action_sheet/native/ActionSheetActionCreators";
export default function openMediaModalOverlayAltTextSheet({ description }) {
ActionSheetActionCreators.openLazy(import("./MediaModalOverlayAltTextSheet"), "MediaModalOverlayAltTextSheet", {
description
});
};
@@ -0,0 +1,17 @@
// Metro module 12311 (f12312).
import _slicedToArray from "../../../../../_bundle/_slicedToArray";
import Module689 from "../../../../../_bundle/Module689";
import { useToken } from "../../../../../design/tokens/native/useToken";
import Module712 from "../../../../../_bundle/Module712";
export default function useMediaModalFooterBackground() {
const r20 = _slicedToArray(Module689(useToken(Module712.colors.THEME_LOCKED_BLUR_FALLBACK)).rgba(), 4);
return {
mediaModalFooterBackgroundColorRgba: {
r: r20[0],
g: r20[1],
b: r20[2],
a: r20[3]
},
MediaModalFooterUnderlay: void 0
};
};