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

543 lines
22 KiB
TypeScript

// Metro module 11415 (f11416).
import _slicedToArray from "../../../../_bundle/_slicedToArray";
import { memo, useRef, useCallback, useEffect, useMemo } from "react";
import { View, AppState } from "react-native";
import ActionSheetStore from "../../../action_sheet/native/ActionSheetStore";
import PendingReplyStore from "../../../replies/PendingReplyStore";
import ChannelStore from "../../../../stores/ChannelStore";
import * as _VoiceMessagesUIStore from "../VoiceMessagesUIStore";
import { useVoiceMessagesUIStore, showVoiceMessagesTooltip, setIsVoiceMessageButtonMounted, setVoiceMessageAnimationState, hideVoiceMessagesTooltip, setShowRecordingOverlay } from "../VoiceMessagesUIStore";
import * as _VoiceMessageConstants from "../../VoiceMessageConstants";
import { VOICE_RECORDING_MIN_DURATION_MILLIS } from "../../VoiceMessageConstants";
import { MessageFlags, ComponentActionsKeyed, ComponentActions } from "../../../../Constants";
import { MessageSendLocation } from "../../../messages/MessageConstants";
import { NativePermissionTypes } from "../../../native_permissions/NativePermissionConstants";
import { jsx } from "react/jsx-runtime";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { XSmallBoldIcon } from "../../../../design/components/Icon/native/redesign/generated/XSmallBoldIcon";
import * as _NavigationRouteUtils_native from "../../../main_tabs_v2/helpers/NavigationRouteUtils.native";
import { useIsModalOpen, getOpenModalKey } from "../../../main_tabs_v2/helpers/NavigationRouteUtils.native";
import { isVoiceChannelModalKey } from "../../../../utils/native/PrivateChannelCallUtils";
import { triggerHaptic, endAudioRecording, emitVoiceMessageRecorded, startAudioRecording } from "../VoiceMessageUtils";
import * as _ReanimatedRexport from "../../../reanimated/ReanimatedRexport";
import { useSharedValue } from "../../../reanimated/ReanimatedRexport";
import { useMobileVisualRefreshConfig } from "../../../themes/experiments/MobileVisualRefreshExperiment";
import { useClientThemesOverride } from "../../../client_themes/native/ClientThemesOverrides";
import useChatWidth from "../../../chat/native/useChatWidth";
import useWindowDimensions_native from "../../../screen/useWindowDimensions.native";
import { VoiceMessageRecordingResult } from "../../VoiceMessageAnalytics";
import { CloudUpload } from "../../../../lib/uploader/CloudUpload";
import { UploadPlatform } from "../../../../lib/uploader/Upload";
import MessageActionCreators from "../../../../actions/MessageActionCreators";
import { handleUploadMessageAttachmentsErrors } from "../../../media_uploads/handleUploadAttachmentErrors.native";
import { deletePendingReply } from "../../../replies/PendingReplyActionCreators";
import { ComponentDispatch } from "../../../../utils/ComponentDispatchUtils";
import ToastActionCreators from "../../../toast/native/ToastActionCreators";
import * as _index_native from "../../../../intl/index.native";
import { intl } from "../../../../intl/index.native";
import { getFocusedChannelId } from "../../../panels/isChannelFocused.native";
import { getRootNavigationRef } from "../../../main_tabs_v2/RootNavigationRef.native";
import NativePermissionUtils from "../../../native_permissions/NativePermissionUtils";
import { showVoiceRecordingFailed } from "../../../toast/native/ToastUtils";
import useAccessibilityPress from "../../../a11y/native/useAccessibilityPress";
import { GestureDetector, Gesture } from "../../../../_bundle/Module5273";
import useVoiceMessageTooltip from "../useVoiceMessageTooltip";
import ChatInputActionButton from "../../../chat_input/native/action_buttons/ChatInputActionButton";
import { MicrophoneIcon } from "../../../../design/components/Icon/native/redesign/generated/MicrophoneIcon";
function $mk118322($env) {
return (a0, a1, a2) => {
handleUploadMessageAttachmentsErrors({
file: a0,
guildId: $env[5].getGuildId(),
analyticsLocations: [],
code: a1,
reason: a2
});
};
}
let triggerHapticGuarded, useStyles, useStyles2, c7764_30, c7764_31, c7764_32, c7764_33;
let env7764 = {};
const VoiceMessageRecordingCancelledToastIcon = function VoiceMessageRecordingCancelledToastIcon() {
return <View style={useStyles().icon} aria-hidden>
<XSmallBoldIcon color={Module712.colors.WHITE} size="xs" />
</View>;
};
triggerHapticGuarded = function triggerHapticGuarded() {
if (useVoiceMessagesUIStore.getState().showRecordingOverlay) {
triggerHaptic();
}
};
useStyles = createStyles({
icon: {
backgroundColor: Module712.colors.BACKGROUND_FEEDBACK_CRITICAL,
borderRadius: Module712.radii.round,
padding: Module712.space.PX_4,
marginLeft: Module712.space.PX_4
}
});
useStyles2 = createStyles({
themedChatInput: {
backgroundColor: Module712.colors.CARD_SECONDARY_BG
}
});
c7764_30 = {
code: "function VoiceMessageButtonTsx1(newValue){const{voiceMessageAnimationState,runOnJS,triggerHapticGuarded}=this.__closure;if(voiceMessageAnimationState.get()[1]===newValue)return;const prevValue=voiceMessageAnimationState.get()[1];voiceMessageAnimationState.set([prevValue,newValue]);runOnJS(triggerHapticGuarded)();}"
};
c7764_31 = {
code: "function VoiceMessageButtonTsx2(){const{runOnJS,handleFinalize}=this.__closure;runOnJS(handleFinalize)();}"
};
c7764_32 = {
code: "function VoiceMessageButtonTsx3(e){const{isGestureActiveValue,LOCK_THRESHOLD,cancelThresholdX,handleUpdateValue,VoiceMessageAnimationState}=this.__closure;if(!isGestureActiveValue.get())return;if(e.translationY<=-LOCK_THRESHOLD&&e.absoluteX>=cancelThresholdX){handleUpdateValue(VoiceMessageAnimationState.LOCKING);}else if(e.absoluteX<cancelThresholdX){handleUpdateValue(VoiceMessageAnimationState.CANCELLING);}else if(e.absoluteX>=cancelThresholdX){handleUpdateValue(VoiceMessageAnimationState.SENDING);}}"
};
c7764_33 = {
code: "function VoiceMessageButtonTsx4(e){const{isGestureActiveValue,runOnJS,setIsUsingHoldGesture,voiceMessageAnimationState,VoiceMessageAnimationState,startRecording}=this.__closure;if(e.numberOfTouches>1)return;if(isGestureActiveValue.get())return;runOnJS(setIsUsingHoldGesture)(true);voiceMessageAnimationState.set([VoiceMessageAnimationState.SENDING,VoiceMessageAnimationState.SENDING]);runOnJS(startRecording)();}"
};
const r96 = memo(function(a0) {
let ref, sharedValue;
let c18818_0;
let env18816 = {
$parent: env7764
};
const disabled = a0.disabled;
env18816[0] = disabled;
const channelId = a0.channelId;
env18816[1] = channelId;
env18816[2] = void 0;
env18816[3] = void 0;
env18816[4] = void 0;
env18816[5] = void 0;
env18816[6] = void 0;
env18816[7] = void 0;
env18816[8] = void 0;
env18816[9] = void 0;
env18816[10] = void 0;
env18816[11] = void 0;
env18816[12] = void 0;
env18816[13] = void 0;
env18816[14] = void 0;
const styles2 = useStyles2();
const chatInputFloating = useMobileVisualRefreshConfig({
location: "VoiceMessageButton"
}).chatInputFloating;
const clientThemesOverride = useClientThemesOverride(styles2.themedChatInput);
const voiceMessageAnimationState = (0, useVoiceMessagesUIStore)((a0) => a0.voiceMessageAnimationState);
env18816[2] = voiceMessageAnimationState;
const sharedValue2 = useSharedValue(0);
env18816[3] = sharedValue2;
ref = void 0;
sharedValue = void 0;
ref = useRef(false);
sharedValue = useSharedValue(false);
const r52 = _slicedToArray([ref, sharedValue, useCallback((a0) => {
ref.current = a0;
sharedValue.set(a0);
}, [ref, sharedValue])], 3);
const r23 = r52[0];
env18816[4] = r23;
const r20 = r52[1];
env18816[5] = r20;
const r53 = r52[2];
env18816[6] = r53;
env18816[7] = useRef(true);
env18816[8] = useRef(AppState.currentState);
env18816[9] = useRef(null);
const chatWidth = useChatWidth();
const width = useWindowDimensions_native().width;
c18818_0 = void 0;
c18818_0 = async (c30400_0) => {
let c30400_1, c30400_2;
L21: {
L20: {
let env31624;
c30400_2 = void 0;
const r9 = env31624 = {
$parent: env7764
};
c30400_1 = r9;
env31624[0] = void 0;
env31624[1] = void 0;
env31624[0] = c30400_0.isCancelling;
let cancelReason = c30400_0.cancelReason;
if (cancelReason === void 0) {
cancelReason = VoiceMessageRecordingResult.CANCELLED_USER_REQUESTED;
}
env31624[1] = cancelReason;
env31624[2] = void 0;
env31624[3] = void 0;
env31624[4] = void 0;
env31624[5] = void 0;
env31624[6] = void 0;
env31624[7] = void 0;
env31624[8] = void 0;
await void 0;
const r70 = await endAudioRecording();
const r79 = c30400_2;
env31624[2] = r70;
env31624[3] = env31624[2].data;
env31624[4] = env31624[2].startTimeMillis;
(0, r79.$parent[6])(false);
const r89 = env31624[0];
const r91 = c30400_2;
if (r89) {
r91.$parent[9].current = env31624[1];
emitVoiceMessageRecorded(env31624[1], env31624[3].durationSecs, env31624[4]);
break L21;
}
if (env31624[3].durationSecs < VOICE_RECORDING_MIN_DURATION_MILLIS / 1000) {
emitVoiceMessageRecorded(VoiceMessageRecordingResult.CANCELLED_DURATION, env31624[3].durationSecs, env31624[4]);
(0, showVoiceMessagesTooltip)();
break L20;
}
const r131 = c30400_2;
emitVoiceMessageRecorded(VoiceMessageRecordingResult.SENT, env31624[3].durationSecs, env31624[4]);
env31624[5] = ChannelStore.getChannel(r131.$parent[1]);
if (env31624[5] != null) {
const r154 = c30400_1;
const r155 = c30400_2;
env31624[6] = [new CloudUpload({
uri: env31624[3].filename,
originalUri: env31624[3].filename,
mimeType: "audio/ogg",
filename: "voice-message.ogg",
platform: UploadPlatform.REACT_NATIVE,
durationSecs: env31624[3].durationSecs,
waveform: env31624[3].waveform
}, env31624[5].id)];
const r184 = r155.$parent;
env31624[7] = PendingReplyStore.getPendingReply(r184[1]);
env31624[8] = MessageActionCreators.getSendMessageOptionsForReply(env31624[7]);
MessageActionCreators.sendMessage(env31624[5].id, {
content: "",
tts: false,
invalidEmojis: [],
validNonShortcutEmojis: []
}, void 0, {
flags: MessageFlags.IS_VOICE_MESSAGE,
location: MessageSendLocation.VOICE_MESSAGE,
attachmentsToUpload: env31624[6],
onAttachmentUploadError: $mk118322(r154),
...env31624[8]
});
deletePendingReply(r184[1]);
}
return void 0;
}
return void 0;
}
};
const callback = useCallback(function() {
return c18818_0.apply(this, arguments);
}, [channelId, r53]);
env18816[10] = callback;
useEffect(() => {
ComponentDispatch.subscribeKeyed(ComponentActionsKeyed.VOICE_MESSAGE_SEND, env18816[1], env18816[10]);
return () => {
ComponentDispatch.unsubscribeKeyed(ComponentActionsKeyed.VOICE_MESSAGE_SEND, env18816[1], env18816[10]);
};
}, [channelId, callback]);
useEffect(() => {
(0, setIsVoiceMessageButtonMounted)(true);
return () => {
(0, setIsVoiceMessageButtonMounted)(false);
};
}, []);
useEffect(() => {
let c27055_0 = AppState.addEventListener("change", function(a0) {
const r4 = env18816[8];
const current3 = r4.current;
const r15 = env18816[9];
const current2 = r15.current;
const CANCELLED_ON_BACKGROUND = VoiceMessageRecordingResult.CANCELLED_ON_BACKGROUND;
if (!(a0 !== "active" || current3 !== "inactive" && current3 !== "background" || !(current2 === CANCELLED_ON_BACKGROUND))) {
ToastActionCreators.open({
key: "VOICE_MESSAGE_CANCELLED_ON_BACKGROUND",
content: intl.string(_index_native.t.JM7Y2D),
icon: () => (0, jsx)(VoiceMessageRecordingCancelledToastIcon, {}),
position: "bottom"
});
r15.current = null;
}
r4.current = a0;
});
return () => {
c27055_0.remove();
};
}, []);
useEffect(() => {
env18816[7].current = true;
const current = env18816[4].current;
return () => {
env18816[7].current = false;
const state = useVoiceMessagesUIStore.getState();
if (state.showRecordingOverlay || state.recordingStatus != null || current) {
(0, env18816[6])(false);
endAudioRecording();
}
};
}, [r23, r53]);
const isModalOpen = useIsModalOpen();
useEffect(() => {
let _cancel2, handleActionSheetChange2, handleNavigationChange2;
const cancel2 = function cancel() {
return _cancel2.apply(this, arguments);
};
_cancel2 = function _cancel() {
const r9 = async () => {
let c31625_1;
let c32028_0;
L15: {
L11: {
c31625_1 = void 0;
c32028_0 = void 0;
const state = useVoiceMessagesUIStore.getState();
if (!state.showRecordingOverlay && state.recordingStatus == null && !env18816[4].current) {
break L11;
}
(0, env18816[6])(false);
c32028_0 = await endAudioRecording();
emitVoiceMessageRecorded(VoiceMessageRecordingResult.CANCELLED_GESTURE_CONFLICT, c32028_0.data.durationSecs, c32028_0.startTimeMillis);
break L15;
}
return void 0;
}
};
_cancel2 = r9;
return r9.apply(this, arguments);
};
handleActionSheetChange2 = function handleActionSheetChange() {
if (ActionSheetStore.isOpen()) {
cancel2();
}
};
handleNavigationChange2 = function handleNavigationChange() {
const focusedChannelId = getFocusedChannelId();
if (focusedChannelId != null) {
if (focusedChannelId !== env18816[1]) {
cancel2();
}
} else {
cancel2();
}
};
cancel2();
ActionSheetStore.addReactChangeListener(handleActionSheetChange2);
const rootNavigationRef = getRootNavigationRef();
if (rootNavigationRef != null) {
rootNavigationRef.addListener("state", handleNavigationChange2);
}
return () => {
ActionSheetStore.removeReactChangeListener(handleActionSheetChange2);
const rootNavigationRef = getRootNavigationRef();
if (rootNavigationRef != null) {
rootNavigationRef.removeListener("state", handleNavigationChange2);
}
};
}, [r23, r53, channelId]);
useEffect(() => {
(0, setVoiceMessageAnimationState)({
currWaveHeight: env18816[3]
});
}, [sharedValue2, isModalOpen]);
const callback2 = useCallback(async () => {
let c27058_0, c27058_1, c27058_2;
let c27058_3 = 0;
const r12 = env18816;
const r11 = env7764;
L26: {
L25: {
try {
let env30401;
c27058_1 = r12;
const r31 = env30401 = {
$parent: r11
};
c27058_0 = r31;
env30401[0] = void 0;
env30401[1] = void 0;
if ((function isNormalModalOpen() {
if (_NavigationRouteUtils_native.isModalOpen()) {
const openModalKey = getOpenModalKey();
return openModalKey == null || !isVoiceChannelModalKey(openModalKey);
}
return false;
})()) {
break L26;
}
if (!env18816[7].current) {
break L26;
}
if (ActionSheetStore.isOpen()) {
break L26;
}
if (ChannelStore.getChannel(env18816[1]) == null) {
break L26;
}
(0, env18816[6])(true);
ComponentDispatch.dispatch(ComponentActions.VOICE_MESSAGE_BUTTON_PRESSED);
if (!await NativePermissionUtils.requestPermission(NativePermissionTypes.AUDIO)) {
break L25;
}
if (!env18816[4].current) {
break L25;
}
(0, hideVoiceMessagesTooltip)();
env30401[0] = performance.now();
(0, setShowRecordingOverlay)(true);
c27058_3 = 1;
await startAudioRecording(env30401[0]);
c27058_3 = 0;
env30401[1] = useVoiceMessagesUIStore.getState();
if (env30401[1].recordingId !== env30401[0]) {
break L25;
}
const voiceMessageAnimationState = env30401[1].voiceMessageAnimationState;
if ((voiceMessageAnimationState == null ? void 0 : voiceMessageAnimationState.get()[1]) !== _VoiceMessageConstants.VoiceMessageAnimationState.LOCKED && !env18816[4].current) {
endAudioRecording();
break L25;
}
triggerHaptic();
} catch ($e) {
const r29 = $e;
let r7 = r29;
c27058_2 = r29;
if (c27058_3 !== 0) {
while (true) {
try {
c27058_3 = 0;
(0, env18816[6])(false);
showVoiceRecordingFailed();
} catch (r166) {
r7 = r166;
c27058_2 = r166;
if (c27058_3 === 0) {
break;
}
continue;
}
return void 0;
}
}
throw r7;
}
}
return void 0;
}
}, [r23, r53, channelId]);
env18816[11] = callback2;
const Z = function Z(a0) {
const r3 = env18816[2];
if (r3.get()[1] !== a0) {
r3.set([r3.get()[1], a0]);
_ReanimatedRexport.runOnJS(triggerHapticGuarded)();
}
};
Z.__closure = {
voiceMessageAnimationState,
runOnJS: _ReanimatedRexport.runOnJS,
triggerHapticGuarded
};
Z.__workletHash = 9127775028714;
Z.__initData = c7764_30;
const callback3 = useCallback(Z, [voiceMessageAnimationState]);
env18816[12] = callback3;
const callback4 = useCallback(() => {
if (env18816[4].current) {
(0, env18816[6])(false);
const r6 = env18816[2];
const r5 = r6.get()[1];
if (_VoiceMessageConstants.VoiceMessageAnimationState.SENDING === r5) {
(0, env18816[10])({
isCancelling: false
});
} else if (_VoiceMessageConstants.VoiceMessageAnimationState.CANCELLING === r5) {
(0, env18816[10])({
isCancelling: true
});
} else {
if (_VoiceMessageConstants.VoiceMessageAnimationState.LOCKING === r5) {
(0, _VoiceMessagesUIStore.setIsUsingHoldGesture)(false);
r6.set([_VoiceMessageConstants.VoiceMessageAnimationState.LOCKING, _VoiceMessageConstants.VoiceMessageAnimationState.LOCKED]);
_ReanimatedRexport.runOnJS(triggerHapticGuarded)();
return void 0;
}
endAudioRecording();
}
} else {
endAudioRecording();
}
}, [voiceMessageAnimationState, r23, callback, r53]);
env18816[13] = callback4;
const accessibilityPress = useAccessibilityPress(async () => {
let c27059_0 = env18816;
await (0, env18816[11])();
(0, _VoiceMessagesUIStore.setIsUsingHoldGesture)(false);
env18816[2].set([_VoiceMessageConstants.VoiceMessageAnimationState.LOCKED, _VoiceMessageConstants.VoiceMessageAnimationState.LOCKED]);
}, intl.string(_index_native.t.lwy6aX));
const { accessibilityActions, onAccessibilityAction } = accessibilityPress;
const r142 = 0.5 * chatWidth + (width - chatWidth);
env18816[14] = r142;
return <GestureDetector gesture={useMemo(() => {
const r20 = Gesture.Pan().enabled(!env18816[0]).minDistance(0);
const n = function n(a0) {
if (!(a0.numberOfTouches > 1 || env18816[5].get())) {
_ReanimatedRexport.runOnJS(_VoiceMessagesUIStore.setIsUsingHoldGesture)(true);
env18816[2].set([_VoiceMessageConstants.VoiceMessageAnimationState.SENDING, _VoiceMessageConstants.VoiceMessageAnimationState.SENDING]);
_ReanimatedRexport.runOnJS(env18816[11])();
}
};
const isGestureActiveValue = env18816[5];
n.__closure = {
isGestureActiveValue,
runOnJS: _ReanimatedRexport.runOnJS,
setIsUsingHoldGesture: _VoiceMessagesUIStore.setIsUsingHoldGesture,
voiceMessageAnimationState: env18816[2],
VoiceMessageAnimationState: _VoiceMessageConstants.VoiceMessageAnimationState,
startRecording: env18816[11]
};
n.__workletHash = 15771181123252;
n.__initData = c7764_33;
const r30 = r20.onTouchesDown(n);
const t = function t(a0) {
L8: {
if (env18816[5].get()) {
if (a0.translationY <= -40 && a0.absoluteX >= env18816[14]) {
(0, env18816[12])(_VoiceMessageConstants.VoiceMessageAnimationState.LOCKING);
break L8;
}
const absoluteX = a0.absoluteX;
const r10 = env18816[14];
if (absoluteX < r10) {
(0, env18816[12])(_VoiceMessageConstants.VoiceMessageAnimationState.CANCELLING);
} else if (a0.absoluteX >= r10) {
(0, env18816[12])(_VoiceMessageConstants.VoiceMessageAnimationState.SENDING);
}
}
}
};
t.__closure = {
isGestureActiveValue,
LOCK_THRESHOLD: 40,
cancelThresholdX: env18816[14],
handleUpdateValue: env18816[12],
VoiceMessageAnimationState: _VoiceMessageConstants.VoiceMessageAnimationState
};
t.__workletHash = 9262214665783;
t.__initData = c7764_32;
const r38 = r30.onUpdate(t);
const e = function e() {
_ReanimatedRexport.runOnJS(env18816[13])();
};
e.__closure = {
runOnJS: _ReanimatedRexport.runOnJS,
handleFinalize: env18816[13]
};
e.__workletHash = 2411654680943;
e.__initData = c7764_31;
return r38.onFinalize(e);
}, [disabled, r20, voiceMessageAnimationState, callback2, r142, callback3, callback4])}>
<ChatInputActionButton ref={useVoiceMessageTooltip().tooltipTargetRef} IconComponent={MicrophoneIcon} active={false} accessibilityLabel={intl.string(_index_native.t.lwy6aX)} accessibilityActions={accessibilityActions} onAccessibilityAction={onAccessibilityAction} disabled={disabled} style={chatInputFloating ? void 0 : clientThemesOverride} />
</GestureDetector>;
});
export default r96;