Files
discord-decomp/modules/voice_panel/native/card/VoicePanelCardView.tsx
T
2026-11-01 12:12:55 +02:00

236 lines
12 KiB
TypeScript

// Metro module 15957 (f15958).
import { useRef, useState, useEffect, useContext, useMemo, memo, useCallback } from "react";
import { StyleSheet, View } from "react-native";
import ChannelRTCStore from "../../../calls/ChannelRTCStore";
import * as _VoicePanelConstants from "../../VoicePanelConstants";
import { LAYOUT_PHYSICS, VoicePanelModes } from "../../VoicePanelConstants";
import { VoicePanelControlsModes } from "../controls/VoicePanelControlsConstants";
import { VoicePanelPIPModes } from "../pip/VoicePanelPIPConstants";
import { EDGE_GUTTER } from "./VoicePanelCardConstants";
import { isUserParticipant } from "../../../calls/CallConstants";
import VoicePanelCard from "./VoicePanelCard";
import * as _ReanimatedRexport from "../../../reanimated/ReanimatedRexport";
import { useAnimatedStyle, useAnimatedReaction } from "../../../reanimated/ReanimatedRexport";
import * as _cheapWorkletShallowEqual from "../../../reanimated/native/cheapWorkletShallowEqual";
import MobileVisualRefreshExperiment from "../../../themes/experiments/MobileVisualRefreshExperiment";
import VoicePanelStateContext from "../VoicePanelStateContext";
import { useToken } from "../../../../design/tokens/native/useToken";
import Module712 from "../../../../_bundle/Module712";
import calculateVoicePanelHeaderSpecs from "../header/calculateVoicePanelHeaderSpecs";
import roundToNearestPixel from "../utils/roundToNearestPixel";
import * as _spring from "../../../../design/animation/reanimated/spring/spring";
import { usePIPState } from "../pip/VoicePanelPIPStateContext";
import useRefValue from "../../../../hooks/useRefValue";
import ReanimatedNativeView from "../../../core/native/ReanimatedNativeView";
import { Freeze } from "../../../../_bundle/Suspender";
import { useChunkedParticipants } from "../hooks/useVoicePanelParticipants";
import { useStateFromStoresArray } from "../../../../_bundle/Module589";
import Module12 from "../../../../_bundle/Module12";
import { AccessibilityAnnouncer } from "../../../../_bundle/Module3902";
import { intl, t } from "../../../../intl/index.native";
import { TransitionGroup } from "../../../../design/components/TransitionGroup/TransitionGroup";
let SCALE_PHYSICS, renderCard, c11433_18, __initData, __initData2, __initData3, CardContentFreezer;
const getCardKey = function getCardKey(a0) {
return `${a0.type}-${a0.id}`;
};
renderCard = function renderCard(a0, a1, a2, a3) {
return <VoicePanelCard key={a0} item={a1} transitionState={a2} cleanUp={a3} />;
};
CardContentFreezer = function CardContentFreezer({ children }) {
let freeze, animatedStyle;
freeze = void 0;
animatedStyle = void 0;
const mode = usePIPState().mode;
const ref = useRef(mode === VoicePanelPIPModes.IN_APP);
const [, setState] = useState({});
useEffect(() => {
if (mode === VoicePanelPIPModes.IN_APP) {
let c30937_0 = setTimeout(() => {
if (!ref.current) {
ref.current = true;
setState({});
}
}, 700);
return () => {
clearTimeout(c30937_0);
};
}
ref.current = false;
}, [mode]);
const refValue = useRefValue(ref);
freeze = mode === VoicePanelPIPModes.IN_APP && refValue;
let c22643_0 = freeze;
const isRefreshEnabled = MobileVisualRefreshExperiment("VoicePanelCardView");
let c22643_1 = isRefreshEnabled;
const context = useContext(VoicePanelStateContext);
const { connected, controlsSpecs, safeArea, contentDimensions, windowDimensions, mode: mode2, focused, wrapperOffset } = context;
const token = useToken(Module712.modules.mobile.VOICE_PANEL_GUTTER);
const r65 = function() {
let r95;
const mode3 = controlsSpecs.get().mode;
const HIDDEN = VoicePanelControlsModes.HIDDEN;
const r20 = Math.max(safeArea.get().bottom, EDGE_GUTTER);
const r38 = calculateVoicePanelHeaderSpecs(safeArea.get(), token);
const { height, paddingTop } = r38;
const r41 = connected.get();
let opacity = 1;
let r1 = 0;
let r42 = 1;
let r43 = 0;
if (r41) {
let r48 = 0 + paddingTop + contentDimensions.get().height + r20;
if (r48 - windowDimensions.get().height < 8) {
r48 = windowDimensions.get().height;
}
const r55 = mode2.get();
const PIP = VoicePanelModes.PIP;
r1 = 0;
r42 = 1;
r43 = r48;
if (r55 !== PIP) {
r1 = 0;
r42 = 1;
r43 = r48;
if (mode3 !== HIDDEN) {
const r61 = focused.get() == null;
r1 = 0;
r42 = 1;
r43 = r48;
if (r61) {
const r68 = r48 - height - EDGE_GUTTER - controlsSpecs.get().height - r20;
const r73 = windowDimensions.get().height - paddingTop - r20;
const r82 = windowDimensions.get().height - height - controlsSpecs.get().height - r20;
if (contentDimensions.get().height > r68) {
r95 = r68 / contentDimensions.get().height;
} else {
const width = windowDimensions.get().width;
r95 = c22643_1 ? width / windowDimensions.get().width : (width - 48) / windowDimensions.get().width;
}
const r109 = contentDimensions.get().height < r73 && contentDimensions.get().height > r82 ? height - ((r73 - contentDimensions.get().height) / 2 - (r82 - contentDimensions.get().height * r95) / 2) * r95 : height;
r1 = (contentDimensions.get().height > r68 ? r109 + (r48 * r95 - r48) / 2 : r109 + (r68 - (windowDimensions.get().height - paddingTop - r20)) / 2) - paddingTop * r95;
r42 = r95;
r43 = r48;
}
}
}
}
const r145 = {
position: "relative",
width: windowDimensions.get().width,
height: roundToNearestPixel(r43),
transform: [{
translateY: _spring.withSpring(r1 + wrapperOffset.get().y, !wrapperOffset.get().gestureActive && mode2.get() !== VoicePanelModes.PIP ? SCALE_PHYSICS : LAYOUT_PHYSICS)
}, {
scale: _spring.withSpring(r42, SCALE_PHYSICS)
}],
opacity: null
};
if (c22643_0) {
opacity = 0;
}
r145.opacity = opacity;
return r145;
};
r65.__closure = {
controlsSpecs,
VoicePanelControlsModes,
safeArea,
EDGE_GUTTER,
calculateVoicePanelHeaderSpecs,
edgeGutter: token,
connected,
contentDimensions,
windowDimensions,
mode: mode2,
VoicePanelModes,
focused,
isRefreshEnabled,
roundToNearestPixel,
withSpring: _spring.withSpring,
wrapperOffset,
LAYOUT_PHYSICS,
SCALE_PHYSICS,
freeze
};
r65.__workletHash = 495797244676;
r65.__initData = __initData3;
animatedStyle = useAnimatedStyle(r65);
return useMemo(() => <ReanimatedNativeView style={animatedStyle}>
<Freeze freeze={freeze}>
<View collapsable={false} style={StyleSheet.absoluteFill}>{children}</View>
</Freeze>
</ReanimatedNativeView>, [animatedStyle, freeze, children]);
};
const { UI_SHOW_HIDE_PHYSICS, VOICE_PANEL_CHUNK_DIVISOR } = _VoicePanelConstants;
SCALE_PHYSICS = {
...UI_SHOW_HIDE_PHYSICS,
mass: 1,
restSpeedThreshold: 0.00001
};
c11433_18 = {
start: 0,
end: VOICE_PANEL_CHUNK_DIVISOR
};
__initData = {
code: "function VoicePanelCardViewTsx1(){const{viewableChunks}=this.__closure;return viewableChunks.get();}"
};
__initData2 = {
code: "function VoicePanelCardViewTsx2(newChunks,previous){const{cheapWorkletShallowEqual,runOnJS,updateValueIfChange}=this.__closure;if(cheapWorkletShallowEqual(newChunks,previous!==null&&previous!==void 0?previous:undefined))return;runOnJS(updateValueIfChange)(newChunks);}"
};
__initData3 = {
code: "function VoicePanelCardViewTsx3(){const{controlsSpecs,VoicePanelControlsModes,safeArea,EDGE_GUTTER,calculateVoicePanelHeaderSpecs,edgeGutter,connected,contentDimensions,windowDimensions,mode,VoicePanelModes,focused,isRefreshEnabled,roundToNearestPixel,withSpring,wrapperOffset,LAYOUT_PHYSICS,SCALE_PHYSICS,freeze}=this.__closure;const hidden=controlsSpecs.get().mode===VoicePanelControlsModes.HIDDEN;let height=0;let scale=1;let top=0;const safeAreaBottom=Math.max(safeArea.get().bottom,EDGE_GUTTER);const{height:headerBarHeight,paddingTop:safeAreaTop}=calculateVoicePanelHeaderSpecs(safeArea.get(),edgeGutter);if(connected.get()){height+=safeAreaTop;height+=contentDimensions.get().height;height+=safeAreaBottom;if(height-windowDimensions.get().height<8){height=windowDimensions.get().height;}if(mode.get()!==VoicePanelModes.PIP&&!hidden&&focused.get()==null){const targetHeight=height-headerBarHeight-EDGE_GUTTER-controlsSpecs.get().height-safeAreaBottom;const fullView=windowDimensions.get().height-safeAreaTop-safeAreaBottom;const controlsView=windowDimensions.get().height-headerBarHeight-controlsSpecs.get().height-safeAreaBottom;top=headerBarHeight;scale=function(){if(contentDimensions.get().height>targetHeight){return targetHeight/contentDimensions.get().height;}return isRefreshEnabled?windowDimensions.get().width/windowDimensions.get().width:(windowDimensions.get().width-48)/windowDimensions.get().width;}();if(contentDimensions.get().height<fullView&&contentDimensions.get().height>controlsView){const offsetOriginal=(fullView-contentDimensions.get().height)/2;const scaledContent=contentDimensions.get().height*scale;const scaledOffset=(controlsView-scaledContent)/2;top-=(offsetOriginal-scaledOffset)*scale;}if(contentDimensions.get().height>targetHeight){top+=(height*scale-height)/2;}else{top+=(targetHeight-(windowDimensions.get().height-safeAreaTop-safeAreaBottom))/2;}top-=safeAreaTop*scale;}}return{position:'relative',width:windowDimensions.get().width,height:roundToNearestPixel(height),transform:[{translateY:withSpring(top+wrapperOffset.get().y,wrapperOffset.get().gestureActive||mode.get()===VoicePanelModes.PIP?LAYOUT_PHYSICS:SCALE_PHYSICS)},{scale:withSpring(scale,SCALE_PHYSICS)}],opacity:freeze?0:1};}"
};
const r59 = memo(function VoicePanelCardView({ viewableChunks: viewableChunks2 }) {
let chunkedParticipants, stateFromStoresArray, ref2;
chunkedParticipants = void 0;
stateFromStoresArray = void 0;
ref2 = void 0;
const channelId = useContext(VoicePanelStateContext).channelId;
const viewableChunks = viewableChunks2;
const [state, setState2] = useState(c11433_18);
const callback = useCallback((c30938_0) => {
setState2((prevState2) => {
const start = prevState2.start;
return start === c30938_0.start ? prevState2.end === c30938_0.end ? prevState2 : c30938_0 : c30938_0;
});
}, []);
const h = () => viewableChunks.get();
h.__closure = {
viewableChunks
};
h.__workletHash = 1074173860641;
h.__initData = __initData;
const r34 = function(a0, a1) {
if (!_cheapWorkletShallowEqual.cheapWorkletShallowEqual(a0, a1 == null ? void 0 : a1)) {
_ReanimatedRexport.runOnJS(callback)(a0);
}
};
r34.__closure = {
cheapWorkletShallowEqual: _cheapWorkletShallowEqual.cheapWorkletShallowEqual,
runOnJS: _ReanimatedRexport.runOnJS,
updateValueIfChange: callback
};
r34.__workletHash = 13543715159803;
r34.__initData = __initData2;
useAnimatedReaction(h, r34);
chunkedParticipants = useChunkedParticipants(channelId, state);
stateFromStoresArray = useStateFromStoresArray([ChannelRTCStore], () => ChannelRTCStore.getParticipants(channelId).filter((item) => isUserParticipant(item)), [channelId]);
ref2 = useRef(stateFromStoresArray);
useEffect(() => {
if (!Module12.isEqual(ref2.current, stateFromStoresArray)) {
const r21 = Module12.differenceWith(ref2.current, stateFromStoresArray, (a0, a1) => a0.id === a1.id);
const r12 = r21.length > 0 ? r21[0].user : null;
if (r12 != null) {
AccessibilityAnnouncer.announce(intl.formatToPlainString(t["9NqwWZ"], {
username: r12.username
}));
}
}
ref2.current = stateFromStoresArray;
}, [stateFromStoresArray, channelId]);
return useMemo(() => <CardContentFreezer>
<TransitionGroup items={chunkedParticipants} renderItem={renderCard} getItemKey={getCardKey} lazyCleanUpDelay={1000} />
</CardContentFreezer>, [chunkedParticipants]);
});
export default r59;