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

334 lines
15 KiB
TypeScript

// Metro module 10517 (f10518).
import { useContext, useEffect, useState, useRef, useMemo } from "react";
import { StyleSheet, View } from "react-native";
import EmbeddedActivitiesStore from "../../../activities/EmbeddedActivitiesStore";
import ChannelRTCStore from "../../../calls/ChannelRTCStore";
import { useBestActiveChatInputContainerHeight } from "../../../chat_input/native/useChatBottomManagerUIStore";
import ApplicationStreamingStore from "../../../../stores/ApplicationStreamingStore";
import AuthenticationStore from "../../../../stores/AuthenticationStore";
import ChannelCallLifecycleStore from "../ChannelCallLifecycleStore";
import { useChannelCallStore } from "../ChannelCallStore";
import { VOICE_CALL_OVERLAY_HORIZONTAL_MARGIN, VOICE_CALL_OVERLAY_VERTICAL_MARGIN, VoiceCallOverlayType, VoiceChatDrawerState } from "../ChannelCallConstants";
import { ApplicationStreamStates } from "../../../../Constants";
import { ParticipantTypes, isStreamParticipant } from "../../../calls/CallConstants";
import { Gesture, GestureDetector } from "../../../../_bundle/Module5273";
import * as _ReanimatedRexport from "../../../reanimated/ReanimatedRexport";
import ReanimatedRexport, { useAnimatedStyle } from "../../../reanimated/ReanimatedRexport";
import { STANDARD_EASING } from "../../../../design/void/native";
import { useStateFromStores } from "../../../../_bundle/Module589";
import usePipPosition from "./usePipPosition";
import { RevealContext } from "./RevealProvider";
import useActionBarHeight from "../useActionBarHeight";
import useIsActivityFocused from "../../../activities/useIsActivityFocused";
import { useIsScreenLandscape } from "../../../screen/useIsScreenLandscape.native";
import useSafeAreaInsets_native from "../../../safe_area/useSafeAreaInsets.native";
import { useIsViewingActivity } from "../../../activities/native/useIsViewingActivity";
import { OrientationType } from "../../../device/native/DeviceOrientation";
import usePrevious from "../../../../hooks/usePrevious";
import PictureInPicture, { DEFAULT_PIP_POSITION } from "./PictureInPicture";
import { NAV_BAR_HEIGHT } from "../../../../design/components/Navigator/native/NavigatorConstants.native";
import * as _timing from "../../../../design/animation/reanimated/timing/timing";
import { setPipEnabledWhileFocusedOnActivityOrStream } from "../VoiceCallOverlayUtils";
import { intl, t } from "../../../../intl/index.native";
import { openIgnoreThermalStateAlert } from "../../../activities/native/openIgnoreThermalStateAlert";
import PopoutMenu from "./PopoutMenu";
import PictureInPictureVideo from "./PictureInPictureVideo";
import usePipVideoOrStream from "../usePipVideoOrStream";
import useSelectedParticipant from "../../useSelectedParticipant";
import { getEmbeddedActivityParticipantId } from "../../../calls/ChannelRTCParticipants";
import { useIsStreamFocused } from "../../useIsStreamFocused";
import useTrackActivityVideoPip from "../useTrackActivityVideoPip";
let __initData, TIMING_CONFIG, c7059_26, __initData2;
const CameraPreview = function CameraPreview(props) {
let c18098_2, reveal, c18098_4, bestActiveChatInputContainerHeight, c18098_6, bottom, top, LANDSCAPE, screenOrientation, state, setState, state2, setState2, setState3;
const { channel: channel3, nonSelfPipParticipant, selfParticipant, participantScreenIsFocused } = props;
c18098_2 = void 0;
reveal = void 0;
c18098_4 = void 0;
bestActiveChatInputContainerHeight = void 0;
c18098_6 = void 0;
bottom = void 0;
top = void 0;
LANDSCAPE = void 0;
screenOrientation = void 0;
state = void 0;
setState = void 0;
state2 = void 0;
setState2 = void 0;
setState3 = void 0;
const stateFromStores = useStateFromStores([ChannelCallLifecycleStore], () => ChannelCallLifecycleStore.isReactingToThermalState());
const [preferredPosition, onMove] = usePipPosition();
c18098_2 = onMove;
reveal = useContext(RevealContext).reveal;
const actionBarHeight = useActionBarHeight();
c18098_4 = actionBarHeight;
bestActiveChatInputContainerHeight = useBestActiveChatInputContainerHeight();
const isActivityFocused = useIsActivityFocused(channel3.id);
c18098_6 = isActivityFocused;
const isScreenLandscape = useIsScreenLandscape();
const safeAreaInsets_native = useSafeAreaInsets_native();
bottom = safeAreaInsets_native.bottom;
top = safeAreaInsets_native.top;
const { left, right } = safeAreaInsets_native;
let r61 = useIsViewingActivity({
channelId: channel3.id
});
const r70 = useStateFromStores([ChannelCallLifecycleStore], () => ChannelCallLifecycleStore.getVoiceCallOverlayLayoutStates())[VoiceCallOverlayType.CAMERA_PREVIEW_PICTURE_IN_PICTURE];
LANDSCAPE = isScreenLandscape ? OrientationType.LANDSCAPE : OrientationType.PORTRAIT;
let r79 = usePrevious(LANDSCAPE);
if (r79 == null) {
r79 = r70?.screenOrientation;
}
screenOrientation = r79;
useEffect(() => {
if (screenOrientation != null && screenOrientation !== LANDSCAPE && c18098_6) {
c18098_2(DEFAULT_PIP_POSITION);
}
}, [LANDSCAPE, screenOrientation, isActivityFocused, onMove]);
[state, setState] = useState(top + VOICE_CALL_OVERLAY_VERTICAL_MARGIN);
[state2, setState2] = useState(bottom + VOICE_CALL_OVERLAY_VERTICAL_MARGIN);
useEffect(() => {
let r4, r14;
let r3 = top + VOICE_CALL_OVERLAY_VERTICAL_MARGIN;
let r5 = bottom + VOICE_CALL_OVERLAY_VERTICAL_MARGIN;
if (participantScreenIsFocused) {
if (reveal) {
r3 = NAV_BAR_HEIGHT + top + VOICE_CALL_OVERLAY_VERTICAL_MARGIN;
}
if (reveal) {
r5 = c18098_4 + bottom + VOICE_CALL_OVERLAY_VERTICAL_MARGIN;
}
r14 = r5;
r4 = r3;
} else {
r14 = bestActiveChatInputContainerHeight + bottom + VOICE_CALL_OVERLAY_VERTICAL_MARGIN;
r4 = r3;
}
setState(r4);
setState2(r14);
}, [reveal, bestActiveChatInputContainerHeight, participantScreenIsFocused, actionBarHeight, top, bottom]);
const ee = function ee() {
return {
marginTop: _timing.withTiming(state, TIMING_CONFIG),
marginBottom: _timing.withTiming(state2, TIMING_CONFIG)
};
};
ee.__closure = {
withTiming: _timing.withTiming,
marginTopState: state,
TIMING_CONFIG,
marginBottomState: state2
};
ee.__workletHash = 17411027531876;
ee.__initData = __initData2;
const animatedStyle = useAnimatedStyle(ee);
const ref2 = useRef(null);
let state3;
[state3, setState3] = useState(null);
const rows = c7059_26.HIDE_PIP === state3 ? [{
text: intl.string(t.L3I0Jr),
onClick: function handleHidePip() {
setPipEnabledWhileFocusedOnActivityOrStream(false);
}
}] : c7059_26.HANDLE_THERMAL_EVENT === state3 ? [{
text: intl.string(t["1fRDnT"]),
onClick: openIgnoreThermalStateAlert
}] : [];
const ref = ref2;
const memo = useMemo(() => {
const close2 = ref.current?.close;
const close = close2;
const r17 = Gesture.Tap();
const n = function n() {
if (close != null) {
_ReanimatedRexport.runOnJS(close)();
}
};
n.__closure = {
closeFunc: close,
runOnJS: _ReanimatedRexport.runOnJS
};
n.__workletHash = 9707001557651;
n.__initData = __initData;
return r17.onTouchesUp(n);
}, [ref]);
const r169 = [state3 == null ? null : <GestureDetector gesture={memo}>
<View style={StyleSheet.absoluteFill} />
</GestureDetector>, ,];
if (r61) {
r61 = stateFromStores;
}
r169[1] = <View style={StyleSheet.absoluteFill} pointerEvents="box-none">
<ReanimatedRexport.View key={isScreenLandscape ? "landscape" : "portrait"} style={[{
flex: 1,
marginLeft: left + VOICE_CALL_OVERLAY_HORIZONTAL_MARGIN,
marginRight: right + VOICE_CALL_OVERLAY_HORIZONTAL_MARGIN
}, animatedStyle]} pointerEvents="box-none">
<PictureInPicture channel={channel3} preferredPosition={preferredPosition} onMove={onMove} isInCallScreen marginTop={state} marginBottom={state2}>
<PopoutMenu ref={ref} disabled={!r61} trigger={<PictureInPictureVideo channel={channel3} selfParticipant={selfParticipant} pipParticipant={nonSelfPipParticipant} />} rows={rows} onOpen={() => {
setState3(stateFromStores ? c7059_26.HANDLE_THERMAL_EVENT : c7059_26.HIDE_PIP);
}} onClose={() => {
setState3(null);
}} />
</PictureInPicture>
</ReanimatedRexport.View>
</View>;
return <>{r169}</>;
};
__initData = {
code: "function CameraPreviewTsx1(){const{closeFunc,runOnJS}=this.__closure;if(closeFunc!=null){runOnJS(closeFunc)();}}"
};
TIMING_CONFIG = {
duration: 250,
easing: STANDARD_EASING
};
c7059_26 = {
HIDE_PIP: "HIDE_PIP",
HANDLE_THERMAL_EVENT: "HANDLE_THERMAL_EVENT"
};
__initData2 = {
code: "function CameraPreviewTsx2(){const{withTiming,marginTopState,TIMING_CONFIG,marginBottomState}=this.__closure;return{marginTop:withTiming(marginTopState,TIMING_CONFIG),marginBottom:withTiming(marginBottomState,TIMING_CONFIG)};}"
};
export default function CameraPreviewContainer(props) {
let r81, r101, isStreamFocused, isViewingActivity, stateFromStores4, stateFromStores5;
let c18100_3, id;
const { channel, participantScreenIsFocused: participantScreenIsFocused2 = true } = props;
let c18100_1 = participantScreenIsFocused2;
let isChannelCallModalOpen = props.isChannelCallModalOpen;
if (isChannelCallModalOpen === void 0) {
isChannelCallModalOpen = false;
}
c18100_3 = void 0;
id = void 0;
const selectedParticipant = useSelectedParticipant(channel);
let c18100_2 = selectedParticipant;
const stateFromStores2 = useStateFromStores([ChannelRTCStore, AuthenticationStore, ApplicationStreamingStore], () => {
const id2 = AuthenticationStore.getId();
const currentUserActiveStream = ApplicationStreamingStore.getCurrentUserActiveStream();
let c26703_1 = currentUserActiveStream != null && currentUserActiveStream.state === ApplicationStreamStates.ACTIVE;
const r22 = ChannelRTCStore.getStreamParticipants(channel.id).find((item) => item.user.id === id2 && c26703_1);
return c18100_2 != null && r22 != null && c18100_2.id === r22.id ? c18100_1 ? null : r22 : r22;
});
const channelCallStore = useChannelCallStore(({ voiceChatDrawerState }) => voiceChatDrawerState === VoiceChatDrawerState.OPEN || voiceChatDrawerState === VoiceChatDrawerState.OPENING);
const stateFromStores3 = useStateFromStores([ChannelRTCStore, EmbeddedActivitiesStore], () => {
const currentEmbeddedActivity = EmbeddedActivitiesStore.getCurrentEmbeddedActivity();
return currentEmbeddedActivity != null ? ChannelRTCStore.getParticipants(channel.id).find((item) => item.id === getEmbeddedActivityParticipantId({
applicationId: currentEmbeddedActivity.applicationId,
instanceId: currentEmbeddedActivity.compositeInstanceId
})) : null;
});
const r1 = stateFromStores3 != null && selectedParticipant?.id === stateFromStores3?.id && !channelCallStore;
c18100_3 = r1;
let nonSelfPipParticipant = r1 ? null : stateFromStores3;
let channel2;
L22: {
isStreamFocused = useIsStreamFocused(channel.id);
isViewingActivity = useIsViewingActivity({
channelId: channel.id
});
stateFromStores4 = useStateFromStores([ChannelRTCStore, AuthenticationStore], () => {
let r36;
const id4 = AuthenticationStore.getId();
const participant = ChannelRTCStore.getParticipant(channel.id, id4);
if (participant?.streamId == null && !c18100_3) {
return null;
}
if (c18100_1) {
const r20 = c18100_2 != null && c18100_2?.id !== id4;
L20: {
L19: {
if (c18100_2 == null && !channel.isGuildStageVoice()) {
const id5 = channel.id;
const id3 = id4;
const participants = ChannelRTCStore.getParticipants(id5);
const r28 = participants.length <= 4 ? participants.filter((participant) => !(isStreamParticipant(participant) && participant.user.id === id3)) : participants;
if (r28.length > 1 && r28.length <= 3) {
break L19;
}
}
r36 = null;
if (!r20) {
break L20;
}
}
r36 = participant;
}
return r36;
}
return participant;
});
stateFromStores5 = useStateFromStores([AuthenticationStore, ChannelRTCStore], () => {
let r16;
const isStreamParticipant2 = isStreamParticipant(c18100_2);
const type = c18100_2?.type;
L18: {
const r13 = type === ParticipantTypes.USER;
if (!(!isStreamParticipant2 && !r13) && c18100_2?.streamId != null) {
r16 = c18100_2;
if (!c18100_1) {
break L18;
}
}
if (isStreamParticipant2 && (c18100_2 == null ? void 0 : c18100_2.user.id) !== AuthenticationStore.getId()) {
const participant = ChannelRTCStore.getParticipant(channel.id, c18100_2.user.id);
const localVideoDisabled = participant?.localVideoDisabled;
r16 = participant;
if (!localVideoDisabled) {
break L18;
}
r16 = null;
} else {
r16 = r13 ? ChannelRTCStore.getStreamParticipants(channel.id).find((item) => item.user.id === c18100_2.user.id) : void 0;
}
}
return r16?.streamId != null ? r16 : null;
});
id = channel.id;
const stateFromStores6 = useStateFromStores([ChannelRTCStore], () => id != null && ChannelRTCStore.getSelectedParticipant(id) != null);
channel2 = channel;
const stateFromStores7 = useStateFromStores([ChannelRTCStore], () => ChannelRTCStore.getSelectedParticipant(channel2.id));
const pipVideoOrStream = usePipVideoOrStream(channel.id);
const r80 = pipVideoOrStream == null;
r81 = null;
if (!r80) {
const id4 = pipVideoOrStream.user.id;
const id5 = AuthenticationStore.getId();
r81 = null;
if (id4 !== id5) {
if (participantScreenIsFocused2) {
r81 = null;
if (!stateFromStores6) {
break L22;
}
}
r81 = pipVideoOrStream.id !== stateFromStores7?.id ? pipVideoOrStream : null;
}
}
}
if (nonSelfPipParticipant == null) {
nonSelfPipParticipant = stateFromStores2;
}
if (nonSelfPipParticipant == null) {
nonSelfPipParticipant = stateFromStores5;
}
if (nonSelfPipParticipant == null) {
nonSelfPipParticipant = r81;
}
const selfParticipant = stateFromStores4 !== nonSelfPipParticipant ? stateFromStores4 : null;
const stateFromStores8 = useStateFromStores([ChannelCallLifecycleStore], () => ChannelCallLifecycleStore.isPipEnabledWhileFocusedOnActivityOrStream());
if (isChannelCallModalOpen) {
isChannelCallModalOpen = channel.isGuildStageVoice();
}
L40: {
useTrackActivityVideoPip(channel);
if (!(!r1 && !isStreamFocused) && !stateFromStores8) {
r101 = null;
if (!isViewingActivity) {
break L40;
}
}
r101 = selfParticipant == null ? nonSelfPipParticipant == null ? null : isChannelCallModalOpen ? null : <CameraPreview channel={channel} participantScreenIsFocused={participantScreenIsFocused2} nonSelfPipParticipant={nonSelfPipParticipant} selfParticipant={selfParticipant} /> : isChannelCallModalOpen ? null : <CameraPreview channel={channel} participantScreenIsFocused={participantScreenIsFocused2} nonSelfPipParticipant={nonSelfPipParticipant} selfParticipant={selfParticipant} />;
}
return r101;
};