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,8 @@
// Metro module 10340 (f10341).
const r8 = {
REPLY_TOGGLE: "REPLY_TOGGLE",
SEND_MESSAGE_BUTTON: "SEND_MESSAGE_BUTTON",
REACTION_BUTTON: "REACTION_BUTTON",
REACTION_PICKER_BUTTON: "REACTION_PICKER_BUTTON"
};
export { r8 as InAppNotificationAccessoryTypes };
@@ -0,0 +1,60 @@
// Metro module 10360 (f10361).
import { useMemo, useCallback } from "react";
import { View } from "react-native";
import GuildIcon, { ImageSizes, GuildIconSizes } from "../../guild/native/GuildIcon";
import ClipView, { CutoutShape } from "../../../design/components/Icon/native/ClipView";
import Module712 from "../../../_bundle/Module712";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { useGuildIncidentsState } from "../../guild_antiraid/GuildAntiRaidHooks";
import { intl, t } from "../../../intl/index.native";
import { transitionToChannel } from "../../routing/transitionToChannel";
import { NotificationPressable } from "./Notification";
import { WarningIcon } from "../../../design/components/Icon/native/redesign/generated/WarningIcon";
import { SystemMessageText } from "./MessagePreviewText";
let c6933_8 = {
shape: CutoutShape.RoundedRect,
x: ImageSizes[GuildIconSizes.NORMAL] - -6 - 24,
y: -6,
width: 24,
height: 24,
cornerRadius: Module712.radii.sm
};
const useStyles = createStyles({
warningBadge: {
position: "absolute",
top: -6,
right: -6,
width: 24,
height: 24,
alignItems: "center",
justifyContent: "center"
},
warningIcon: {
width: 16,
height: 16
}
});
export default function AlertNotification(props) {
const notification = props.notification;
const { key, channel, guild } = notification;
const styles = useStyles();
const text = useGuildIncidentsState(key).incidentData?.raidDetectedAt != null ? intl.string(t.Mn3elp) : intl.string(t.evRhwg);
return <NotificationPressable icon={<>
<ClipView cutouts={[c6933_8]}>
<GuildIcon guild={guild} selected={false} />
</ClipView>
<View style={styles.warningBadge}>
<WarningIcon style={styles.warningIcon} color={Module712.colors.ICON_FEEDBACK_WARNING} />
</View>
</>} header={useMemo(() => ({
type: "simple",
text: intl.string(t["2IY4YN"]),
secondaryText: guild?.name
}), [guild])} onPress={useCallback(() => {
transitionToChannel(channel.id, {
navigationReplace: true
});
}, [channel.id])} notification={notification}>
<SystemMessageText text={text} />
</NotificationPressable>;
};
@@ -0,0 +1,89 @@
// Metro module 10387 (f10388).
import { View } from "react-native";
import { PAN_INPUT_RANGE, extrapolateConfig } from "./InAppNotificationConstants";
import { EMOJI_URL_BASE_SIZE } from "../../emojis/EmojiConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useInAppNotificationContext } from "./InAppNotificationContext";
import * as _ReanimatedRexport from "../../reanimated/ReanimatedRexport";
import ReanimatedRexport, { useSharedValue, useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
import useMountEffect from "../../../_bundle/useMountEffect";
import { withTiming } from "../../../design/animation/reanimated/timing/timing";
import Emoji from "../../emojis/native/Emoji";
import AvatarUtils from "../../../utils/AvatarUtils";
import { CircleCheckIcon } from "../../../design/components/Icon/native/redesign/generated/CircleCheckIcon";
import { Text } from "../../../design/components/Text/native/Text";
const useStyles = createStyles({
container: {
alignItems: "center",
justifyContent: "center",
marginTop: Module712.space.PX_12
},
notificationRow: {
...Module712.shadows.SHADOW_HIGH,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: Module712.space.PX_8,
backgroundColor: Module712.colors.MOBILE_ALERT_BACKGROUND_DEFAULT,
paddingStart: Module712.space.PX_8,
paddingEnd: Module712.space.PX_12,
paddingVertical: Module712.space.PX_8,
borderRadius: Module712.radii.round,
overflow: "hidden"
},
textEmoji: {
fontSize: 20
},
imageEmoji: {
width: 20,
height: 20
}
});
const __initData = {
code: "function ConfirmationToastTsx1(){const{animatedValue,interpolate,notificationGestureY,PAN_INPUT_RANGE,extrapolateConfig}=this.__closure;const value=animatedValue.get();const scale=interpolate(value,[0,1],[0.8,1]);const enterTranslateY=interpolate(value,[0,1],[-20,0]);const gestureY=notificationGestureY.get();const dismissOpacity=interpolate(gestureY,PAN_INPUT_RANGE,[0,1,0],extrapolateConfig);return{transform:[{translateY:enterTranslateY+gestureY},{scale:scale}],opacity:value*dismissOpacity};}"
};
export function ConfirmationToast(props) {
const { message, reaction } = props;
const styles = useStyles();
const notificationGestureY = useInAppNotificationContext().notificationGestureY;
const sharedValue = useSharedValue(0);
useMountEffect(() => {
sharedValue.set(withTiming(1, {
duration: 200
}));
});
const A = function A() {
const r16 = sharedValue.get();
const scale = _ReanimatedRexport.interpolate(r16, [0, 1], [0.8, 1]);
const r24 = _ReanimatedRexport.interpolate(r16, [0, 1], [-20, 0]);
const r27 = notificationGestureY.get();
return {
transform: [{
translateY: r24 + r27
}, {
scale
}],
opacity: r16 * _ReanimatedRexport.interpolate(r27, PAN_INPUT_RANGE, [0, 1, 0], extrapolateConfig)
};
};
A.__closure = {
animatedValue: sharedValue,
interpolate: _ReanimatedRexport.interpolate,
notificationGestureY,
PAN_INPUT_RANGE,
extrapolateConfig
};
A.__workletHash = 4654280152495;
A.__initData = __initData;
return <ReanimatedRexport.View style={[styles.container, useAnimatedStyle(A)]}>
<View style={styles.notificationRow}>
{reaction != null ? <Emoji textEmojiStyle={styles.textEmoji} fastImageStyle={styles.imageEmoji} name={reaction.id == null ? reaction.surrogates : ""} src={reaction.id != null ? AvatarUtils.getEmojiURL({
id: reaction.id,
animated: reaction.animated,
size: EMOJI_URL_BASE_SIZE
}) : reaction.url} /> : <CircleCheckIcon size="md" color={Module712.colors.STATUS_POSITIVE} />}
<Text variant="text-sm/semibold" color="text-default">{message}</Text>
</View>
</ReanimatedRexport.View>;
}
@@ -0,0 +1,36 @@
// Metro module 10342 (f10343).
import { useMemo, useCallback } from "react";
import { NOTIFICATION_PREVIEW_LINE_CLAMP } from "./InAppNotificationConstants";
import useChannelName from "../../channel/useChannelName";
import { intl, t } from "../../../intl/index.native";
import { getUserAuthor } from "../../messages/useMessageAuthor";
import { transitionToThread } from "../../routing/transitionToChannel";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import { NotificationPressable } from "./Notification";
import { Avatar, AvatarSizes } from "../../../design/void/native";
import { Text } from "../../../design/components/Text/native/Text";
export default function ForumThreadCreatedNotification(props) {
const notification = props.notification;
const { thread, threadCreator, parentChannel, guild } = notification;
let threadName = useChannelName(thread);
if (threadName == null) {
threadName = intl.string(t["/YzI63"]);
}
const r36 = intl.formatToPlainString(t.WUIDu9, {
threadName
});
const userAuthor = getUserAuthor(threadCreator, thread);
return <NotificationPressable icon={<Avatar size={AvatarSizes.NORMAL} user={threadCreator} guildId={thread.guild_id} />} header={useMemo(() => ({
type: "message",
channel: parentChannel,
parentChannel: null,
guild,
author: userAuthor
}), [parentChannel, guild, userAuthor])} onPress={useCallback(() => {
transitionToThread(thread);
}, [thread])} onSettingsPress={useCallback(() => ModalActionCreators.pushLazy(import("../../../components_native/InAppNotificationSettingsModal"), {
channelId: notification.parentChannel.id
}), [notification.parentChannel.id])} notification={notification}>
<Text variant="redesign/message-preview/medium" color="text-subtle" lineClamp={NOTIFICATION_PREVIEW_LINE_CLAMP}>{r36}</Text>
</NotificationPressable>;
};
@@ -0,0 +1,27 @@
// Metro module 10262 (f10263).
import Module712 from "../../../_bundle/Module712";
import { Easing } from "../../reanimated/ReanimatedRexport";
const set = new Set([10, 25]);
const PX_8 = Module712.space.PX_8;
const PX_16 = Module712.space.PX_16;
const r37 = {
duration: 220,
easing: Easing.bezier(0.16, 1, 0.3, 1)
};
export { set as REACTION_MILESTONE_COUNTS };
export const IN_APP_NOTIFICATION_MAX_HEIGHT = 96;
export const NOTIFICATION_MAX_WIDTH = 480;
export const NOTIFICATION_PREVIEW_LINE_CLAMP = 2;
export const EXPANDABLE_MIN_WINDOW_HEIGHT = 500;
export { PX_8 as RIGHT_ACCESSORY_LEFT_MARGIN };
export { PX_16 as NOTIFICATION_CONTAINER_MARGIN };
export const PAN_INPUT_RANGE = [-100, 0, 100];
export const NOTIFICATION_BOB_RANGE = 20;
export const MIN_SWIPE_DISTANCE = 25;
export const MIN_SWIPE_VELOCITY = 100;
export const STARTED_SWIPE_THRESHOLD = 5;
export const extrapolateConfig = {
extrapolateRight: "clamp",
extrapolateLeft: "clamp"
};
export { r37 as DEFAULT_ANIMATION_TIMING };
@@ -0,0 +1,525 @@
// Metro module 10276 (f10277).
import { useMemo, useState, useCallback, useRef, useEffect } from "react";
import { Keyboard, StyleSheet, View } from "react-native";
import NativeMenuStore from "../../native_menu/native/NativeMenuStore";
import ReadStateStore from "../../../stores/ReadStateStore";
import { DEFAULT_ANIMATION_TIMING, EXPANDABLE_MIN_WINDOW_HEIGHT, MIN_SWIPE_DISTANCE, MIN_SWIPE_VELOCITY, NOTIFICATION_BOB_RANGE, PAN_INPUT_RANGE, extrapolateConfig, NOTIFICATION_CONTAINER_MARGIN } from "./InAppNotificationConstants";
import { AnalyticEvents, AnalyticsObjectTypes, AnalyticsObjects, AnalyticsSections, InAppNotificationTypes } from "../../../Constants";
import * as _ReanimatedRexport from "../../reanimated/ReanimatedRexport";
import ReanimatedRexport, { Easing, useSharedValue, cancelAnimation, useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { useCanExpandInAppNotification } from "./InAppNotificationExpandExperiment";
import { canReactToMessage } from "../../reactions/canReactToMessage";
import { canReplyToMessage } from "../../replies/canReplyToMessage";
import MessageNotification from "./MessageNotification";
import MessageFailedToSendNotification from "./MessageFailedToSendNotification";
import ForumThreadCreatedNotification from "./ForumThreadCreatedNotification";
import { BugReporterNotification } from "../../bug_reporter/native/BugReporterNotification";
import AlertNotification from "./AlertNotification";
import ReactionNotification from "./ReactionNotification";
import ReminderNotification from "./ReminderNotification";
import RestrictedHoursWarningNotification from "./RestrictedHoursWarningNotification";
import MessageRequestNotification from "./MessageRequestNotification";
import { MessageNotificationDetachedContent } from "./MessageNotificationDetachedContent";
import { extractMetadataFromNotification, trackDismissed } from "./InAppNotificationUtils";
import useStateFromSharedValue from "../../reanimated/native/useStateFromSharedValue";
import { useStateFromStores } from "../../../_bundle/Module589";
import { UNSAFE_markDismissibleContentAsDismissed } from "../../dismissible_content/DismissibleContentUnsafeUtils";
import { DismissibleContent } from "../../../_bundle/Module1358";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import AppAnalyticsUtils from "../../app_analytics/AppAnalyticsUtils";
import useBackPressHandler from "../../routing/native/useBackPressHandler";
import useWindowDimensions_native from "../../screen/useWindowDimensions.native";
import SnowflakeUtils from "../../../utils/SnowflakeUtils";
import { ack } from "../../../actions/ReadStateActionCreators";
import * as _timing from "../../../design/animation/reanimated/timing/timing";
import useMountEffect, { useUnmountEffect } from "../../../hooks/useMountEffect";
import AnalyticsUtils from "../../../utils/AnalyticsUtils";
import { Gesture, GestureDetector } from "../../../_bundle/Module5273";
import * as _spring from "../../../design/animation/reanimated/spring/spring";
import { OverlayView } from "../../../design/void/native";
import { Backdrop } from "../../../design/components/Backdrop/native/Backdrop.native";
import * as _index_native from "../../../intl/index.native";
import { intl } from "../../../intl/index.native";
import { SafeAreaPaddingView } from "../../../components_native/common/SafeAreaView";
import { InAppNotificationContext } from "./InAppNotificationContext";
let c6860_24, useStyles, DetachedNotificationContent, __initData, __initData2, __initData3, __initData4, __initData5, __initData6, __initData7, __initData8, __initData9;
const NotificationWrapper = function NotificationWrapper(props) {
const notification2 = props.notification;
const type = notification2.type;
if (InAppNotificationTypes.MESSAGE === type) {
return <MessageNotification notification={notification2} />;
}
if (InAppNotificationTypes.MESSAGE_FAILED_TO_SEND === type) {
return <MessageFailedToSendNotification notification={notification2} />;
}
if (InAppNotificationTypes.FORUM_THREAD_CREATED === type) {
return <ForumThreadCreatedNotification notification={notification2} />;
}
if (InAppNotificationTypes.BUG_REPORTER === type) {
return <BugReporterNotification notification={notification2} />;
}
if (InAppNotificationTypes.ALERT === type) {
return <AlertNotification notification={notification2} />;
}
if (InAppNotificationTypes.REACTION === type) {
return <ReactionNotification notification={notification2} />;
}
if (InAppNotificationTypes.MESSAGE_REMINDER === type) {
return <ReminderNotification notification={notification2} />;
}
if (InAppNotificationTypes.RESTRICTED_HOURS_WARNING !== type && InAppNotificationTypes.RESTRICTED_SCHEDULE_UPDATED !== type) {
if (InAppNotificationTypes.MESSAGE_REQUEST === type) {
return <MessageRequestNotification notification={notification2} />;
}
return null;
}
return <RestrictedHoursWarningNotification notification={notification2} />;
};
DetachedNotificationContent = function DetachedNotificationContent(props) {
const notification2 = props.notification;
return notification2.type === InAppNotificationTypes.MESSAGE ? <MessageNotificationDetachedContent notification={notification2} /> : null;
};
c6860_24 = {
duration: 200,
easing: Easing.in(Easing.ease)
};
useStyles = createStyles({
safeAreaContainer: {
position: "absolute",
left: 0,
right: 0,
backgroundColor: "transparent",
marginTop: 8,
top: 0,
bottom: 0
},
backdrop: {
position: "absolute",
zIndex: 0
},
animatedContainer: {
marginLeft: NOTIFICATION_CONTAINER_MARGIN,
marginRight: NOTIFICATION_CONTAINER_MARGIN
}
});
__initData = {
code: "function InAppNotificationContainerTsx1(finished){const{runOnJS,handleDismissNotification}=this.__closure;if(finished){runOnJS(handleDismissNotification)('autodismissed');}}"
};
__initData2 = {
code: "function InAppNotificationContainerTsx2(){const{runOnJS,setInitialized}=this.__closure;return runOnJS(setInitialized)(true);}"
};
__initData3 = {
code: "function InAppNotificationContainerTsx3(){const{withTiming,expandedSV,DEFAULT_ANIMATION_TIMING}=this.__closure;return{opacity:withTiming(expandedSV.get()?1:0,DEFAULT_ANIMATION_TIMING)};}"
};
__initData4 = {
code: "function InAppNotificationContainerTsx4(){const{runOnJS,setPanning}=this.__closure;runOnJS(setPanning)(false);}"
};
__initData5 = {
code: "function InAppNotificationContainerTsx5(event){const{velocityY,MIN_SWIPE_VELOCITY,MIN_SWIPE_DISTANCE,isExpandableNotification,notificationGestureY,expandedSV,runOnJS,setExpanded,withTiming,PAN_INPUT_RANGE,DEFAULT_ANIMATION_TIMING,handleDismissNotification,setPanning,withSpring}=this.__closure;const shouldDismiss=Math.abs(velocityY.get())>=MIN_SWIPE_VELOCITY||Math.abs(event.translationY)>=MIN_SWIPE_DISTANCE;if(isExpandableNotification&&event.translationY>MIN_SWIPE_DISTANCE){notificationGestureY.set(0);expandedSV.set(true);runOnJS(setExpanded)(true,'swipe');}else if(shouldDismiss&&event.translationY<=0){notificationGestureY.set(withTiming(event.translationY>0?PAN_INPUT_RANGE[2]:PAN_INPUT_RANGE[0],DEFAULT_ANIMATION_TIMING,'animate-always',function(finished){if(finished){runOnJS(handleDismissNotification)('swipe');}}));}else{runOnJS(setPanning)(false);notificationGestureY.set(withSpring(0,{damping:10,mass:1,stiffness:100,velocity:velocityY.get()},'animate-always'));}}"
};
__initData6 = {
code: "function InAppNotificationContainerTsx6(event){const{startY,isExpandableNotification,notificationGestureY,velocityY}=this.__closure;const rawY=startY.get()+event.translationY;const newY=isExpandableNotification&&rawY>0?rawY:Math.min(rawY,startY.get());notificationGestureY.set(newY);velocityY.set(event.velocityY);}"
};
__initData7 = {
code: "function InAppNotificationContainerTsx7(){const{startY,notificationGestureY,velocityY,runOnJS,setPanning}=this.__closure;startY.set(notificationGestureY.get());velocityY.set(0);runOnJS(setPanning)(true);}"
};
__initData8 = {
code: "function InAppNotificationContainerTsx8(finished){const{runOnJS,handleDismissNotification}=this.__closure;if(finished){runOnJS(handleDismissNotification)('swipe');}}"
};
__initData9 = {
code: "function InAppNotificationContainerTsx9(){const{notificationGestureY,scale,isExpandableNotification,interpolate,MIN_SWIPE_DISTANCE,PAN_INPUT_RANGE,NOTIFICATION_BOB_RANGE,extrapolateConfig,initialized}=this.__closure;const gestureY=notificationGestureY.get();const scaleValue=scale.get();if(isExpandableNotification&&gestureY>0){return{transform:[{translateY:interpolate(gestureY,[0,MIN_SWIPE_DISTANCE,PAN_INPUT_RANGE[2]],[0,0,NOTIFICATION_BOB_RANGE],extrapolateConfig)},{scale:initialized?1:scaleValue}],opacity:initialized?1:scaleValue};}const scaleTransform=initialized?interpolate(gestureY,PAN_INPUT_RANGE,[0.3,1,0.3],extrapolateConfig):scaleValue;const opacityTransform=initialized?interpolate(gestureY,PAN_INPUT_RANGE,[0,1,0],extrapolateConfig):scaleValue;return{transform:[{translateY:gestureY},{scale:scaleTransform}],opacity:opacityTransform};}"
};
export default function InAppNotificationContainer(props) {
let r122;
let guildId, channelId, messageId, channelType, sharedValue, sharedValue2, sharedValue3, sharedValue4, state, setState, state2, setState2, state3, setState3, sharedValue5, isExpanded, state4, setState4, state5, setState5, callback, callback2, showReactionBar, showReplyInput, isExpandableNotification, callback3, ref;
const notification = props.notification;
guildId = void 0;
channelId = void 0;
messageId = void 0;
channelType = void 0;
sharedValue = void 0;
sharedValue2 = void 0;
sharedValue3 = void 0;
sharedValue4 = void 0;
state = void 0;
setState = void 0;
state2 = void 0;
setState2 = void 0;
state3 = void 0;
setState3 = void 0;
sharedValue5 = void 0;
isExpanded = void 0;
state4 = void 0;
setState4 = void 0;
state5 = void 0;
setState5 = void 0;
callback = void 0;
callback2 = void 0;
showReactionBar = void 0;
showReplyInput = void 0;
isExpandableNotification = void 0;
callback3 = void 0;
ref = void 0;
const styles = useStyles();
const memo = useMemo(() => extractMetadataFromNotification(notification), [notification]);
guildId = memo.guildId;
channelId = memo.channelId;
messageId = memo.messageId;
channelType = memo.channelType;
sharedValue = useSharedValue(0);
sharedValue2 = useSharedValue(0);
sharedValue3 = useSharedValue(0);
sharedValue4 = useSharedValue(0);
[state, setState] = useState(null);
[state2, setState2] = useState(false);
[state3, setState3] = useState(false);
sharedValue5 = useSharedValue(false);
isExpanded = useStateFromSharedValue(sharedValue5);
[state4, setState4] = useState(false);
[state5, setState5] = useState(false);
const stateFromStores = useStateFromStores([NativeMenuStore], () => NativeMenuStore.isOpen());
callback = useCallback(() => {
UNSAFE_markDismissibleContentAsDismissed(DismissibleContent.IN_APP_NOTIFICATION_EXPAND_NUX);
}, []);
callback2 = useCallback((a0, a1) => {
sharedValue5.set(a0);
if (a0) {
let expand_source = a1;
ActionSheetActionCreators.hideAllActionSheets();
callback();
const IN_APP_NOTIFICATION_EXPANDED = AnalyticEvents.IN_APP_NOTIFICATION_EXPANDED;
if (a1 == null) {
expand_source = "unknown";
}
AppAnalyticsUtils.trackWithMetadata(IN_APP_NOTIFICATION_EXPANDED, {
type: notification.type,
notif_guild_id: guildId,
notif_channel_id: channelId,
in_app_notification_id: notification.inAppNotificationId,
message_id: messageId,
expand_source
});
}
ActionSheetActionCreators.setActionSheetZIndex(a0 ? 1 : void 0);
}, [sharedValue5, notification, guildId, channelId, messageId, callback]);
useBackPressHandler(useCallback(() => {
let r5 = !!isExpanded;
if (r5) {
callback2(false);
r5 = true;
}
return r5;
}, [isExpanded, callback2]), isExpanded);
const windowDimensions_native = useWindowDimensions_native({
ignoreKeyboard: true
});
const { width, height } = windowDimensions_native;
const canExpandInAppNotification = useCanExpandInAppNotification("InAppNotificationContainer");
let canExpand = canExpandInAppNotification.canExpand;
const canReact = canExpandInAppNotification.canReact;
if (notification.type !== InAppNotificationTypes.MESSAGE) {
r122 = {
showReactionBar: false,
showReplyInput: false,
isExpandableNotification: false
};
} else {
const { message, channel } = notification;
if (canExpand) {
canExpand = height > EXPANDABLE_MIN_WINDOW_HEIGHT;
}
const canReactToMessage2 = canReactToMessage(message, channel);
const canReplyToMessage2 = canReplyToMessage(channel, message);
let showReactionBar2 = (canExpand ? canReact : canExpand) && canReactToMessage2;
if (canExpand) {
canExpand = canReplyToMessage2;
}
r122 = {
showReactionBar: showReactionBar2,
showReplyInput: canExpand,
isExpandableNotification: null
};
if (!showReactionBar2) {
showReactionBar2 = canExpand;
}
r122.isExpandableNotification = showReactionBar2;
}
showReactionBar = r122.showReactionBar;
showReplyInput = r122.showReplyInput;
isExpandableNotification = r122.isExpandableNotification;
callback3 = useCallback((a0) => {
if (a0 != null) {
trackDismissed({
type: notification.type,
guildId,
channelId,
dismissReason: a0,
inAppNotificationId: notification.inAppNotificationId,
messageId
});
}
if (state4 && notification.type === InAppNotificationTypes.MESSAGE) {
const r11 = ReadStateStore.ackMessageId(notification.channel.id);
if ((r11 == null || SnowflakeUtils.compare(r11, notification.message.id) < 0) && notification.mentionCount >= ReadStateStore.getMentionCount(notification.channel.id)) {
ack(notification.channel.id, {
section: AnalyticsSections.IN_APP_NOTIFICATION,
object: AnalyticsObjects.ACK_IN_APP_NOTIFICATION_ACTION,
objectType: AnalyticsObjectTypes.ACK_SEMI_AUTOMATIC
}, true, true, notification.message.id);
}
}
const onDismiss2 = notification.onDismiss;
if (onDismiss2 != null) {
onDismiss2.call(notification);
}
}, [state4, notification, guildId, channelId, messageId]);
ref = useRef(null);
useEffect(() => {
let r3 = state3;
if (state3) {
r3 = ref.current == null;
}
if (r3) {
ref.current = setTimeout(() => {
const r7 = PAN_INPUT_RANGE[0];
const r20 = function t(a0) {
if (a0) {
_ReanimatedRexport.runOnJS(callback3)("autodismissed");
}
};
r20.__closure = {
runOnJS: _ReanimatedRexport.runOnJS,
handleDismissNotification: callback3
};
r20.__workletHash = 1150739008183;
r20.__initData = __initData;
sharedValue.set(_timing.withTiming(r7, DEFAULT_ANIMATION_TIMING, "respect-motion-settings", r20));
}, 2000);
}
}, [state3, sharedValue, callback3]);
useUnmountEffect(() => {
ActionSheetActionCreators.setActionSheetZIndex(void 0);
if (ref.current != null) {
clearTimeout(ref.current);
cancelAnimation(sharedValue);
}
});
useMountEffect(() => {
const r18 = () => _ReanimatedRexport.runOnJS(setState2)(true);
r18.__closure = {
runOnJS: _ReanimatedRexport.runOnJS,
setInitialized: setState2
};
r18.__workletHash = 11548697745556;
r18.__initData = __initData2;
sharedValue4.set(_timing.withTiming(1, c6860_24, "respect-motion-settings", r18));
return () => cancelAnimation(sharedValue4);
});
useEffect(() => {
if (state2) {
AnalyticsUtils.track(AnalyticEvents.IN_APP_NOTIFICATION_SHOWN, {
type: notification.type,
guild_id: guildId,
channel_id: channelId,
in_app_notification_id: notification.inAppNotificationId,
message_id: messageId,
channel_type: channelType
});
}
}, [state2, notification.type, guildId, channelId, notification.inAppNotificationId, messageId, channelType]);
const xt = () => ({
opacity: _timing.withTiming(sharedValue5.get() ? 1 : 0, DEFAULT_ANIMATION_TIMING)
});
xt.__closure = {
withTiming: _timing.withTiming,
expandedSV: sharedValue5,
DEFAULT_ANIMATION_TIMING
};
xt.__workletHash = 2841593511002;
xt.__initData = __initData3;
const animatedStyle = useAnimatedStyle(xt);
const r170 = Gesture.Pan().enabled(isExpanded ? !isExpanded : !state3);
const Rt = function Rt() {
sharedValue3.set(sharedValue.get());
sharedValue2.set(0);
_ReanimatedRexport.runOnJS(setState5)(true);
};
Rt.__closure = {
startY: sharedValue3,
notificationGestureY: sharedValue,
velocityY: sharedValue2,
runOnJS: _ReanimatedRexport.runOnJS,
setPanning: setState5
};
Rt.__workletHash = 11316955045022;
Rt.__initData = __initData7;
const r179 = r170.onBegin(Rt);
const Gt = function Gt(a0) {
let r6;
const r8 = sharedValue3.get() + a0.translationY;
if (isExpandableNotification) {
r6 = r8;
if (!(r6 > 0)) {
r6 = Math.min(r8, sharedValue3.get());
}
} else {
r6 = Math.min(r8, sharedValue3.get());
}
sharedValue.set(r6);
sharedValue2.set(a0.velocityY);
};
Gt.__closure = {
startY: sharedValue3,
isExpandableNotification,
notificationGestureY: sharedValue,
velocityY: sharedValue2
};
Gt.__workletHash = 16677375054247;
Gt.__initData = __initData6;
const r185 = r179.onUpdate(Gt);
const vt = function vt(a0) {
const r2 = Math.abs(sharedValue2.get()) >= MIN_SWIPE_VELOCITY || Math.abs(a0.translationY) >= MIN_SWIPE_DISTANCE;
if (isExpandableNotification && a0.translationY > MIN_SWIPE_DISTANCE) {
sharedValue.set(0);
sharedValue5.set(true);
_ReanimatedRexport.runOnJS(callback2)(true, "swipe");
} else if (r2 && a0.translationY <= 0) {
const r59 = a0.translationY > 0 ? PAN_INPUT_RANGE[2] : PAN_INPUT_RANGE[0];
const n = function n(a0) {
if (a0) {
_ReanimatedRexport.runOnJS(callback3)("swipe");
}
};
n.__closure = {
runOnJS: _ReanimatedRexport.runOnJS,
handleDismissNotification: callback3
};
n.__workletHash = 1684596854482;
n.__initData = __initData8;
sharedValue.set(_timing.withTiming(r59, DEFAULT_ANIMATION_TIMING, "animate-always", n));
} else {
_ReanimatedRexport.runOnJS(setState5)(false);
sharedValue.set(_spring.withSpring(0, {
damping: 10,
mass: 1,
stiffness: 100,
velocity: sharedValue2.get()
}, "animate-always"));
}
};
vt.__closure = {
velocityY: sharedValue2,
MIN_SWIPE_VELOCITY,
MIN_SWIPE_DISTANCE,
isExpandableNotification,
notificationGestureY: sharedValue,
expandedSV: sharedValue5,
runOnJS: _ReanimatedRexport.runOnJS,
setExpanded: callback2,
withTiming: _timing.withTiming,
PAN_INPUT_RANGE,
DEFAULT_ANIMATION_TIMING,
handleDismissNotification: callback3,
setPanning: setState5,
withSpring: _spring.withSpring
};
vt.__workletHash = 5165226193044;
vt.__initData = __initData5;
const r203 = r185.onEnd(vt);
const Mt = function Mt() {
_ReanimatedRexport.runOnJS(setState5)(false);
};
Mt.__closure = {
runOnJS: _ReanimatedRexport.runOnJS,
setPanning: setState5
};
Mt.__workletHash = 2178187669683;
Mt.__initData = __initData4;
const gesture = r203.onFinalize(Mt);
const bt = function bt() {
let r26;
const translateY = sharedValue.get();
const r5 = sharedValue4.get();
if (isExpandableNotification && translateY > 0) {
const transform = [{
translateY: _ReanimatedRexport.interpolate(translateY, [0, MIN_SWIPE_DISTANCE, PAN_INPUT_RANGE[2]], [0, 0, NOTIFICATION_BOB_RANGE], extrapolateConfig)
}, ,];
let opacity = 1;
transform[1] = {
scale: state2 ? 1 : r5
};
if (!state2) {
opacity = r5;
}
r26 = {
transform,
opacity
};
} else {
r26 = {
transform: [{
translateY
}, {
scale: state2 ? _ReanimatedRexport.interpolate(translateY, PAN_INPUT_RANGE, [0.3, 1, 0.3], extrapolateConfig) : r5
}],
opacity: state2 ? _ReanimatedRexport.interpolate(translateY, PAN_INPUT_RANGE, [0, 1, 0], extrapolateConfig) : r5
};
}
return r26;
};
bt.__closure = {
notificationGestureY: sharedValue,
scale: sharedValue4,
isExpandableNotification,
interpolate: _ReanimatedRexport.interpolate,
MIN_SWIPE_DISTANCE,
PAN_INPUT_RANGE,
NOTIFICATION_BOB_RANGE,
extrapolateConfig,
initialized: state2
};
bt.__workletHash = 14122965198084;
bt.__initData = __initData9;
const animatedStyle2 = useAnimatedStyle(bt);
const memo2 = useMemo(() => ({
notificationGestureY: sharedValue,
velocityY: sharedValue2,
containerScale: sharedValue4,
initialized: state2,
autoDismissing: state3,
setAutoDismissing: setState3,
setActionTaken: setState4,
isExpanded,
expandedSV: sharedValue5,
setExpanded: callback2,
handleDismissNotification: callback3,
panning: state5,
isExpandableNotification,
showReactionBar,
showReplyInput,
confirmation: state,
setConfirmation: setState
}), [state3, sharedValue5, callback3, state2, isExpanded, sharedValue, sharedValue4, callback2, sharedValue2, state5, isExpandableNotification, showReactionBar, showReplyInput, state, setState]);
return <OverlayView style={StyleSheet.absoluteFill} pointerEvents="box-none">
<View style={[styles.backdrop, {
width,
height
}]} pointerEvents={isExpanded ? "auto" : "none"}>
<Backdrop style={animatedStyle} onDismiss={() => {
Keyboard.dismiss();
callback2(false);
}} accessibilityLabel={intl.string(_index_native.t["9sewOj"])} />
</View>
<SafeAreaPaddingView top bottom left right style={styles.safeAreaContainer} pointerEvents="box-none" importantForAccessibility={stateFromStores ? "no-hide-descendants" : void 0}>
<InAppNotificationContext.Provider value={memo2}>
<GestureDetector gesture={gesture}>
<ReanimatedRexport.View style={[styles.animatedContainer, animatedStyle2]} pointerEvents="box-none">
<NotificationWrapper notification={notification} />
</ReanimatedRexport.View>
</GestureDetector>
<DetachedNotificationContent notification={notification} />
</InAppNotificationContext.Provider>
</SafeAreaPaddingView>
</OverlayView>;
};
@@ -0,0 +1,11 @@
// Metro module 10302 (f10303).
import { createContext, useContext } from "react";
const context = createContext(void 0);
export { context as InAppNotificationContext };
export function useInAppNotificationContext() {
const context2 = useContext(context);
if (context2 == null) {
throw new Error("useInAppNotificationContext must be used within provider of InAppNotificationContext");
}
return context2;
}
@@ -0,0 +1,25 @@
// Metro module 10277 (f10278).
import { createApexExperiment } from "../../experiments/apex/index";
const apexExperiment = createApexExperiment({
name: "2026-05-in-app-notification-expand",
kind: "user",
defaultConfig: {
canExpand: false,
canReact: false
},
variations: {
1: {
canExpand: true,
canReact: true
},
2: {
canExpand: true,
canReact: false
}
}
});
export function useCanExpandInAppNotification(a0) {
return apexExperiment.useConfig({
location: a0
});
}
@@ -0,0 +1,34 @@
// Metro module 10336 (f10337).
import { Storage } from "../../../_bundle/Module595";
let c6914_2 = "inAppNotificationExpandNux";
let c6914_3 = {
lastShownAtMs: 0,
numTimesShown: 0
};
export const MAX_TIMES_SHOWN = 7;
export const ONE_DAY_MS = 86400000;
export const NUX_REVEAL_DELAY_MS = 1000;
export const NUX_REVEAL_DURATION_MS = 300;
export const DRAG_HANDLE_BOUNCE_DISTANCE = 4;
export const DRAG_HANDLE_BOUNCE_DURATION_MS = 650;
export function getExpandNUXState() {
let r9 = Storage.get(c6914_2);
if (r9 == null) {
r9 = c6914_3;
}
return r9;
}
export function markExpandNUXStateAsShown() {
let r13 = Storage.get(c6914_2);
if (r13 == null) {
r13 = c6914_3;
}
Storage.set(c6914_2, {
...r13,
numTimesShown: r13.numTimesShown + 1,
lastShownAtMs: Date.now()
});
}
export function resetExpandNUXState() {
Storage.set(c6914_2, c6914_3);
}
@@ -0,0 +1,126 @@
// Metro module 10261 (f10262).
import { useMemo } from "react";
import { REACTION_MILESTONE_COUNTS } from "./InAppNotificationConstants";
import { AnalyticEvents, ChannelTypes, InAppNotificationTypes, MessageEmbedTypes, MessageFlags } from "../../../Constants";
import { sumBy } from "../../../_bundle/Module12";
import { v4 } from "../../../_bundle/Module514";
import { isIOS } from "../../../_bundle/Module501";
import isForwardMessage from "../../forwarding/isForwardMessage";
import AppAnalyticsUtils from "../../app_analytics/AppAnalyticsUtils";
let $mk84274 = function() {
return (a0) => a0.type === MessageEmbedTypes.GIFV;
};
const extractMetadataFromNotification = function extractMetadataFromNotification(notification) {
let channelId, channelType, guildId, messageId;
L43: {
const type = notification.type;
if (InAppNotificationTypes.MESSAGE !== type && InAppNotificationTypes.REACTION !== type) {
if (InAppNotificationTypes.ALERT === type) {
let r36 = notification.guild?.id;
if (r36 == null) {
r36 = notification.channel?.guild_id;
}
const id2 = notification.channel?.id;
channelType = notification.channel?.type;
messageId = void 0;
channelId = id2;
guildId = r36;
break L43;
}
if (InAppNotificationTypes.FORUM_THREAD_CREATED === type) {
const guild_id2 = notification.thread?.guild_id;
channelId = notification.thread?.id;
channelType = void 0;
messageId = void 0;
guildId = guild_id2;
break L43;
}
if (InAppNotificationTypes.MESSAGE_FAILED_TO_SEND === type) {
channelId = notification.channelId;
channelType = void 0;
messageId = void 0;
guildId = void 0;
break L43;
}
const MESSAGE_REMINDER = InAppNotificationTypes.MESSAGE_REMINDER;
channelType = void 0;
messageId = void 0;
channelId = void 0;
guildId = void 0;
if (MESSAGE_REMINDER !== type) {
break L43;
}
const guild_id = notification.channel?.guild_id;
const id = notification.channel?.id;
channelType = notification.channel?.type;
messageId = void 0;
channelId = id;
guildId = guild_id;
} else {
let r48 = notification.guild?.id;
if (r48 == null) {
r48 = notification.channel?.guild_id;
}
const id3 = notification.channel?.id;
const id4 = notification.message?.id;
channelType = notification.channel?.type;
messageId = id4;
channelId = id3;
guildId = r48;
}
}
return {
guildId,
channelId,
messageId,
channelType
};
};
export function isReactionMilestoneNotification(a0, a1) {
if (a1 != null && a1 !== ChannelTypes.GUILD_ANNOUNCEMENT) {
return REACTION_MILESTONE_COUNTS.has(sumBy(a0, ({ count_details }) => {
let r6 = count_details?.burst;
if (r6 == null) {
r6 = 0;
}
let r4 = count_details?.normal;
if (r4 == null) {
r4 = 0;
}
return r6 + r4;
}));
}
return false;
}
export function generateInAppNotificationId() {
return v4();
}
export function getMessagePreviewTextVariant() {
return isIOS() ? "text-md/normal" : "text-md/medium";
}
export function useHasPreviewableMedia(a0) {
return useMemo(() => a0.hasFlag(MessageFlags.IS_VOICE_MESSAGE) || a0.attachments.length > 0 || a0.embeds.length > 0 && a0.embeds.every($mk84274()) || a0.stickerItems.length > 0 || isForwardMessage(a0) && a0.messageSnapshots.some(({ message }) => message.hasFlag(MessageFlags.IS_VOICE_MESSAGE) || message.attachments.length > 0 || message.embeds.length > 0 && message.embeds.every($mk84274()) || message.stickerItems.length > 0), [a0]);
}
export { extractMetadataFromNotification };
export function trackInAppNotificationAccessoryClicked(a0, a1) {
const r10 = extractMetadataFromNotification(a0);
AppAnalyticsUtils.trackWithMetadata(AnalyticEvents.IN_APP_NOTIFICATION_ACCESSORY_CLICKED, {
type: a0.type,
in_app_notification_id: a0.inAppNotificationId,
notif_guild_id: r10.guildId,
notif_channel_id: r10.channelId,
message_id: r10.messageId,
accessory: a1
});
}
export function trackDismissed(a0) {
const { guildId, channelId } = a0;
AppAnalyticsUtils.trackWithMetadata(AnalyticEvents.IN_APP_NOTIFICATION_DISMISSED, {
type: a0.type,
guild_id: guildId,
channel_id: channelId,
dismiss_reason: a0.dismissReason,
in_app_notification_id: a0.inAppNotificationId,
message_id: a0.messageId
});
}
@@ -0,0 +1,284 @@
// Metro module 10333 (f10334).
import { useMemo } from "react";
import { PixelRatio, StyleSheet, View } from "react-native";
import AccessibilityStore from "../../a11y/AccessibilityStore";
import { RIGHT_ACCESSORY_LEFT_MARGIN } from "./InAppNotificationConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { PlayIcon } from "../../../design/components/Icon/native/redesign/generated/PlayIcon";
import { Text } from "../../../design/components/Text/native/Text";
import { useToken } from "../../../design/tokens/native/useToken";
import { isAndroid } from "../../../utils/PlatformUtils";
import VisualEffectView from "../../visual_effect_view/native/VisualEffectView";
import { ImageWarningIcon } from "../../../design/components/Icon/native/redesign/generated/ImageWarningIcon";
import { EyeIcon } from "../../../design/components/Icon/native/redesign/generated/EyeIcon";
import { useStateFromStores } from "../../../_bundle/defaultAreStatesEqual";
import { useShouldAgeVerifyForExplicitMedia } from "../../explicit_media_redaction/ExplicitMediaRedactionUtils";
import { useEnabledHarmTypesBitmaskForMessage } from "../../explicit_media_redaction/hooks/useContentHarmTypes";
import { PreviewableMediaTypes, usePreviewableMedia } from "./hooks/usePreviewableMedia";
import { getAttachmentObscurityProps } from "../../messages/native/renderer/ExplicitMediaUtils";
import { getAttachmentUrl } from "../../media_viewer/native/MediaSourceUtil";
import { getSrcWithWidthAndHeight } from "../../../utils/native/ImageUtils";
import FastImage from "../../../components_native/common/FastImage";
import { getMediaObscuredReasonFromBitmask, getEnabledHarmTypesForChannelAndAuthorId } from "../../explicit_media_redaction/ObscuredMediaUtils";
import { ObscuredMediaTypes } from "../../explicit_media_redaction/ExplicitMediaRedactionModels";
import Video from "../../../components_native/common/Video";
import Sticker from "../../stickers/native/Sticker";
import { BADGE_PADDING } from "../../../design/void/native";
import ClipView, { CutoutShape } from "../../../design/components/Icon/native/ClipView";
import ReanimatedRexport, { useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
let useStyles, useStyles2, useStyles3, useStyles4, useStyles5, CountBadge, ObscuredMediaOverlay, SinglePreviewableMedia, MultiplePreviewableMedia, MediaPreviewRightAccessoryContent, __initData, ExpandableMediaPreview, SimpleMediaPreview;
const VideoBadge = function VideoBadge() {
const styles = useStyles();
return <View style={styles.badge}>
<PlayIcon style={styles.icon} size="custom" color="white" />
</View>;
};
CountBadge = function CountBadge(props) {
const total = props.total;
return <View style={useStyles2().badge}>
<Text variant="text-xs/semibold" color="text-default">{total}</Text>
</View>;
};
ObscuredMediaOverlay = function ObscuredMediaOverlay(props) {
const { isObscured, isSpoiler, children } = props;
const styles3 = useStyles3();
const token = useToken(Module712.colors.SPOILER_HIDDEN_BACKGROUND);
if (!isObscured && !isSpoiler) {
return children;
}
const blurTheme = isAndroid() ? "dark" : "light";
return <>
{children}
{isObscured && <View style={styles3.obscureBackground} />}
{isObscured ? !isObscured : <VisualEffectView blurTheme={blurTheme} android_fallbackColor={token} style={StyleSheet.absoluteFill} />}
<View style={styles3.spoilerIconContainer}>
{isObscured ? <ImageWarningIcon size="sm" color="white" /> : <View style={styles3.spoilerPill}>
<EyeIcon size="sm" color="white" />
</View>}
</View>
</>;
};
SinglePreviewableMedia = function SinglePreviewableMedia(props) {
const { previewableMedia, size, message } = props;
const styles3 = useStyles3();
const stateFromStores = useStateFromStores([AccessibilityStore], () => AccessibilityStore.useReducedMotion);
const { type, media, icon } = previewableMedia;
const shouldAgeVerifyForExplicitMedia = useShouldAgeVerifyForExplicitMedia();
const enabledHarmTypesBitmaskForMessage = useEnabledHarmTypesBitmaskForMessage(message);
if (PreviewableMediaTypes.VOICE_MESSAGE === type) {
return <View style={{
width: size,
height: size
}}>{icon}</View>;
}
if (PreviewableMediaTypes.AUDIO !== type && PreviewableMediaTypes.FILE !== type) {
if (PreviewableMediaTypes.IMAGE !== type && PreviewableMediaTypes.VIDEO !== type) {
if (PreviewableMediaTypes.GIF === type) {
const url = media.video?.url;
const thumbnail = media.thumbnail;
if (thumbnail == null) {
return null;
}
const isObscured = getMediaObscuredReasonFromBitmask({
type: ObscuredMediaTypes.Embed,
media
}, getEnabledHarmTypesForChannelAndAuthorId(message.channel_id, message.author?.id)).length > 0;
const poster = thumbnail.proxyURL != null && thumbnail.proxyURL !== "" ? thumbnail.proxyURL : thumbnail.url;
return <View style={[styles3.mediaThumbnailContainer, {
width: size,
height: size
}]}>
<ObscuredMediaOverlay isObscured={isObscured} isSpoiler={false}>
{url != null && (url !== "" && !stateFromStores) ? <Video resizeMode="cover" width={size} height={size} paused={false} src={{
videoURI: url
}} poster={poster} postponeRender={false} /> : <FastImage source={{
uri: poster
}} style={styles3.mediaThumbnail} resizeMode="cover" />}
</ObscuredMediaOverlay>
</View>;
}
if (PreviewableMediaTypes.STICKER === type) {
return <View style={[styles3.mediaThumbnailContainer, {
width: size,
height: size
}]}>
<Sticker sticker={media} size={size} animated={!stateFromStores} />
</View>;
}
return null;
}
const { width, height } = media;
if (width != null && !(width <= 0) && height != null && !(height <= 0)) {
const attachmentObscurityProps = getAttachmentObscurityProps({
attachment: media,
shouldObscureSpoiler: true,
enabledContentHarmTypeFlags: enabledHarmTypesBitmaskForMessage,
shouldAgeVerify: shouldAgeVerifyForExplicitMedia
});
return <View style={[styles3.mediaThumbnailContainer, {
width: size,
height: size
}]}>
<ObscuredMediaOverlay isObscured={attachmentObscurityProps.obscure} isSpoiler={attachmentObscurityProps.isSpoiler}>
<FastImage source={{
uri: getSrcWithWidthAndHeight({
src: getAttachmentUrl(media),
sourceWidth: width,
sourceHeight: height,
targetWidth: 2 * size,
targetHeight: 2 * size,
animated: false,
format: type === PreviewableMediaTypes.VIDEO ? "png" : void 0
})
}} style={styles3.mediaThumbnail} resizeMode="cover" />
{type === PreviewableMediaTypes.VIDEO ? <VideoBadge /> : null}
</ObscuredMediaOverlay>
</View>;
}
return null;
}
return <View style={[styles3.iconContainer, {
width: size,
height: size
}]}>{icon}</View>;
};
MultiplePreviewableMedia = function MultiplePreviewableMedia(props) {
const { previewableMedia, totalMediaCount, message } = props;
return <View style={useStyles4().container}>
<ClipView cutouts={[useMemo(() => {
const r7 = BADGE_PADDING + 5;
const width = PixelRatio.roundToNearestPixel(20 + 2 * BADGE_PADDING);
return {
shape: CutoutShape.RoundedRect,
x: 56 - width + r7,
y: -r7,
width,
height: width,
cornerRadius: PixelRatio.roundToNearestPixel(width / 2)
};
}, [])]}>
<SinglePreviewableMedia previewableMedia={previewableMedia} size={56} message={message} />
</ClipView>
<CountBadge total={totalMediaCount} />
</View>;
};
MediaPreviewRightAccessoryContent = function MediaPreviewRightAccessoryContent(props) {
const { previewableMedia, totalMediaCount, message } = props;
const previewableMedia2 = previewableMedia[0];
return totalMediaCount === 1 ? <SinglePreviewableMedia previewableMedia={previewableMedia2} size={64} message={message} /> : <MultiplePreviewableMedia previewableMedia={previewableMedia2} totalMediaCount={totalMediaCount} message={message} />;
};
ExpandableMediaPreview = function ExpandableMediaPreview(props) {
const { message, totalMediaCount, accessoryExitProgressSV, previewableMedia } = props;
const styles5 = useStyles5();
const l = function l() {
const r6 = accessoryExitProgressSV.get();
return {
opacity: 1 - r6,
transform: [{
scale: 1 - r6
}]
};
};
l.__closure = {
accessoryExitProgressSV
};
l.__workletHash = 9116777278421;
l.__initData = __initData;
return <ReanimatedRexport.View style={[styles5.rightAccessoryAbsolute, useAnimatedStyle(l)]}>
<MediaPreviewRightAccessoryContent previewableMedia={previewableMedia} totalMediaCount={totalMediaCount} message={message} />
</ReanimatedRexport.View>;
};
SimpleMediaPreview = function SimpleMediaPreview(props) {
const { message, previewableMedia, totalMediaCount } = props;
return <View style={useStyles5().rightAccessoryContainer}>
<MediaPreviewRightAccessoryContent previewableMedia={previewableMedia} totalMediaCount={totalMediaCount} message={message} />
</View>;
};
useStyles = createStyles({
badge: {
alignItems: "center",
justifyContent: "center",
backgroundColor: Module712.colors.CONTROL_OVERLAY_SECONDARY_BACKGROUND_DEFAULT,
borderRadius: Module712.radii.xs,
width: 16,
height: 16,
position: "absolute",
bottom: 4,
left: 4
},
icon: {
width: 10,
height: 10
}
});
useStyles2 = createStyles({
badge: {
width: 20,
height: 20,
backgroundColor: Module712.colors.BACKGROUND_MOD_SUBTLE,
borderRadius: Module712.radii.round,
alignItems: "center",
justifyContent: "center",
position: "absolute",
right: -5,
top: -5
}
});
useStyles3 = createStyles({
mediaThumbnailContainer: {
borderRadius: Module712.radii.sm,
overflow: "hidden"
},
mediaThumbnail: {
width: "100%",
height: "100%"
},
iconContainer: {
alignItems: "center",
justifyContent: "center",
backgroundColor: Module712.colors.BACKGROUND_MOD_SUBTLE,
borderRadius: Module712.radii.sm
},
obscureBackground: {
...StyleSheet.absoluteFillObject,
backgroundColor: Module712.unsafe_rawColors.PRIMARY_500
},
spoilerIconContainer: {
...StyleSheet.absoluteFillObject,
justifyContent: "center",
alignItems: "center"
},
spoilerPill: {
padding: Module712.space.PX_4,
borderRadius: Module712.radii.xs,
backgroundColor: Module712.colors.CONTROL_OVERLAY_SECONDARY_BACKGROUND_DEFAULT,
justifyContent: "center",
alignItems: "center"
}
});
useStyles4 = createStyles({
container: {
overflow: "visible"
}
});
useStyles5 = createStyles({
rightAccessoryContainer: {
marginLeft: RIGHT_ACCESSORY_LEFT_MARGIN
},
rightAccessoryAbsolute: {
position: "absolute",
right: Module712.space.PX_12,
top: Module712.space.PX_12
}
});
__initData = {
code: "function MediaPreviewRightAccessoryTsx1(){const{accessoryExitProgressSV}=this.__closure;const progress=accessoryExitProgressSV.get();return{opacity:1-progress,transform:[{scale:1-progress}]};}"
};
export const PREVIEW_SIZE = 64;
export function MediaPreviewRightAccessory(props) {
const { message, accessoryExitProgressSV: accessoryExitProgressSV2 } = props;
const previewableMedia = usePreviewableMedia(message);
const length = previewableMedia.length;
return length !== 0 ? accessoryExitProgressSV2 != null ? <ExpandableMediaPreview message={message} previewableMedia={previewableMedia} totalMediaCount={length} accessoryExitProgressSV={accessoryExitProgressSV2} /> : <SimpleMediaPreview message={message} previewableMedia={previewableMedia} totalMediaCount={length} /> : null;
}
@@ -0,0 +1,41 @@
// Metro module 10341 (f10342).
import { memo, useCallback } from "react";
import { View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { intl, t } from "../../../intl/index.native";
import { transitionToMessage } from "../../routing/transitionToChannel";
import { JumpType } from "../../../flow/Client";
import { NotificationPressable } from "./Notification";
import { RetryIcon } from "../../../design/components/Icon/native/redesign/generated/RetryIcon";
import { SystemMessageText } from "./MessagePreviewText";
const useStyles = createStyles({
iconContainer: {
width: 40,
height: 40,
backgroundColor: Module712.colors.BACKGROUND_MOD_SUBTLE,
display: "flex",
justifyContent: "center",
alignItems: "center",
borderRadius: Module712.radii.md
}
});
const r37 = memo(function MessageFailedToSendNotification(props) {
const notification = props.notification;
const styles = useStyles();
const header = {
type: "simple",
text: intl.string(t.Q0x94X)
};
const { channelId, messageId } = notification;
return <NotificationPressable icon={<View style={styles.iconContainer}>
<RetryIcon size="md" color={Module712.colors.ICON_SUBTLE} />
</View>} header={header} onPress={useCallback(() => {
transitionToMessage(channelId, messageId, {
jumpType: JumpType.INSTANT
});
}, [channelId, messageId])} notification={notification}>
<SystemMessageText text={intl.string(t.xxRPOT)} />
</NotificationPressable>;
});
export default r37;
@@ -0,0 +1,458 @@
// Metro module 10278 (f10279).
import * as Module19 from "react";
import { useMemo, useCallback, useEffect } from "react";
import { View } from "react-native";
import AccessibilityStore from "../../a11y/AccessibilityStore";
import { DEFAULT_ANIMATION_TIMING, IN_APP_NOTIFICATION_MAX_HEIGHT, NOTIFICATION_PREVIEW_LINE_CLAMP, RIGHT_ACCESSORY_LEFT_MARGIN } from "./InAppNotificationConstants";
import { MessageEmbedTypes } from "../../../Constants";
import * as _PlatformUtils from "../../../utils/PlatformUtils";
import Module712 from "../../../_bundle/Module712";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import MessagePreviewText from "./MessagePreviewText";
import useTruncatedGradientColors from "./hooks/useTruncatedGradientColors";
import { useStateFromStores } from "../../../_bundle/Module589";
import { useHasPreviewableMedia } from "./InAppNotificationUtils";
import useWindowDimensions_native from "../../screen/useWindowDimensions.native";
import ReanimatedRexport, { useSharedValue, useAnimatedStyle, useDerivedValue } from "../../reanimated/ReanimatedRexport";
import { NativeChannelRowPreview } from "../../main_tabs_v2/native/shared_components/ChannelRowPreview";
import { RoleDot, Avatar, AvatarSizes } from "../../../design/void/native";
import { useInAppNotificationContext } from "./InAppNotificationContext";
import { triggerHapticFeedback, HapticFeedbackTypes } from "../../haptics/HapticUtils.native";
import { addReaction, ReactionLocations } from "../../reactions/ReactionActionCreators";
import { toReactionEmoji } from "../../reactions/ReactionUtils";
import { intl, t } from "../../../intl/index.native";
import { getUserAuthor, useNullableMessageAuthor } from "../../messages/useMessageAuthor";
import { useIsScreenReaderEnabled } from "../../a11y/native/useIsScreenReaderEnabled.native";
import MessageParser from "../../messages/MessageParser";
import { AccessibilityAnnouncer } from "../../../_bundle/Module3902";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import { transitionToMessage } from "../../routing/transitionToChannel";
import * as _MediaPreviewRightAccessory from "./MediaPreviewRightAccessory";
import { MediaPreviewRightAccessory } from "./MediaPreviewRightAccessory";
import * as _timing from "../../../design/animation/reanimated/timing/timing";
import { NotificationPressable } from "./Notification";
import { MessageNotificationReactBar } from "./MessageNotificationReactBar";
function $mk84317($env) {
return (a0) => {
const height = a0.nativeEvent.layout.height;
if (height > 0) {
$env[0].set(height);
}
};
}
let __initData, __initData2, Component, __initData3, Component2, __initData4, __initData5, __initData6, Component4, __initData7, __initData8, __initData9, __initData10;
const ACCESSORY_EXIT_THRESHOLD = 20;
const isAndroid = _PlatformUtils.isAndroid();
const PX_12 = Module712.space.PX_12;
const PX_8 = Module712.space.PX_8;
const useStyles = createStyles({
newContainerRoleDot: {
paddingRight: 4,
paddingTop: 0
},
initialPreviewOverlay: {
position: "absolute",
top: 0,
left: 0,
right: 0,
overflow: "hidden"
},
expandedPreviewOverlay: {
position: "absolute",
top: 0,
left: 0,
right: 0
}
});
let Component3 = Module19.memo(function(a0) {
return <MessagePreviewText message={a0.message} lineClamp={NOTIFICATION_PREVIEW_LINE_CLAMP} maxHeight={IN_APP_NOTIFICATION_MAX_HEIGHT} />;
});
__initData = {
code: "function MessageNotificationTsx1(){const{contentHeight,EXPANDED_MAX_HEIGHT,TRUNCATED_MESSAGE_HEIGHT_OFFSET,EXPANDED_SHORT_PREVIEW_PADDING}=this.__closure;const isGradientShown=contentHeight.get()>=EXPANDED_MAX_HEIGHT-TRUNCATED_MESSAGE_HEIGHT_OFFSET;const isShortPreview=contentHeight.get()>0&&!isGradientShown;return{paddingBottom:isShortPreview?EXPANDED_SHORT_PREVIEW_PADDING:0};}"
};
__initData2 = {
code: "function MessageNotificationTsx2(){const{IS_ANDROID,hasPreviewableMedia,hasTextContent,hasEmbedMedia,fadeProgress,ACCESSORY_EXIT_THRESHOLD}=this.__closure;if(IS_ANDROID&&hasPreviewableMedia&&hasTextContent&&!hasEmbedMedia){return{opacity:fadeProgress.get()};}if(!hasTextContent||hasEmbedMedia){return{opacity:fadeProgress.get(),transform:[{translateY:(1-fadeProgress.get())*ACCESSORY_EXIT_THRESHOLD}]};}return{opacity:1};}"
};
Component = Module19.memo(function({ message, expandedPreviewHeight, fadeProgress }) {
let hasPreviewableMedia, memo, c17830_4, c17830_5, sharedValue;
let env17831;
let env17832;
hasPreviewableMedia = void 0;
memo = void 0;
c17830_4 = void 0;
c17830_5 = void 0;
sharedValue = void 0;
const styles = useStyles();
const truncatedGradientColors = useTruncatedGradientColors();
const { gradientColors, gradientStyles } = truncatedGradientColors;
const stateFromStores = useStateFromStores([AccessibilityStore], () => AccessibilityStore.useReducedMotion);
hasPreviewableMedia = useHasPreviewableMedia(message);
memo = useMemo(() => message.embeds.some((embed) => embed.image != null || embed.thumbnail != null || embed.type === MessageEmbedTypes.GIFV), [message.embeds]);
const memo2 = useMemo(() => {
let r1 = hasPreviewableMedia;
if (!hasPreviewableMedia) {
r1 = message.poll != null;
}
if (!r1) {
r1 = memo;
}
return r1;
}, [hasPreviewableMedia, message.poll, memo]);
const hasTextContent = message.content.length > 0;
c17830_4 = hasTextContent;
const EXPANDED_MAX_HEIGHT = 0.24 * useWindowDimensions_native({
ignoreKeyboard: true
}).height;
c17830_5 = EXPANDED_MAX_HEIGHT;
const r52 = env17831 = {};
env17831[0] = expandedPreviewHeight;
const callback2 = useCallback($mk84317(r52), [expandedPreviewHeight]);
sharedValue = useSharedValue(0);
const r60 = env17832 = {};
env17832[0] = sharedValue;
const callback3 = useCallback($mk84317(r60), [sharedValue]);
const r68 = function h() {
const r9 = sharedValue.get() >= c17830_5 - PX_8;
return {
paddingBottom: sharedValue.get() > 0 ? r9 ? 0 : PX_12 : 0
};
};
r68.__closure = {
contentHeight: sharedValue,
EXPANDED_MAX_HEIGHT,
TRUNCATED_MESSAGE_HEIGHT_OFFSET: PX_8,
EXPANDED_SHORT_PREVIEW_PADDING: PX_12
};
r68.__workletHash = 4300216170219;
r68.__initData = __initData;
const animatedStyle = useAnimatedStyle(r68);
const r77 = function u() {
return isAndroid && (hasPreviewableMedia && (c17830_4 && !memo)) ? {
opacity: fadeProgress.get()
} : c17830_4 && !memo ? {
opacity: 1
} : {
opacity: fadeProgress.get(),
transform: [{
translateY: (1 - fadeProgress.get()) * ACCESSORY_EXIT_THRESHOLD
}]
};
};
r77.__closure = {
IS_ANDROID: isAndroid,
hasPreviewableMedia,
hasTextContent,
hasEmbedMedia: memo,
fadeProgress,
ACCESSORY_EXIT_THRESHOLD
};
r77.__workletHash = 9879198032662;
r77.__initData = __initData2;
const animatedStyle2 = useAnimatedStyle(r77);
return <ReanimatedRexport.View style={[styles.expandedPreviewOverlay, memo2 ? animatedStyle2 : null, animatedStyle]} onLayout={callback2}>
<View onLayout={callback3}>
<NativeChannelRowPreview message={message} lineClamp={memo2 ? 6 : void 0} maxHeight={EXPANDED_MAX_HEIGHT} gifAutoPlay={!stateFromStores} gradientStyles={gradientStyles} gradientColors={gradientColors} />
</View>
</ReanimatedRexport.View>;
});
__initData3 = {
code: "function MessageNotificationTsx3(){const{shouldHandlePreviewableMediaExpand,fadeProgress,accessoryWidthSV}=this.__closure;return shouldHandlePreviewableMediaExpand?{opacity:Math.max(0,1-fadeProgress.get()*2),right:accessoryWidthSV.get()}:{opacity:Math.max(0,1-fadeProgress.get()*2)};}"
};
Component2 = Module19.memo(function({ initialPreviewHeight: initialPreviewHeight2, fadeProgress: fadeProgress2, initialPreviewContent, accessoryWidthSV, shouldHandlePreviewableMediaExpand }) {
let env17834;
const styles = useStyles();
const r15 = env17834 = {};
env17834[0] = initialPreviewHeight2;
const callback2 = useCallback($mk84317(r15), [initialPreviewHeight2]);
const r23 = () => shouldHandlePreviewableMediaExpand ? {
opacity: Math.max(0, 1 - 2 * fadeProgress2.get()),
right: accessoryWidthSV.get()
} : {
opacity: Math.max(0, 1 - 2 * fadeProgress2.get())
};
r23.__closure = {
shouldHandlePreviewableMediaExpand,
fadeProgress: fadeProgress2,
accessoryWidthSV
};
r23.__workletHash = 15466459240148;
r23.__initData = __initData3;
return <ReanimatedRexport.View style={[styles.initialPreviewOverlay, useAnimatedStyle(r23)]}>
<View onLayout={callback2}>{initialPreviewContent}</View>
</ReanimatedRexport.View>;
});
__initData4 = {
code: "function MessageNotificationTsx4(){const{expandedPreviewHeight,EXPANDED_MAX_HEIGHT,expandedSV,notificationGestureY,initialPreviewHeight}=this.__closure;const maxExpandedHeight=Math.min(expandedPreviewHeight.get(),EXPANDED_MAX_HEIGHT);if(expandedSV.get()){return maxExpandedHeight;}const dragDistance=Math.max(0,notificationGestureY.get());const maxHeight=Math.max(maxExpandedHeight,initialPreviewHeight.get());return Math.min(initialPreviewHeight.get()+dragDistance,maxHeight);}"
};
__initData5 = {
code: "function MessageNotificationTsx5(){const{expandedSV,expandedPreviewHeight,EXPANDED_MAX_HEIGHT,initialPreviewHeight,notificationGestureY,ACCESSORY_EXIT_THRESHOLD,currentHeight}=this.__closure;if(expandedSV.get()){return 1;}const maxExpandedHeight=Math.min(expandedPreviewHeight.get(),EXPANDED_MAX_HEIGHT);const heightDifference=maxExpandedHeight-initialPreviewHeight.get();const dragDistance=Math.max(0,notificationGestureY.get());if(heightDifference<=0){return Math.min(1,dragDistance/ACCESSORY_EXIT_THRESHOLD);}return Math.min(1,(currentHeight.get()-initialPreviewHeight.get())/heightDifference);}"
};
__initData6 = {
code: "function MessageNotificationTsx6(){const{shouldHandlePreviewableMediaExpand,currentHeight,accessoryWidthSV}=this.__closure;return shouldHandlePreviewableMediaExpand?{overflow:'hidden',height:currentHeight.get(),marginRight:-accessoryWidthSV.get()}:{overflow:'hidden',height:currentHeight.get()};}"
};
Component4 = Module19.memo(function({ message: message3, expandedSV, notificationGestureY, initialPreviewContent, initialPreviewHeight, accessoryWidthSV: accessoryWidthSV2 }) {
let derivedValue;
derivedValue = void 0;
const EXPANDED_MAX_HEIGHT = 0.24 * useWindowDimensions_native({
ignoreKeyboard: true
}).height;
let c17835_4 = EXPANDED_MAX_HEIGHT;
const sharedValue2 = useSharedValue(EXPANDED_MAX_HEIGHT);
const hasPreviewableMedia4 = useHasPreviewableMedia(message3);
let r11 = isAndroid;
if (isAndroid) {
r11 = hasPreviewableMedia4;
}
const hasPreviewableMedia2 = r11;
const r36 = function h() {
const r10 = Math.min(sharedValue2.get(), c17835_4);
if (expandedSV.get()) {
return r10;
}
const r18 = Math.max(0, notificationGestureY.get());
const r24 = Math.max(r10, initialPreviewHeight.get());
return Math.min(initialPreviewHeight.get() + r18, r24);
};
r36.__closure = {
expandedPreviewHeight: sharedValue2,
EXPANDED_MAX_HEIGHT,
expandedSV,
notificationGestureY,
initialPreviewHeight
};
r36.__workletHash = 10745028098653;
r36.__initData = __initData4;
derivedValue = useDerivedValue(r36);
const r42 = function u() {
if (expandedSV.get()) {
return 1;
}
const r18 = Math.min(sharedValue2.get(), c17835_4) - initialPreviewHeight.get();
const r23 = Math.max(0, notificationGestureY.get());
return r18 <= 0 ? Math.min(1, r23 / ACCESSORY_EXIT_THRESHOLD) : Math.min(1, (derivedValue.get() - initialPreviewHeight.get()) / r18);
};
r42.__closure = {
expandedSV,
expandedPreviewHeight: sharedValue2,
EXPANDED_MAX_HEIGHT,
initialPreviewHeight,
notificationGestureY,
ACCESSORY_EXIT_THRESHOLD,
currentHeight: derivedValue
};
r42.__workletHash = 7693825745292;
r42.__initData = __initData5;
const derivedValue4 = useDerivedValue(r42);
const _ = () => hasPreviewableMedia2 ? {
overflow: "hidden",
height: derivedValue.get(),
marginRight: -accessoryWidthSV2.get()
} : {
overflow: "hidden",
height: derivedValue.get()
};
_.__closure = {
shouldHandlePreviewableMediaExpand: hasPreviewableMedia2,
currentHeight: derivedValue,
accessoryWidthSV: accessoryWidthSV2
};
_.__workletHash = 9399498954959;
_.__initData = __initData6;
return <ReanimatedRexport.View style={useAnimatedStyle(_)}>
<Component message={message3} expandedPreviewHeight={sharedValue2} fadeProgress={derivedValue4} />
<Component2 initialPreviewHeight={initialPreviewHeight} fadeProgress={derivedValue4} initialPreviewContent={initialPreviewContent} accessoryWidthSV={accessoryWidthSV2} shouldHandlePreviewableMediaExpand={hasPreviewableMedia2} />
</ReanimatedRexport.View>;
});
__initData7 = {
code: "function MessageNotificationTsx7(){const{isExpandableNotification,expandedSV,notificationGestureY,ACCESSORY_EXIT_THRESHOLD}=this.__closure;if(!isExpandableNotification){return 0;}if(expandedSV.get()){return 1;}const dragDistance=Math.max(0,notificationGestureY.get());return Math.min(1,dragDistance/ACCESSORY_EXIT_THRESHOLD);}"
};
__initData8 = {
code: "function MessageNotificationTsx8(){const{PREVIEW_SIZE,RIGHT_ACCESSORY_LEFT_MARGIN,accessoryExitProgressSV}=this.__closure;return(PREVIEW_SIZE+RIGHT_ACCESSORY_LEFT_MARGIN)*(1-accessoryExitProgressSV.get());}"
};
__initData9 = {
code: "function MessageNotificationTsx9(){const{isExpandableNotification,hasPreviewableMedia,accessoryWidthSV,PREVIEW_SIZE}=this.__closure;if(!isExpandableNotification||!hasPreviewableMedia){return{};}return{marginRight:accessoryWidthSV.get(),minHeight:PREVIEW_SIZE};}"
};
__initData10 = {
code: "function MessageNotificationTsx10(){const{withTiming,expandedSV,DEFAULT_ANIMATION_TIMING}=this.__closure;return{opacity:withTiming(expandedSV.get()?1:0,DEFAULT_ANIMATION_TIMING),maxHeight:withTiming(expandedSV.get()?60:0,DEFAULT_ANIMATION_TIMING)};}"
};
const r78 = Module19.memo(function MessageNotification(props) {
let isExpanded, expandedSV2, notificationGestureY2, handleDismissNotification, isExpandableNotification, callback, hasPreviewableMedia3, derivedValue2, derivedValue3;
const notification = props.notification;
isExpanded = void 0;
expandedSV2 = void 0;
notificationGestureY2 = void 0;
handleDismissNotification = void 0;
isExpandableNotification = void 0;
callback = void 0;
hasPreviewableMedia3 = void 0;
derivedValue2 = void 0;
derivedValue3 = void 0;
const styles = useStyles();
const { message: message2, channel, parentChannel, guild } = notification;
if (message2.content.length === 0 && message2.interaction !== null && message2.interaction !== void 0 && message2.activityInstance !== null && message2.activityInstance !== void 0) {
message2.content = intl.formatToPlainString(t["7eikg1"], {
username: getUserAuthor(message2.interaction?.user, channel).nick
});
}
const nullableMessageAuthor = useNullableMessageAuthor(message2);
const newContainerRoleDot = styles.newContainerRoleDot;
const stateFromStores = useStateFromStores([AccessibilityStore], () => AccessibilityStore.roleStyle);
let color = nullableMessageAuthor?.colorString;
if (color == null) {
color = void 0;
}
const accessoryLabelNode = stateFromStores === "dot" ? color !== void 0 ? <RoleDot color={color} colors={nullableMessageAuthor?.colorStrings} containerStyles={newContainerRoleDot} /> : void 0 : void 0;
const inAppNotificationContext = useInAppNotificationContext();
isExpanded = inAppNotificationContext.isExpanded;
expandedSV2 = inAppNotificationContext.expandedSV;
notificationGestureY2 = inAppNotificationContext.notificationGestureY;
handleDismissNotification = inAppNotificationContext.handleDismissNotification;
let isExpandableNotification2 = inAppNotificationContext.isExpandableNotification;
isExpandableNotification = isExpandableNotification2;
const showReactionBar = inAppNotificationContext.showReactionBar;
const inAppNotificationContext2 = useInAppNotificationContext();
const { setExpanded, setAutoDismissing, setActionTaken, isExpanded: isExpanded2, setConfirmation } = inAppNotificationContext2;
const callback2 = useCallback((a0, a1, a2) => {
triggerHapticFeedback(HapticFeedbackTypes.IMPACT_LIGHT);
addReaction(a0.channel.id, a0.message.id, toReactionEmoji(a1), ReactionLocations.IN_APP_NOTIFICATION, {
burst: a2
});
setActionTaken(true);
setExpanded(false);
setConfirmation({
type: "message",
reaction: a1,
message: intl.string(t.UjTvrz)
});
setAutoDismissing(true);
}, [setActionTaken, setExpanded, setAutoDismissing, setConfirmation]);
const accessibilityActions = isExpandableNotification ? [{
name: "expand_toggle",
label: intl.string(t["PbxI/x"])
}] : void 0;
callback = callback2;
const isScreenReaderEnabled = useIsScreenReaderEnabled();
useEffect(() => {
AccessibilityAnnouncer.announce(intl.formatToPlainString(t.Hjp1LH, {
userName: nullableMessageAuthor.nick,
message: MessageParser.unparse(message2.content, channel.id, true)
}));
}, [nullableMessageAuthor.nick, channel.id, message2.content]);
const callback3 = useCallback(() => {
ModalActionCreators.popAll();
transitionToMessage(channel.id, message2.id, {
navigationReplace: true
});
}, [channel.id, message2.id]);
const callback4 = useCallback(() => ModalActionCreators.pushLazy(import("../../../components_native/InAppNotificationSettingsModal"), {
channelId: channel.id
}, "in-app-notification-settings-modal"), [channel.id]);
hasPreviewableMedia3 = useHasPreviewableMedia(message2);
const sharedValue3 = useSharedValue(IN_APP_NOTIFICATION_MAX_HEIGHT);
const F = function F() {
if (isExpandableNotification) {
if (expandedSV2.get()) {
return 1;
}
return Math.min(1, Math.max(0, notificationGestureY2.get()) / ACCESSORY_EXIT_THRESHOLD);
}
return 0;
};
F.__closure = {
isExpandableNotification,
expandedSV: expandedSV2,
notificationGestureY: notificationGestureY2,
ACCESSORY_EXIT_THRESHOLD
};
F.__workletHash = 10189805207166;
F.__initData = __initData7;
derivedValue2 = useDerivedValue(F);
const k = () => (_MediaPreviewRightAccessory.PREVIEW_SIZE + RIGHT_ACCESSORY_LEFT_MARGIN) * (1 - derivedValue2.get());
k.__closure = {
PREVIEW_SIZE: _MediaPreviewRightAccessory.PREVIEW_SIZE,
RIGHT_ACCESSORY_LEFT_MARGIN,
accessoryExitProgressSV: derivedValue2
};
k.__workletHash = 12027019053130;
k.__initData = __initData8;
derivedValue3 = useDerivedValue(k);
const U = function U() {
return isExpandableNotification && hasPreviewableMedia3 ? {
marginRight: derivedValue3.get(),
minHeight: _MediaPreviewRightAccessory.PREVIEW_SIZE
} : {};
};
U.__closure = {
isExpandableNotification,
hasPreviewableMedia: hasPreviewableMedia3,
accessoryWidthSV: derivedValue3,
PREVIEW_SIZE: _MediaPreviewRightAccessory.PREVIEW_SIZE
};
U.__workletHash = 2118539495108;
U.__initData = __initData9;
const animatedStyle = useAnimatedStyle(U);
const memo2 = useMemo(() => ({
type: "message",
channel,
parentChannel,
guild,
author: nullableMessageAuthor,
expanded: isExpanded,
onDismiss: handleDismissNotification
}), [channel, parentChannel, guild, nullableMessageAuthor, isExpanded, handleDismissNotification]);
const initialPreviewContent = <Component3 message={message2} />;
const children = isExpandableNotification ? <Component4 message={message2} expandedSV={expandedSV2} notificationGestureY={notificationGestureY2} initialPreviewContent={initialPreviewContent} initialPreviewHeight={sharedValue3} accessoryWidthSV={derivedValue3} /> : initialPreviewContent;
const Z = function Z() {
return {
opacity: _timing.withTiming(expandedSV2.get() ? 1 : 0, DEFAULT_ANIMATION_TIMING),
maxHeight: _timing.withTiming(expandedSV2.get() ? 60 : 0, DEFAULT_ANIMATION_TIMING)
};
};
Z.__closure = {
withTiming: _timing.withTiming,
expandedSV: expandedSV2,
DEFAULT_ANIMATION_TIMING
};
Z.__workletHash = 2035414692485;
Z.__initData = __initData10;
const animatedStyle2 = useAnimatedStyle(Z);
const props2 = {
icon: <Avatar user={message2.author} guildId={notification.guild?.id} size={AvatarSizes.NORMAL} />,
accessoryLabelNode,
bodyStyle: animatedStyle,
rightAccessory: isExpandableNotification ? isExpanded ? null : <MediaPreviewRightAccessory message={message2} accessoryExitProgressSV={isExpandableNotification ? derivedValue2 : void 0} /> : <MediaPreviewRightAccessory message={message2} accessoryExitProgressSV={isExpandableNotification ? derivedValue2 : void 0} />,
children,
header: memo2,
showDragHandle: null,
onAccessibilityExpand: null,
expandedContentVisible: null,
notification: null,
onPress: null,
onSettingsPress: null,
accessibilityActions: null,
onAccessibilityAction: null,
expandableContent: null
};
if (isExpandableNotification) {
isExpandableNotification2 = isExpanded ? isScreenReaderEnabled : !isExpanded;
}
const onAccessibilityExpand = function onAccessibilityExpand() {
setExpanded(!isExpanded2, "accessibility_expand");
};
const onAccessibilityAction = function onAccessibilityAction(a0) {
if (a0.nativeEvent.actionName === "expand_toggle") {
setExpanded(!isExpanded2, "accessibility_expand");
}
};
props2.showDragHandle = isExpandableNotification2;
props2.onAccessibilityExpand = onAccessibilityExpand;
props2.expandedContentVisible = isExpanded;
props2.notification = notification;
props2.onPress = callback3;
props2.onSettingsPress = callback4;
props2.accessibilityActions = accessibilityActions;
props2.onAccessibilityAction = onAccessibilityAction;
props2.expandableContent = showReactionBar ? <MessageNotificationReactBar notification={notification} onReactionPress={(event, a1) => callback(notification, event, a1)} animationStyle={animatedStyle2} /> : void 0;
return <NotificationPressable {...props2} />;
});
export default r78;
@@ -0,0 +1,71 @@
// Metro module 10383 (f10384).
import { useCallback } from "react";
import { Keyboard } from "react-native";
import { DEFAULT_ANIMATION_TIMING } from "./InAppNotificationConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { useInAppNotificationContext } from "./InAppNotificationContext";
import { intl, t } from "../../../intl/index.native";
import useAnimatedKeyboardHeight from "../../keyboard/native/useAnimatedKeyboardHeight";
import useSafeAreaInsets_native from "../../safe_area/useSafeAreaInsets.native";
import ReanimatedRexport, { useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
import * as _timing from "../../../design/animation/reanimated/timing/timing";
import { ConfirmationToast } from "./ConfirmationToast";
import { MessageReplyInput } from "./MessageReplyInput";
const useStyles = createStyles({
expandFooterContainer: {
position: "absolute",
left: 0,
right: 0
}
});
const __initData = {
code: "function MessageNotificationDetachedContentTsx1(){const{withTiming,expandedSV,DEFAULT_ANIMATION_TIMING,keyboardHeight,safeAreaBottom}=this.__closure;return{opacity:withTiming(expandedSV.get()?1:0,DEFAULT_ANIMATION_TIMING),transform:[{scale:withTiming(expandedSV.get()?1:0.8,DEFAULT_ANIMATION_TIMING)}],bottom:4+Math.max(keyboardHeight.get(),safeAreaBottom)};}"
};
export function MessageNotificationDetachedContent(props) {
let c17915_5, bottom;
const notification = props.notification;
c17915_5 = void 0;
bottom = void 0;
const styles = useStyles();
const inAppNotificationContext = useInAppNotificationContext();
const { isExpanded, expandedSV, showReplyInput, setActionTaken, setExpanded, setAutoDismissing, confirmation, setConfirmation } = inAppNotificationContext;
const callback = useCallback(() => {
Keyboard.dismiss();
setActionTaken(true);
setExpanded(false);
setAutoDismissing(true);
setConfirmation({
type: "message",
reaction: null,
message: intl.string(t["b/4dOF"])
});
}, [setActionTaken, setExpanded, setAutoDismissing, setConfirmation]);
const animatedKeyboardHeight = useAnimatedKeyboardHeight();
c17915_5 = animatedKeyboardHeight;
bottom = useSafeAreaInsets_native().bottom;
const _ = function _() {
return {
opacity: _timing.withTiming(expandedSV.get() ? 1 : 0, DEFAULT_ANIMATION_TIMING),
transform: [{
scale: _timing.withTiming(expandedSV.get() ? 1 : 0.8, DEFAULT_ANIMATION_TIMING)
}],
bottom: 4 + Math.max(c17915_5.get(), bottom)
};
};
_.__closure = {
withTiming: _timing.withTiming,
expandedSV,
DEFAULT_ANIMATION_TIMING,
keyboardHeight: animatedKeyboardHeight,
safeAreaBottom: bottom
};
_.__workletHash = 1331449062174;
_.__initData = __initData;
const animatedStyle = useAnimatedStyle(_);
return <>
{confirmation != null ? <ConfirmationToast message={confirmation.message} reaction={confirmation.reaction} /> : null}
{isExpanded ? showReplyInput ? <ReanimatedRexport.View style={[styles.expandFooterContainer, animatedStyle]}>
<MessageReplyInput notification={notification} onMessageSent={callback} />
</ReanimatedRexport.View> : null : null}
</>;
}
@@ -0,0 +1,140 @@
// Metro module 10337 (f10338).
import { useMemo } from "react";
import { View } from "react-native";
import AccessibilityStore from "../../a11y/AccessibilityStore";
import RelationshipStore from "../../../stores/RelationshipStore";
import UserStore from "../../../stores/UserStore";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { Text } from "../../../design/components/Text/native/Text";
import { computeChannelName } from "../../channel/useChannelName";
import { ChannelTypesSets, ChannelTypes } from "../../../_bundle/Module692";
import { ChatIcon } from "../../../design/components/Icon/native/redesign/generated/ChatIcon";
import { ThreadIcon } from "../../../design/components/Icon/native/redesign/generated/ThreadIcon";
import { getSimpleChannelIconComponent } from "../../../utils/native/ChannelUtils";
import { useStateFromStores } from "../../../_bundle/Module589";
import { PressableOpacity } from "../../../design/void/Pressables/native/Pressables";
import { intl, t } from "../../../intl/index.native";
import { XSmallIcon } from "../../../design/components/Icon/native/redesign/generated/XSmallIcon";
let androidRippleConfig, hitSlop, useStyles;
const LocationText = function LocationText(props) {
const { channel, parentChannel, author, location: location2 } = props;
let color2 = props.color;
const styles = useStyles();
if (color2 == null) {
color2 = "text-muted";
}
const color = color2;
return <View style={styles.secondaryTextContainer}>
{author != null && <Text variant="text-md/bold" color={color} maxFontSizeMultiplier={1.75} style={styles.separator}>·</Text>}
{useMemo(() => {
const Component = ChannelTypesSets.PRIVATE_CHANNEL.has(channel.type) ? void 0 : channel.type === ChannelTypes.PUBLIC_THREAD ? parentChannel != null && parentChannel.type === ChannelTypes.GUILD_FORUM ? ChatIcon : ThreadIcon : getSimpleChannelIconComponent(channel);
return Component != null ? <Component color={color} style={styles.icon} /> : null;
}, [channel, parentChannel, styles.icon, color])}
<Text variant="text-md/semibold" color={color} lineClamp={1} style={styles.secondaryText}>{location2}</Text>
</View>;
};
androidRippleConfig = Object.freeze({
radius: 12
});
hitSlop = Object.freeze({
top: 8,
right: 8,
bottom: 8,
left: 8
});
useStyles = createStyles({
container: {
flexDirection: "row",
alignItems: "center",
gap: Module712.space.PX_8
},
headerContent: {
flex: 1,
flexDirection: "row",
alignItems: "center"
},
primaryText: {
flexShrink: 1,
marginRight: 2
},
secondaryTextContainer: {
flexDirection: "row",
alignItems: "center",
gap: 2,
flex: 1,
overflow: "hidden"
},
separator: {
marginHorizontal: 2
},
icon: {
width: 16,
height: 16
},
secondaryText: {
flex: 1
}
});
export default function MessageNotificationHeader(props) {
let location2;
const { channel: channel2, parentChannel: parentChannel2, guild, author } = props;
let expanded = props.expanded;
const { onDismiss, locationTextColor } = props;
const styles2 = useStyles();
const stateFromStores = useStateFromStores([AccessibilityStore], () => AccessibilityStore.roleStyle);
const colorString = author?.colorString;
const color2 = stateFromStores === "username" ? colorString : void 0;
const r23 = color2 != null ? {
color: color2
} : void 0;
L24: {
const r10 = computeChannelName(channel2, UserStore, RelationshipStore);
const type = channel2.type;
const GROUP_DM = ChannelTypes.GROUP_DM;
location2 = r10;
if (GROUP_DM !== type) {
if (ChannelTypes.GUILD_FORUM !== type && ChannelTypes.GUILD_TEXT !== type && ChannelTypes.GUILD_ANNOUNCEMENT !== type) {
if (ChannelTypes.ANNOUNCEMENT_THREAD !== type && ChannelTypes.PUBLIC_THREAD !== type) {
const PRIVATE_THREAD = ChannelTypes.PRIVATE_THREAD;
location2 = null;
if (PRIVATE_THREAD !== type) {
break L24;
}
}
const r15 = parentChannel2 != null ? computeChannelName(parentChannel2, UserStore, RelationshipStore) : null;
location2 = r15 != null ? `${r10}, ${r15}` : guild != null ? `${r10}, ${guild.name}` : r10;
break L24;
}
location2 = guild != null ? `${r10}, ${guild.name}` : null;
}
}
const r112 = [<View style={styles2.headerContent}>
{author != null && <Text variant="text-md/semibold" color="mobile-text-heading-primary" lineClamp={1} style={[styles2.primaryText, r23]}>{author.nick}</Text>}
{location2 != null && <LocationText location={location2} channel={channel2} parentChannel={parentChannel2} author={author} color={locationTextColor} />}
</View>, ,];
if (expanded) {
expanded = onDismiss != null;
}
if (expanded) {
expanded = <PressableOpacity accessibilityRole="button" accessibilityLabel={intl.string(t.LnEgqX)} hitSlop={hitSlop} androidRippleConfig={androidRippleConfig} onPress={() => onDismiss("close_from_expanded")}>
<XSmallIcon color="icon-subtle" style={{
height: 20,
width: 20
}} />
</PressableOpacity>;
}
r112[1] = expanded;
return <View style={styles2.container}>{r112}</View>;
};
export function SimpleNotificationHeader(props) {
const { text, secondaryText, labelStyle } = props;
const styles2 = useStyles();
return <View style={styles2.container}>
<Text variant="text-md/semibold" color="mobile-text-heading-primary" lineClamp={1} style={[styles2.primaryText, labelStyle]}>{text}</Text>
{secondaryText != null && <View style={styles2.secondaryTextContainer}>
<Text variant="text-md/bold" color="text-muted" maxFontSizeMultiplier={1.75} style={styles2.separator}>·</Text>
<Text variant="text-md/semibold" color="text-muted" lineClamp={1} style={styles2.secondaryText}>{secondaryText}</Text>
</View>}
</View>;
}
@@ -0,0 +1,78 @@
// Metro module 10339 (f10340).
import { useMemo, useCallback } from "react";
import { Keyboard, View } from "react-native";
import { NOTIFICATION_CONTAINER_MARGIN, NOTIFICATION_MAX_WIDTH } from "./InAppNotificationConstants";
import { EmojiPickerSource } from "../../emoji_picker/native/components/EmojiPickerListConstants";
import { EmojiIntention } from "../../emojis/EmojiConstants";
import Module712 from "../../../_bundle/Module712";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import useWindowDimensions_native from "../../screen/useWindowDimensions.native";
import { useEmojisForReactionRow } from "../../reactions/native/useEmojisForReactionRow";
import { trackInAppNotificationAccessoryClicked } from "./InAppNotificationUtils";
import { InAppNotificationAccessoryTypes } from "../InAppNotificationTypes";
import { openEmojiPickerActionSheet } from "../../emoji_picker/native/openEmojiPickerActionSheet";
import { ReactionTypes } from "../../messages/MessageReactionsTypes";
import { ReactionLocations } from "../../reactions/ReactionActionCreators";
import ReanimatedRexport from "../../reanimated/ReanimatedRexport";
import { EmojiReactionRowButton, getEmojiKey, EmojiPickerRowButton } from "../../reactions/native/EmojiReactionRowButton";
const PX_12 = Module712.space.PX_12;
const useStyles = createStyles({
container: {
alignSelf: "center",
flexDirection: "row",
gap: 8,
alignItems: "center",
justifyContent: "space-between",
paddingHorizontal: PX_12,
paddingVertical: 10,
width: "100%"
},
divider: {
height: 1,
backgroundColor: Module712.colors.BORDER_SUBTLE,
margin: 0,
padding: 0
},
roundButton: {
borderRadius: Module712.radii.round
}
});
export function MessageNotificationReactBar(props) {
let callback;
const { notification, onReactionPress, animationStyle } = props;
callback = void 0;
const styles = useStyles();
const width = useWindowDimensions_native().width;
const emojisForReactionRow = useEmojisForReactionRow(notification.channel, useMemo(() => {
const r1 = 2 * PX_12;
return Math.min(NOTIFICATION_MAX_WIDTH - r1, width - r1 - 2 * NOTIFICATION_CONTAINER_MARGIN);
}, [width]), 48);
const callback2 = useCallback(() => {
Keyboard.dismiss();
trackInAppNotificationAccessoryClicked(notification, InAppNotificationAccessoryTypes.REACTION_PICKER_BUTTON);
openEmojiPickerActionSheet({
onPressEmoji: onReactionPress,
channel: notification.channel,
pickerIntention: EmojiIntention.REACTION,
reactionType: ReactionTypes.NORMAL,
analyticsObject: ReactionLocations.IN_APP_NOTIFICATION,
startExpanded: false,
source: EmojiPickerSource.NOTIFICATION
});
}, [onReactionPress, notification]);
callback = useCallback((a0) => {
trackInAppNotificationAccessoryClicked(notification, InAppNotificationAccessoryTypes.REACTION_BUTTON);
if (a0 != null) {
onReactionPress(a0);
}
}, [notification, onReactionPress]);
return <ReanimatedRexport.View style={animationStyle}>
<View style={styles.divider} />
<View style={styles.container}>
{emojisForReactionRow.map((item, index) => {
return <EmojiReactionRowButton key={getEmojiKey(item, index)} emoji={item == null ? null : item} onPress={() => callback(item)} emojiSize={20} emojiFontSize={16} emojiContainerSize={40} emojiLineHeight={22} styles={styles.roundButton} />;
})}
<EmojiPickerRowButton emojiContainerSize={40} onPress={callback2} iconSize="sm" styles={styles.roundButton} />
</View>
</ReanimatedRexport.View>;
}
@@ -0,0 +1,173 @@
// Metro module 10279 (f10280).
import { useMemo } from "react";
import { View } from "react-native";
import ChannelStore from "../../../stores/ChannelStore";
import { IN_APP_NOTIFICATION_MAX_HEIGHT, NOTIFICATION_PREVIEW_LINE_CLAMP } from "./InAppNotificationConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { isIOS } from "../../../_bundle/Module501";
import Module712 from "../../../_bundle/Module712";
import useTruncatedGradientColors from "./hooks/useTruncatedGradientColors";
import { NativeChannelRowPreview, ChannelRowPreview } from "../../main_tabs_v2/native/shared_components/ChannelRowPreview";
import { getMessagePreviewTextVariant } from "./InAppNotificationUtils";
import { Text } from "../../../design/components/Text/native/Text";
import FastImage from "../../../components_native/common/FastImage";
import { usePreviewableMedia, PreviewableMediaTypes } from "./hooks/usePreviewableMedia";
import { useNullableMessageAuthor } from "../../messages/useMessageAuthor";
import { usePreviewableMediaText } from "./hooks/usePreviewableMediaText";
import { useGetInitialMessagePreview } from "./hooks/useGetInitialMessagePreview";
import { MessageEmbedTypes } from "../../../_bundle/Module693";
import isForwardMessage from "../../forwarding/isForwardMessage";
import { intl, t } from "../../../intl/index.native";
import { ChannelListLayoutTypes } from "../../main_tabs_v2/ChannelListLayoutTypes";
let useStyles, useStyles2, SystemMessageText, EmbedMediaThumbnail, EmbedCard;
const NativeMessagePreviewContent = function NativeMessagePreviewContent(props) {
const { message: message2, lineClamp, maxHeight } = props;
const truncatedGradientColors = useTruncatedGradientColors();
return <View>
<NativeChannelRowPreview message={message2} lineClamp={lineClamp} maxHeight={maxHeight} gradientStyles={truncatedGradientColors.gradientStyles} gradientColors={truncatedGradientColors.gradientColors} />
</View>;
};
SystemMessageText = function SystemMessageText(props) {
const text = props.text;
const styles = useStyles();
return <Text variant={getMessagePreviewTextVariant()} color="text-subtle" style={styles.italic} lineClamp={NOTIFICATION_PREVIEW_LINE_CLAMP}>{text}</Text>;
};
EmbedMediaThumbnail = function EmbedMediaThumbnail(props) {
const media = props.media;
const styles2 = useStyles2();
let proxyURL = media.proxyURL;
if (proxyURL == null) {
proxyURL = media.url;
}
const r16 = media.width / media.height;
return <View style={[styles2.embedMediaContainer, {
aspectRatio: Number.isFinite(r16) ? r16 > 0 ? r16 : 1 : 1
}]}>
<FastImage source={{
uri: proxyURL
}} style={styles2.embedMedia} resizeMode="contain" />
</View>;
};
EmbedCard = function EmbedCard(props) {
const embed = props.embed;
const styles2 = useStyles2();
const name2 = embed.provider?.name;
const name = embed.author?.name;
const rawTitle = embed.rawTitle;
let thumbnail = embed.thumbnail;
if (thumbnail == null) {
thumbnail = embed.image;
}
const backgroundColor = embed.color != null ? embed.color.toLowerCase() !== "#ffffff" ? embed.color : void 0 : void 0;
const r34 = [backgroundColor != null && <View style={[styles2.embedAccentBar, {
backgroundColor
}]} />, <View style={styles2.embedTextContainer}>
{name2 != null && <Text variant="text-xxs/normal" color="text-subtle" lineClamp={1}>{name2}</Text>}
{name != null && <Text variant="text-xs/medium" color="text-default" lineClamp={1}>{name}</Text>}
{rawTitle != null && <Text variant="text-xs/medium" color="text-link" lineClamp={name2 == null ? name == null ? 3 : 1 : 1}>{rawTitle}</Text>}
{embed.rawDescription != null && <Text variant="text-xs/medium" color="text-default" lineClamp={3}>{embed.rawDescription}</Text>}
</View>, thumbnail != null && <EmbedMediaThumbnail media={thumbnail} />];
return <View style={styles2.embedContainer}>{r34}</View>;
};
useStyles = createStyles({
italic: {
fontStyle: "italic",
fontFamily: isIOS() ? "ggsans-NormalItalic, NotoSans-NormalItalic" : "ggsans-MediumItalic, NotoSans-MediumItalic"
}
});
useStyles2 = createStyles({
embedContainer: {
borderRadius: Module712.radii.sm,
paddingTop: Module712.space.PX_8,
paddingBottom: Module712.space.PX_8,
paddingRight: Module712.space.PX_8,
backgroundColor: Module712.colors.BACKGROUND_MOD_SUBTLE,
flexDirection: "row",
overflow: "hidden"
},
embedAccentBar: {
width: 4,
marginTop: -Module712.space.PX_8,
marginBottom: -Module712.space.PX_8,
alignSelf: "stretch"
},
embedTextContainer: {
flex: 1,
gap: Module712.space.PX_4,
paddingVertical: Module712.space.PX_4,
paddingHorizontal: Module712.space.PX_8
},
embedMediaContainer: {
borderRadius: Module712.radii.xs,
overflow: "hidden",
height: 60,
width: void 0
},
embedMedia: {
width: "100%",
height: "100%"
}
});
export default function MessagePreviewText(props) {
const { message, lineClamp, maxHeight, showMessageAuthor = false } = props;
const previewableMedia = usePreviewableMedia(message);
const nullableMessageAuthor = useNullableMessageAuthor(showMessageAuthor ? message : null);
const previewableMediaText = usePreviewableMediaText({
previewableMedia,
author: nullableMessageAuthor
});
const { text: text2, secondaryText } = previewableMediaText;
const getInitialMessagePreview = useGetInitialMessagePreview({
message
});
const memo = useMemo(() => message.embeds.filter((embed) => embed.image != null || embed.thumbnail != null), [message.embeds]);
if (memo.length > 0) {
const embed = memo[0];
return embed.type === MessageEmbedTypes.GIFV && text2 != null ? <SystemMessageText text={text2} /> : <View>
<NativeMessagePreviewContent message={getInitialMessagePreview} lineClamp={NOTIFICATION_PREVIEW_LINE_CLAMP} maxHeight={IN_APP_NOTIFICATION_MAX_HEIGHT} />
<EmbedCard embed={embed} />
</View>;
}
if (isForwardMessage(message)) {
const r2 = message.messageSnapshots.length > 0 && message.messageSnapshots[0].message.content.length > 0;
const r3 = previewableMedia.length > 0 && previewableMedia[0].type === PreviewableMediaTypes.GIF;
L29: {
if (previewableMedia.length > 0) {
if (r2 && !r3) {
break L29;
}
return <SystemMessageText text={nullableMessageAuthor != null ? intl.format(t.sLDHDi, {
username: nullableMessageAuthor.nick
}) : intl.string(t["9ddYKt"])} />;
}
}
return <NativeMessagePreviewContent message={getInitialMessagePreview} lineClamp={lineClamp} maxHeight={maxHeight} />;
}
if (message.content.length > 0) {
if (nullableMessageAuthor != null) {
const channel = ChannelStore.getChannel(message.channel_id);
const messagePreviewTextVariant = getMessagePreviewTextVariant();
if (channel != null) {
return <ChannelRowPreview channel={channel} message={message} color="text-default" layout={ChannelListLayoutTypes.COZY} variant={messagePreviewTextVariant} muted={false} lineClamp={lineClamp} />;
}
}
return <NativeMessagePreviewContent message={getInitialMessagePreview} lineClamp={lineClamp} maxHeight={maxHeight} />;
}
if (previewableMedia.length > 0 && text2 !== null) {
return <View>
<SystemMessageText text={text2} />
{secondaryText !== null && <Text variant="redesign/message-preview/medium" color="text-link" lineClamp={NOTIFICATION_PREVIEW_LINE_CLAMP}>{secondaryText}</Text>}
</View>;
}
if (message.poll != null) {
const text = message.poll.question.text;
return <View>
<SystemMessageText text={nullableMessageAuthor != null ? intl.format(t["1wtRlq"], {
username: nullableMessageAuthor.nick
}) : intl.string(t.n3shVJ)} />
<Text variant="redesign/message-preview/medium" color="text-default" lineClamp={NOTIFICATION_PREVIEW_LINE_CLAMP}>{text}</Text>
</View>;
}
return <NativeMessagePreviewContent message={message} lineClamp={lineClamp} maxHeight={maxHeight} />;
};
export { SystemMessageText };
@@ -0,0 +1,264 @@
// Metro module 10388 (f10389).
import _slicedToArray from "../../../_bundle/_slicedToArray";
import { useEffect, useRef, useState, useMemo, useLayoutEffect, useCallback } from "react";
import { StyleSheet, Keyboard, View } from "react-native";
import ChannelStore from "../../../stores/ChannelStore";
import { EmojiIntention } from "../../emojis/EmojiConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useMobileVisualRefreshConfig } from "../../themes/experiments/MobileVisualRefreshExperiment";
import * as _ReanimatedRexport from "../../reanimated/ReanimatedRexport";
import ReanimatedRexport, { useSharedValue, useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
import { withTiming } from "../../../design/animation/reanimated/timing/timing";
import { ChatInputReplyBar } from "../../chat_input/native/ChatInputContextBar";
import { useNullableMessageAuthor } from "../../messages/useMessageAuthor";
import useChannelName from "../../channel/useChannelName";
import { useInputStyles } from "../../../design/components/Input/native/InputFieldContainer.native";
import { trackInAppNotificationAccessoryClicked } from "./InAppNotificationUtils";
import { InAppNotificationAccessoryTypes } from "../InAppNotificationTypes";
import { triggerHapticFeedback, HapticFeedbackTypes } from "../../haptics/HapticUtils.native";
import MessageParser from "../../messages/MessageParser";
import MessageActionCreators from "../../../actions/MessageActionCreators";
import { openEmojiPickerActionSheet } from "../../emoji_picker/native/openEmojiPickerActionSheet";
import getEmojiText from "../../emojis/utils/getEmojiText";
import { IconButton } from "../../../design/components/Button/native/IconButton.native";
import { ArrowAngleLeftUpIcon } from "../../../design/components/Icon/native/redesign/generated/ArrowAngleLeftUpIcon";
import { intl, t } from "../../../intl/index.native";
import { NativeTextInput } from "../../../design/components/Input/native/NativeTextInput.native";
import { ReactionIcon } from "../../../design/components/Icon/native/redesign/generated/ReactionIcon";
import { SendMessageIcon } from "../../../design/components/Icon/native/redesign/generated/SendMessageIcon";
let useStyles, c6955_13;
let env6955 = {};
const AnimatedChatInputReplyBar = function AnimatedChatInputReplyBar(props) {
const { replying, pendingReply, pendingReplyAuthor, onToggleReplyMention: onToggleReplyMention2 } = props;
const chatInputFloating = useMobileVisualRefreshConfig({
location: "MessageReplyInput"
}).chatInputFloating;
const styles = useStyles();
const sharedValue = useSharedValue(0);
useEffect(() => {
const r12 = {
duration: 150
};
if (replying) {
sharedValue.set(withTiming(1, r12));
} else {
sharedValue.set(withTiming(0, r12));
}
}, [replying, sharedValue]);
const y = () => ({
height: _ReanimatedRexport.interpolate(sharedValue.get(), [0, 1], [0, 40]),
opacity: sharedValue.get()
});
y.__closure = {
interpolate: _ReanimatedRexport.interpolate,
sv: sharedValue,
REPLY_BAR_HEIGHT: 40
};
y.__workletHash = 878601267127;
y.__initData = c6955_13;
return <ReanimatedRexport.View style={[styles.replyBarContainer, chatInputFloating ? styles.replyBarRedesign : styles.replyBarNoRedesign, useAnimatedStyle(y)]}>
<ChatInputReplyBar pendingReply={pendingReply} pendingReplyAuthor={pendingReplyAuthor} onToggleReplyMention={onToggleReplyMention2} chatInputFloatingOverride />
</ReanimatedRexport.View>;
};
useStyles = createStyles({
inputContainer: {
flexDirection: "column",
gap: 0,
backgroundColor: Module712.colors.MOBILE_ALERT_BACKGROUND_DEFAULT,
padding: 0,
marginHorizontal: Module712.space.PX_16,
marginBottom: Module712.space.PX_4,
borderRadius: Module712.radii.lg,
overflow: "hidden"
},
iconsContainer: {
flexDirection: "row",
alignItems: "center",
gap: 4
},
input: {
flex: 1,
borderRadius: Module712.radii.none,
border: 0,
color: Module712.colors.TEXT_DEFAULT
},
inputRow: {
flexDirection: "row",
alignItems: "center",
gap: 8,
paddingHorizontal: Module712.space.PX_12,
paddingVertical: Module712.space.PX_12
},
placeholderText: {
color: Module712.colors.INPUT_PLACEHOLDER_TEXT_DEFAULT
},
replyBarContainer: {
justifyContent: "center",
alignContent: "center",
backgroundColor: Module712.colors.BACKGROUND_MOD_STRONG,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: Module712.colors.BORDER_MUTED,
overflow: "hidden"
},
replyBarNoRedesign: {
paddingLeft: Module712.space.PX_12,
paddingRight: Module712.space.PX_8
},
replyBarRedesign: {
paddingLeft: Module712.space.PX_4
}
});
c6955_13 = {
code: "function MessageReplyInputTsx1(){const{interpolate,sv,REPLY_BAR_HEIGHT}=this.__closure;return{height:interpolate(sv.get(),[0,1],[0,REPLY_BAR_HEIGHT]),opacity:sv.get()};}"
};
export function MessageReplyInput(props) {
let c17919_0;
let env17918 = {
$parent: env6955
};
const notification = props.notification;
env17918[0] = notification;
const onMessageSent = props.onMessageSent;
env17918[1] = onMessageSent;
env17918[2] = void 0;
env17918[3] = void 0;
env17918[4] = void 0;
env17918[5] = void 0;
env17918[6] = void 0;
env17918[7] = void 0;
env17918[8] = void 0;
env17918[9] = void 0;
env17918[10] = void 0;
env17918[11] = void 0;
env17918[12] = void 0;
env17918[13] = void 0;
env17918[14] = void 0;
const ref = useRef(null);
env17918[2] = ref;
const r31 = _slicedToArray(useState(""), 2);
const value = r31[0];
env17918[3] = value;
const onChangeText = r31[1];
env17918[4] = onChangeText;
const r34 = _slicedToArray(useState(false), 2);
const loading = r34[0];
env17918[5] = loading;
env17918[6] = r34[1];
const r38 = _slicedToArray(useState(false), 2);
const replying2 = r38[0];
env17918[7] = replying2;
env17918[8] = r38[1];
const r43 = _slicedToArray(useState(true), 2);
const r24 = r43[0];
env17918[9] = r24;
env17918[10] = r43[1];
const styles = useStyles();
const message = notification.message;
env17918[11] = message;
const channel = notification.channel;
env17918[12] = channel;
const nullableMessageAuthor = useNullableMessageAuthor(message);
const channelName = useChannelName(channel, true);
const styles2 = useInputStyles({});
const memo = useMemo(() => {
const channel = env17918[12];
return {
shouldMention: env17918[9],
showMentionToggle: !channel.isPrivate(),
channel,
message: env17918[11]
};
}, [r24, channel, message]);
env17918[13] = memo;
useLayoutEffect(() => {
const current = env17918[2].current;
if (current != null) {
current.focus();
}
}, []);
c17919_0 = void 0;
c17919_0 = async (c30217_0) => {
let c30217_1;
L18: {
L17: {
c30217_1 = void 0;
if (env17918[5] === true) {
break L18;
}
const id = c30217_0.channel.id;
const r12 = env17918[3];
if (r12.length === 0) {
break L18;
}
if (id != null) {
trackInAppNotificationAccessoryClicked(c30217_0, InAppNotificationAccessoryTypes.SEND_MESSAGE_BUTTON);
(0, env17918[6])(true);
triggerHapticFeedback(HapticFeedbackTypes.IMPACT_MEDIUM);
await MessageActionCreators.sendMessage(id, MessageParser.parse(ChannelStore.getChannel(id), r12), false, {
...env17918[7] ? MessageActionCreators.getSendMessageOptionsForReply(env17918[13]) : {},
location: "InAppNotification"
});
(0, env17918[1])();
(0, env17918[6])(false);
(0, env17918[4])("");
break L17;
}
break L18;
}
return void 0;
}
};
env17918[14] = useCallback(function() {
return c17919_0.apply(this, arguments);
}, [value, onMessageSent, memo, replying2, loading]);
const r73 = [notification.channel, ,];
const id = notification.guild?.id;
const r77 = () => {
Keyboard.dismiss();
const r16 = {
onPressEmoji: (a0) => {
let c30218_0 = getEmojiText(a0);
(0, env17918[4])((a0) => `${a0} ${c30218_0}`);
const current = env17918[2].current;
if (current != null) {
current.focus();
}
},
pickerIntention: EmojiIntention.CHAT,
channel: null,
guildId: null,
startExpanded: false
};
const r17 = env17918[0];
let channel = r17.channel;
if (channel == null) {
channel = void 0;
}
r16.channel = channel;
let guildId = r17.guild?.id;
if (guildId == null) {
guildId = void 0;
}
r16.guildId = guildId;
openEmojiPickerActionSheet(r16);
};
r73[1] = id;
const callback = useCallback(r77, r73);
return <View style={styles.inputContainer}>
<AnimatedChatInputReplyBar replying={replying2} pendingReply={memo} pendingReplyAuthor={nullableMessageAuthor} onToggleReplyMention={() => (0, env17918[10])(!env17918[9])} />
<View style={styles.inputRow}>
<IconButton variant={replying2 ? "secondary" : "icon-only"} size="sm" icon={<ArrowAngleLeftUpIcon size="sm" color={Module712.colors.CHAT_INPUT_ICON_DEFAULT_TINT} />} onPress={() => {
trackInAppNotificationAccessoryClicked(env17918[0], InAppNotificationAccessoryTypes.REPLY_TOGGLE);
(0, env17918[8])(!env17918[7]);
}} accessibilityLabel={intl.string(t["5IEsGx"])} />
<NativeTextInput ref={ref} style={[styles.input, styles2.text]} placeholderTextColor={styles.placeholderText.color} placeholder={intl.formatToPlainString(t["8lzR/R"], {
channel: channelName
})} autoFocus value={value} onChangeText={onChangeText} />
<View style={styles.iconsContainer}>
<IconButton variant="icon-only" size="sm" icon={<ReactionIcon size="sm" color={Module712.colors.CHAT_INPUT_ICON_DEFAULT_TINT} />} onPress={callback} accessibilityLabel={intl.string(t.sMOuuS)} />
<IconButton variant="primary" size="sm" accessibilityLabel={intl.string(t.TXNS7S)} icon={<SendMessageIcon size="sm" color={Module712.colors.WHITE} />} onPress={() => (0, env17918[14])(env17918[0])} loading={loading} />
</View>
</View>
</View>;
}
@@ -0,0 +1,27 @@
// Metro module 10382 (f10383).
import { useMemo, useCallback } from "react";
import { intl, t } from "../../../intl/index.native";
import InAppNotificationActionCreators from "../../../actions/native/InAppNotificationActionCreators";
import { getRootNavigationRef } from "../../main_tabs_v2/RootNavigationRef.native";
import { NotificationPressable } from "./Notification";
import { Avatar, AvatarSizes } from "../../../design/void/native";
import { SystemMessageText } from "./MessagePreviewText";
export default function MessageRequestInAppNotification(props) {
const notification = props.notification;
const { author, numMutualGuilds } = notification;
return <NotificationPressable icon={<Avatar user={author} size={AvatarSizes.NORMAL} guildId={void 0} />} header={useMemo(() => ({
type: "simple",
text: intl.formatToPlainString(t.LeYU4d, {
name: author.username,
count: numMutualGuilds
})
}), [author.username, numMutualGuilds])} onPress={useCallback(() => {
InAppNotificationActionCreators.clearNotification();
const rootNavigationRef = getRootNavigationRef();
if (rootNavigationRef != null) {
rootNavigationRef.navigate("message-requests");
}
}, [])} notification={notification}>
<SystemMessageText text={intl.string(t["Bx4/Lf"])} />
</NotificationPressable>;
};
@@ -0,0 +1,194 @@
// Metro module 10334 (f10335).
import { useMemo, useCallback, useEffect } from "react";
import { MIN_SWIPE_VELOCITY, STARTED_SWIPE_THRESHOLD, NOTIFICATION_MAX_WIDTH } from "./InAppNotificationConstants";
import { AnalyticEvents } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { extractMetadataFromNotification } from "./InAppNotificationUtils";
import { useInAppNotificationContext } from "./InAppNotificationContext";
import * as _ReanimatedRexport from "../../reanimated/ReanimatedRexport";
import ReanimatedRexport, { useSharedValue, useAnimatedStyle, cancelAnimation } from "../../reanimated/ReanimatedRexport";
import * as _spring from "../../../design/animation/reanimated/spring/spring";
import { useCanExpandInAppNotification } from "./InAppNotificationExpandExperiment";
import * as _timing from "../../../design/animation/reanimated/timing/timing";
import AppAnalyticsUtils from "../../app_analytics/AppAnalyticsUtils";
import { PressableHighlight } from "../../../design/void/Pressables/native/Pressables";
import NotificationContent from "./NotificationContent";
import NotificationProgress from "./NotificationProgress";
const useStyles = createStyles({
shadow: {
...Module712.shadows.SHADOW_HIGH,
backgroundColor: Module712.colors.MOBILE_ALERT_BACKGROUND_DEFAULT,
borderRadius: Module712.radii.lg,
maxWidth: NOTIFICATION_MAX_WIDTH,
width: "100%",
alignSelf: "center",
borderWidth: 1,
borderColor: Module712.colors.BORDER_SUBTLE
},
container: {
borderRadius: Module712.radii.lg,
overflow: "hidden"
}
});
const ON_PRESS_SPRING_CONFIG = {
mass: 1,
overshootClamping: true,
damping: 27,
stiffness: 300
};
const __initData = {
code: "function NotificationTsx1(){const{withSpring,scale,ON_PRESS_SPRING_CONFIG}=this.__closure;return{transform:[{scale:withSpring(scale.get(),ON_PRESS_SPRING_CONFIG)}]};}"
};
const __initData2 = {
code: "function NotificationTsx2(finished){const{runOnJS,handleDismissNotification}=this.__closure;if(finished){runOnJS(handleDismissNotification)('timeout');}}"
};
const __initData3 = {
code: "function NotificationTsx3(){const{withTiming,expandedSV,tokens,Easing}=this.__closure;return{borderRadius:withTiming(expandedSV.get()?tokens.radii.xl:tokens.radii.lg,{duration:220,easing:Easing.bezier(0.16,1,0.3,1)})};}"
};
export function NotificationPressable(props) {
let guildId, channelId, messageId, type, notificationGestureY, velocityY, autoDismissing, isExpanded, expandedSV, setExpanded, handleDismissNotification, initialized, panning, isExpandableNotification, sharedValue, sharedValue2, c17881_19, callback, callback2;
const { notification, expandableContent, icon, children, accessoryLabelNode, rightAccessory, header, showDragHandle = false, onAccessibilityExpand, bodyStyle, expandedContentVisible = false, onPress, onSettingsPress, ...props2 } = props;
guildId = void 0;
channelId = void 0;
messageId = void 0;
type = void 0;
notificationGestureY = void 0;
velocityY = void 0;
autoDismissing = void 0;
isExpanded = void 0;
expandedSV = void 0;
setExpanded = void 0;
handleDismissNotification = void 0;
initialized = void 0;
panning = void 0;
isExpandableNotification = void 0;
sharedValue = void 0;
sharedValue2 = void 0;
c17881_19 = void 0;
callback = void 0;
callback2 = void 0;
const styles = useStyles();
const memo = useMemo(() => ({
type: notification.type,
...extractMetadataFromNotification(notification)
}), [notification]);
guildId = memo.guildId;
channelId = memo.channelId;
messageId = memo.messageId;
type = memo.type;
const inAppNotificationContext = useInAppNotificationContext();
notificationGestureY = inAppNotificationContext.notificationGestureY;
velocityY = inAppNotificationContext.velocityY;
autoDismissing = inAppNotificationContext.autoDismissing;
isExpanded = inAppNotificationContext.isExpanded;
expandedSV = inAppNotificationContext.expandedSV;
setExpanded = inAppNotificationContext.setExpanded;
handleDismissNotification = inAppNotificationContext.handleDismissNotification;
initialized = inAppNotificationContext.initialized;
panning = inAppNotificationContext.panning;
isExpandableNotification = inAppNotificationContext.isExpandableNotification;
sharedValue = useSharedValue(1);
const callback3 = useCallback(() => sharedValue.set(0.95), [sharedValue]);
const callback4 = useCallback(() => sharedValue.set(1), [sharedValue]);
const R = function R() {
return {
transform: [{
scale: _spring.withSpring(sharedValue.get(), ON_PRESS_SPRING_CONFIG)
}]
};
};
R.__closure = {
withSpring: _spring.withSpring,
scale: sharedValue,
ON_PRESS_SPRING_CONFIG
};
R.__workletHash = 5485274967370;
R.__initData = __initData;
let r74 = useAnimatedStyle(R);
const canExpand = useCanExpandInAppNotification("NotificationPressable").canExpand;
const memo2 = useMemo(() => ({
foreground: true
}), []);
sharedValue2 = useSharedValue(100);
const r2 = notification.duration !== Infinity;
c17881_19 = r2;
useEffect(() => {
const duration = notification.duration;
if (initialized && !panning && c17881_19 && !isExpanded && !autoDismissing) {
const r31 = {
duration: sharedValue2.get() / 100 * duration,
easing: _ReanimatedRexport.Easing.linear
};
const r32 = function(a0) {
if (a0) {
_ReanimatedRexport.runOnJS(handleDismissNotification)("timeout");
}
};
r32.__closure = {
runOnJS: _ReanimatedRexport.runOnJS,
handleDismissNotification
};
r32.__workletHash = 5704836747866;
r32.__initData = __initData2;
sharedValue2.set(_timing.withTiming(0, r31, "animate-always", r32));
return () => {
cancelAnimation(sharedValue2);
};
}
}, [initialized, panning, notification, sharedValue2, handleDismissNotification, isExpanded, autoDismissing, r2]);
callback = useCallback(() => Math.abs(velocityY.get()) >= MIN_SWIPE_VELOCITY || Math.abs(notificationGestureY.get()) >= STARTED_SWIPE_THRESHOLD, [velocityY, notificationGestureY]);
callback2 = useCallback((a0, a1) => {
const r4 = callback();
if ((r4 ? isExpanded : !r4) || autoDismissing) {
AppAnalyticsUtils.trackWithMetadata(a0, {
type,
notif_guild_id: guildId,
notif_channel_id: channelId,
message_id: messageId,
in_app_notification_id: notification.inAppNotificationId,
percent: c17881_19 ? Math.floor(typeof sharedValue2 !== "number" ? sharedValue2.get() : sharedValue2) : void 0
});
if (a1 != null) {
a1();
}
}
}, [callback, autoDismissing, type, notification.inAppNotificationId, guildId, channelId, messageId, sharedValue2, isExpanded, r2]);
const callback5 = useCallback(() => callback2(AnalyticEvents.IN_APP_NOTIFICATION_CLICKED, onPress), [callback2, onPress]);
const callback6 = useCallback(() => {
if (isExpandableNotification) {
setExpanded(true, "long_press");
} else {
callback2(AnalyticEvents.IN_APP_NOTIFICATION_LONG_PRESSED, onSettingsPress);
}
}, [callback2, isExpandableNotification, onSettingsPress, setExpanded]);
const ai = function ai() {
return {
borderRadius: _timing.withTiming(expandedSV.get() ? Module712.radii.xl : Module712.radii.lg, {
duration: 220,
easing: _ReanimatedRexport.Easing.bezier(0.16, 1, 0.3, 1)
})
};
};
ai.__closure = {
withTiming: _timing.withTiming,
expandedSV,
tokens: Module712,
Easing: _ReanimatedRexport.Easing
};
ai.__workletHash = 15276203537259;
ai.__initData = __initData3;
const animatedStyle = useAnimatedStyle(ai);
const style = [styles.shadow, ,];
if (isExpandableNotification) {
r74 = animatedStyle;
}
style[1] = r74;
return <ReanimatedRexport.View style={style}>
<PressableHighlight {...props2} onAccessibilityEscape={() => handleDismissNotification("accessibility_escape")} style={styles.container} androidRippleConfig={memo2} onPress={callback5} onPressIn={callback3} onPressOut={callback4} onLongPress={callback6} accessibilityRole="button">
<NotificationContent icon={icon} accessoryLabelNode={accessoryLabelNode} rightAccessory={rightAccessory} header={header} showDragHandle={showDragHandle} onAccessibilityExpand={onAccessibilityExpand} bodyStyle={bodyStyle} expandedContentVisible={expandedContentVisible}>{children}</NotificationContent>
{r2 ? <NotificationProgress canExpand={canExpand} percent={sharedValue2} type={type} /> : null}
{expandableContent}
</PressableHighlight>
</ReanimatedRexport.View>;
}
@@ -0,0 +1,164 @@
// Metro module 10335 (f10336).
import _slicedToArray from "../../../_bundle/_slicedToArray";
import { useState, useMemo, useCallback, useEffect } from "react";
import { Pressable, View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useIsScreenReaderEnabled } from "../../a11y/native/useIsScreenReaderEnabled.native";
import * as _ReanimatedRexport from "../../reanimated/ReanimatedRexport";
import ReanimatedRexport, { useSharedValue, useAnimatedStyle, withDelay, withRepeat, cancelAnimation } from "../../reanimated/ReanimatedRexport";
import { getExpandNUXState, MAX_TIMES_SHOWN, ONE_DAY_MS, markExpandNUXStateAsShown, NUX_REVEAL_DELAY_MS, NUX_REVEAL_DURATION_MS, DRAG_HANDLE_BOUNCE_DISTANCE, DRAG_HANDLE_BOUNCE_DURATION_MS } from "./InAppNotificationExpandNux";
import { useSelectedDismissibleContent } from "../../dismissible_content/hooks/useSelectedDismissibleContent";
import { DismissibleContent } from "../../../_bundle/Module1358";
import { withTiming } from "../../../design/animation/reanimated/timing/timing";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import MessageNotificationHeader, { SimpleNotificationHeader } from "./MessageNotificationHeader";
let useStyles, useStyles2, __initData, __initData2;
const DragHandle = function DragHandle(props) {
let c17882_5;
const onAccessibilityExpand = props.onAccessibilityExpand;
c17882_5 = void 0;
const styles = useStyles();
const isScreenReaderEnabled = useIsScreenReaderEnabled();
const sharedValue = useSharedValue(0);
const sharedValue2 = useSharedValue(0);
const [state, setState] = useState(0);
const [state2] = useState(() => Date.now());
const r61 = _slicedToArray(useSelectedDismissibleContent(useMemo(() => {
const expandNUXState = getExpandNUXState();
if (expandNUXState.numTimesShown >= MAX_TIMES_SHOWN) {
return false;
}
return !(state2 - expandNUXState.lastShownAtMs < ONE_DAY_MS);
}, [state2]) ? [DismissibleContent.IN_APP_NOTIFICATION_EXPAND_NUX] : [], void 0, true), 1)[0] === DismissibleContent.IN_APP_NOTIFICATION_EXPAND_NUX;
c17882_5 = r61;
const callback = useCallback((a0) => {
const height = a0.nativeEvent.layout.height;
setState((prevState) => {
let r2 = height;
if (prevState === height) {
r2 = prevState;
}
return r2;
});
}, []);
const c = () => ({
opacity: sharedValue2.get(),
height: _ReanimatedRexport.interpolate(sharedValue2.get(), [0, 1], [0, state])
});
c.__closure = {
textRevealProgress: sharedValue2,
interpolate: _ReanimatedRexport.interpolate,
textHeight: state
};
c.__workletHash = 11744264899632;
c.__initData = __initData;
const animatedStyle = useAnimatedStyle(c);
const A = () => ({
transform: [{
translateY: sharedValue.get()
}]
});
A.__closure = {
dragHandleBounceProgress: sharedValue
};
A.__workletHash = 16018166575562;
A.__initData = __initData2;
const animatedStyle2 = useAnimatedStyle(A);
useEffect(() => {
if (c17882_5) {
markExpandNUXStateAsShown();
sharedValue2.set(withDelay(NUX_REVEAL_DELAY_MS, withTiming(1, {
duration: NUX_REVEAL_DURATION_MS
})));
sharedValue.set(withDelay(NUX_REVEAL_DELAY_MS + NUX_REVEAL_DURATION_MS, withRepeat(withTiming(DRAG_HANDLE_BOUNCE_DISTANCE, {
duration: DRAG_HANDLE_BOUNCE_DURATION_MS
}), -1, true)));
return () => {
cancelAnimation(sharedValue2);
cancelAnimation(sharedValue);
};
}
}, [r61, sharedValue2, sharedValue]);
const r91 = r61 ? <>
<ReanimatedRexport.View style={[styles.dragHandleTextContainer, animatedStyle]}>
<Text onLayout={callback} variant="text-xs/normal" color="text-subtle" style={styles.dragHandleText}>
{intl.string(t["vos6/N"])}
</Text>
</ReanimatedRexport.View>
<ReanimatedRexport.View style={[styles.dragHandle, animatedStyle2]} />
</> : <View style={styles.dragHandle} />;
return isScreenReaderEnabled ? onAccessibilityExpand != null ? <Pressable onPress={onAccessibilityExpand} accessibilityRole="button" accessibilityLabel={intl.string(t["PbxI/x"])}>{r91}</Pressable> : r91 : r91;
};
useStyles = createStyles({
dragHandleTextContainer: {
overflow: "hidden"
},
dragHandleText: {
position: "absolute",
left: 0,
right: 0,
textAlign: "center",
paddingBottom: Module712.space.PX_4
},
dragHandle: {
width: 32,
height: 4,
alignSelf: "center",
backgroundColor: Module712.colors.BACKGROUND_ACCENT,
borderRadius: Module712.radii.xs,
marginBottom: Module712.space.PX_8
}
});
useStyles2 = createStyles({
body: {
flex: 1
},
iconContainer: {
marginRight: Module712.space.PX_8
},
contentContainer: {
padding: Module712.space.PX_12,
flexDirection: "row"
},
contentContainerExpanded: {
padding: Module712.space.PX_12,
paddingBottom: 0,
flexDirection: "row"
},
headerContainer: {
flex: 1
},
labelContainer: {
flexDirection: "row",
alignItems: "center"
}
});
__initData = {
code: "function NotificationContentTsx1(){const{textRevealProgress,interpolate,textHeight}=this.__closure;return{opacity:textRevealProgress.get(),height:interpolate(textRevealProgress.get(),[0,1],[0,textHeight])};}"
};
__initData2 = {
code: "function NotificationContentTsx2(){const{dragHandleBounceProgress}=this.__closure;return{transform:[{translateY:dragHandleBounceProgress.get()}]};}"
};
export default function NotificationContent(props) {
const { icon, children, accessoryLabelNode, rightAccessory, header, showDragHandle = false, onAccessibilityExpand, bodyStyle, expandedContentVisible = false } = props;
const styles2 = useStyles2();
const style = expandedContentVisible ? styles2.contentContainerExpanded : styles2.contentContainer;
return <>
<View style={style}>
{icon != null ? <View style={styles2.iconContainer}>{icon}</View> : null}
<ReanimatedRexport.View style={[styles2.body, bodyStyle]}>
<View style={styles2.labelContainer}>
{accessoryLabelNode ?? null}
<View style={styles2.headerContainer}>
{header.type === "message" ? <MessageNotificationHeader {...header} /> : <SimpleNotificationHeader {...header} />}
</View>
</View>
{children}
</ReanimatedRexport.View>
{rightAccessory}
</View>
{showDragHandle ? <DragHandle onAccessibilityExpand={onAccessibilityExpand} /> : null}
</>;
};
@@ -0,0 +1,131 @@
// Metro module 10338 (f10339).
import _slicedToArray from "../../../_bundle/_slicedToArray";
import { useState, useCallback } from "react";
import { View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import ReanimatedRexport, { useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
import { useInAppNotificationContext } from "./InAppNotificationContext";
function $mk84445($env) {
return (a0) => (0, $env[2])(a0.nativeEvent.layout.width);
}
function $mk84446($env) {
return function n() {
const r2 = $env;
const r4 = r2[0];
let r1 = r4;
if (typeof r1 !== "number") {
r1 = r4.get();
}
const r5 = r1 / 100;
const r6 = r2[1];
return {
transform: [{
translateX: r6 * r5 - r6
}]
};
};
}
let useStyles, __initData, RedesignProgress;
const Progress = function Progress(props) {
let env17885;
const { percent, hideProgress } = props;
const styles = useStyles();
const r15 = env17885 = {};
env17885[0] = percent;
env17885[1] = void 0;
env17885[2] = void 0;
const r17 = _slicedToArray(useState(0), 2);
const width = r17[0];
env17885[1] = width;
env17885[2] = r17[1];
const callback = useCallback($mk84445(r15), []);
const r26 = $mk84446(r15);
r26.__closure = {
percent,
width
};
r26.__workletHash = 14879761869068;
r26.__initData = __initData;
return <View onLayout={callback} style={[styles.progressContainerBottom, {
opacity: hideProgress ? 0 : 1
}]}>
<ReanimatedRexport.View style={[styles.progress, useAnimatedStyle(r26)]} />
</View>;
};
RedesignProgress = function RedesignProgress(props) {
let env17886;
const { percent, hideProgress, type } = props;
const styles = useStyles();
const r16 = env17886 = {};
env17886[0] = percent;
env17886[1] = void 0;
env17886[2] = void 0;
const r18 = _slicedToArray(useState(0), 2);
const width = r18[0];
env17886[1] = width;
env17886[2] = r18[1];
const callback = useCallback($mk84445(r16), []);
const r28 = $mk84446(r16);
r28.__closure = {
percent,
width
};
r28.__workletHash = 14879761869068;
r28.__initData = __initData;
return <View onLayout={callback} style={[styles.progressContainerTop, {
opacity: hideProgress ? 0 : 1
}]}>
<View style={styles.progressTrack}>
<ReanimatedRexport.View style={[styles.progressRedesign, type === "ALERT" ? styles.progressBarWarning : styles.progressBarBrand, useAnimatedStyle(r28)]} />
</View>
</View>;
};
useStyles = createStyles({
progress: {
borderRadius: Module712.radii.xs,
backgroundColor: Module712.colors.BACKGROUND_BRAND,
height: 4
},
progressRedesign: {
borderRadius: Module712.radii.xs,
height: 8
},
progressBarBrand: {
backgroundColor: Module712.colors.BACKGROUND_BRAND
},
progressBarWarning: {
backgroundColor: Module712.unsafe_rawColors.YELLOW_300
},
progressTrack: {
width: "100%",
borderRadius: Module712.radii.xs,
backgroundColor: Module712.colors.BACKGROUND_MOD_SUBTLE,
height: 8,
overflow: "hidden"
},
progressContainerTop: {
position: "absolute",
top: -5,
left: 16,
right: 16
},
progressContainerBottom: {
width: "100%",
position: "absolute",
bottom: -1
}
});
__initData = {
code: "function NotificationProgressTsx1(){const{percent,width}=this.__closure;const percentRemaining=(typeof percent==='number'?percent:percent.get())/100;return{transform:[{translateX:-width+width*percentRemaining}]};}"
};
export default function NotificationProgress(props) {
const { canExpand, percent, type } = props;
const inAppNotificationContext = useInAppNotificationContext();
let autoDismissing = inAppNotificationContext.autoDismissing;
const isExpanded = inAppNotificationContext.isExpanded;
if (!autoDismissing) {
autoDismissing = isExpanded;
}
return canExpand ? <RedesignProgress percent={percent} hideProgress={autoDismissing} type={type} /> : <Progress percent={percent} hideProgress={autoDismissing} />;
};
@@ -0,0 +1,314 @@
// Metro module 10361 (f10362).
import { useCallback, useMemo } from "react";
import { View } from "react-native";
import AccessibilityStore from "../../a11y/AccessibilityStore";
import { IN_APP_NOTIFICATION_MAX_HEIGHT, NOTIFICATION_PREVIEW_LINE_CLAMP } from "./InAppNotificationConstants";
import { ChannelTypes, MessageEmbedTypes } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { isIOS } from "../../../_bundle/Module501";
import Module712 from "../../../_bundle/Module712";
import { AnimateEmoji } from "../../user_settings/UserSettings";
import { usePreviewableMedia, PreviewableMediaTypes } from "./hooks/usePreviewableMedia";
import { Text } from "../../../design/components/Text/native/Text";
import AvatarUtils from "../../../utils/AvatarUtils";
import { DEFAULT_EMOJI_SIZE } from "../../forums/native/posts/reactions/ForumPostReactionButton";
import Emoji from "../../emojis/native/Emoji";
import { intl, t } from "../../../intl/index.native";
import isForwardMessage from "../../forwarding/isForwardMessage";
import * as _InAppNotificationUtils from "./InAppNotificationUtils";
import { getMessagePreviewTextVariant, useHasPreviewableMedia, trackDismissed } from "./InAppNotificationUtils";
import useTruncatedGradientColors from "./hooks/useTruncatedGradientColors";
import { NativeChannelRowPreview } from "../../main_tabs_v2/native/shared_components/ChannelRowPreview";
import { useGetInitialMessagePreview } from "./hooks/useGetInitialMessagePreview";
import GroupDMAvatar from "../../group_dm/native/GroupDMAvatar";
import { AvatarSizes, Avatar, RoleDot } from "../../../design/void/native";
import GuildIcon, { GuildIconSizes } from "../../guild/native/GuildIcon";
import { sumBy } from "../../../_bundle/Module12";
import { getUserAuthor } from "../../messages/useMessageAuthor";
import { useStateFromStores } from "../../../_bundle/Module589";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import { transitionToMessage } from "../../routing/transitionToChannel";
import InAppNotificationActionCreators from "../../../actions/native/InAppNotificationActionCreators";
import { NotificationPressable } from "./Notification";
import { MediaPreviewRightAccessory } from "./MediaPreviewRightAccessory";
let useStyles, ReactionNotificationBodyWrapper, ReactorNotificationIcon;
const ReactionNotificationBody = function ReactionNotificationBody(props) {
const { text, secondaryText, hasMessageContent, messagePreview } = props;
const styles2 = useStyles();
const messagePreviewTextVariant = getMessagePreviewTextVariant();
const truncatedGradientColors = useTruncatedGradientColors();
const { gradientColors, gradientStyles } = truncatedGradientColors;
return <>
{[<Text variant={messagePreviewTextVariant} color="text-default" style={styles2.italic}>{text}</Text>, secondaryText != null ? <Text variant="redesign/message-preview/medium" color="text-link" lineClamp={NOTIFICATION_PREVIEW_LINE_CLAMP}>{secondaryText}</Text> : null, hasMessageContent ? messagePreview != null ? <NativeChannelRowPreview message={messagePreview} lineClamp={1} maxHeight={IN_APP_NOTIFICATION_MAX_HEIGHT} textColor="text-subtle" gradientStyles={gradientStyles} gradientColors={gradientColors} /> : null : null]}
</>;
};
ReactionNotificationBodyWrapper = function ReactionNotificationBodyWrapper(props) {
let message3 = props.message;
const { reaction: reaction2, reactionCount, renderAnnouncementText, isMilestone } = props;
const r1 = message3.embeds.length > 0 && message3.embeds[0].type === MessageEmbedTypes.GIFV;
const hasMessageContent = message3.content != null && message3.content.trim() !== "" && !r1;
const message = message3;
const reaction = reaction2;
let c17899_2 = hasMessageContent;
const styles = useStyles();
const setting = AnimateEmoji.useSetting();
const previewableMedia = usePreviewableMedia(message);
const callback = useCallback(() => {
if ((reaction == null ? void 0 : reaction.emoji.name) == null) {
return null;
}
if ((reaction == null ? void 0 : reaction.emoji.name) != null && (reaction == null ? void 0 : reaction.emoji.id) == null) {
return <Text key={reaction.emoji.name} style={styles.italic} variant="text-sm/normal">{reaction.emoji.name}</Text>;
}
const r21 = (reaction == null ? void 0 : reaction.emoji.id) != null;
let src = void 0;
if (r21) {
let animated = setting;
if (setting) {
animated = reaction.emoji.animated;
}
src = AvatarUtils.getEmojiURL({
id: reaction.emoji.id,
animated,
size: DEFAULT_EMOJI_SIZE
});
}
return <Emoji textEmojiStyle={styles.textEmoji} fastImageStyle={styles.imageEmoji} src={src} name={reaction.emoji.name} />;
}, [setting, reaction, styles.imageEmoji, styles.textEmoji, styles.italic]);
const memo = useMemo(() => {
if (previewableMedia.length !== 0 && !c17899_2) {
if (previewableMedia.length === 1) {
const r66 = previewableMedia[0];
const type = r66.type;
if (PreviewableMediaTypes.IMAGE === type) {
return {
text: intl.format(t.I7mNcA, {
emojiHook: callback
}),
secondaryText: null
};
}
if (PreviewableMediaTypes.VIDEO === type) {
return {
text: intl.format(t["Umew/z"], {
emojiHook: callback
}),
secondaryText: null
};
}
if (PreviewableMediaTypes.AUDIO === type) {
return {
text: intl.format(t["P/bwx9"], {
emojiHook: callback
}),
secondaryText: r66.media.filename
};
}
if (PreviewableMediaTypes.FILE === type) {
return {
text: intl.format(t.TXNjGW, {
emojiHook: callback
}),
secondaryText: r66.media.filename
};
}
if (PreviewableMediaTypes.STICKER === type) {
return {
text: intl.format(t.pnm8NC, {
emojiHook: callback
}),
secondaryText: null
};
}
if (PreviewableMediaTypes.VOICE_MESSAGE === type) {
return {
text: intl.format(t.k6YnQO, {
emojiHook: callback
}),
secondaryText: null
};
}
if (PreviewableMediaTypes.GIF === type) {
return {
text: intl.format(t["3oS3Jq"], {
emojiHook: callback
}),
secondaryText: null
};
}
return {
text: intl.format(t.sHV43G, {
emojiHook: callback
}),
secondaryText: null
};
}
if (isForwardMessage(message)) {
return {
text: intl.format(t["8xg9ZQ"], {
emojiHook: callback
}),
secondaryText: null
};
}
const r7 = previewableMedia.every((item) => item.type === PreviewableMediaTypes.FILE);
const length = previewableMedia.length;
const r35 = intl.format(t.sec4g7, {
emojiHook: callback,
count: length
});
let text = intl.format(t.UNRyki, {
emojiHook: callback,
count: length
});
if (r7) {
text = r35;
}
return {
text,
secondaryText: null
};
}
return {
text: c17899_2 ? intl.format(t.sHV43G, {
emojiHook: callback
}) : intl.format(t.ZOzpKt, {
emojiHook: callback
}),
secondaryText: null
};
}, [callback, hasMessageContent, message, previewableMedia]);
const { text, secondaryText } = memo;
const hasPreviewableMedia = useHasPreviewableMedia(message);
const getInitialMessagePreview = useGetInitialMessagePreview({
message
});
if (hasPreviewableMedia) {
message3 = getInitialMessagePreview;
}
if (renderAnnouncementText) {
return <ReactionNotificationBody text={intl.format(t.Tqk79E, {
count: reactionCount
})} />;
}
if (isMilestone) {
return <ReactionNotificationBody text={hasMessageContent ? intl.format(t.NfZxrD, {
count: reactionCount
}) : intl.format(t.vfYN5b, {
count: reactionCount
})} secondaryText={secondaryText} hasMessageContent={hasMessageContent} messagePreview={message3} />;
}
return <ReactionNotificationBody text={text} secondaryText={secondaryText} hasMessageContent={hasMessageContent} messagePreview={message3} />;
};
ReactorNotificationIcon = function ReactorNotificationIcon(props) {
const { notification: notification2, isMilestone } = props;
const styles2 = useStyles();
const { user, guild: guild2, channel: channel2 } = notification2;
return isMilestone && channel2.isGroupDM() ? <GroupDMAvatar channel={channel2} size={AvatarSizes.NORMAL} /> : user != null ? <Avatar user={user} guildId={guild2?.id} size={AvatarSizes.NORMAL} /> : <GuildIcon guild={guild2} size={GuildIconSizes.NORMAL} style={styles2.guildIcon} />;
};
useStyles = createStyles({
newContainerRoleDot: {
paddingRight: 4,
paddingTop: 0
},
container: {
flexDirection: "column"
},
textEmoji: {
fontSize: 12
},
imageEmoji: {
height: 16,
width: 16,
transform: isIOS() ? void 0 : [{
translateY: 2
}]
},
italic: {
fontStyle: "italic",
fontFamily: isIOS() ? "ggsans-NormalItalic, NotoSans-NormalItalic" : "ggsans-MediumItalic, NotoSans-MediumItalic"
},
guildIcon: {
borderRadius: Module712.radii.sm
}
});
export default function ReactionNotification(props) {
let c17900_8, userAuthor;
const notification = props.notification;
c17900_8 = void 0;
userAuthor = void 0;
const styles2 = useStyles();
const { user, channel, guild, parentChannel } = notification;
let r28 = guild?.id;
if (r28 == null) {
r28 = channel.guild_id;
}
const guild_id = r28;
const { id, type } = channel;
const GUILD_ANNOUNCEMENT = ChannelTypes.GUILD_ANNOUNCEMENT;
const { message: message2, reaction: reaction2 } = notification;
const reactions = message2.reactions;
const type2 = channel?.type;
let renderAnnouncementText = type === GUILD_ANNOUNCEMENT;
const isReactionMilestoneNotification = _InAppNotificationUtils.isReactionMilestoneNotification(reactions, type2);
const memo = useMemo(() => sumBy(message2.reactions, ({ count_details }) => {
let r6 = count_details?.burst;
if (r6 == null) {
r6 = 0;
}
let r4 = count_details?.normal;
if (r4 == null) {
r4 = 0;
}
return r6 + r4;
}), [message2.reactions]);
if (renderAnnouncementText) {
renderAnnouncementText = memo !== 1;
}
c17900_8 = renderAnnouncementText;
userAuthor = renderAnnouncementText ? null : isReactionMilestoneNotification ? null : getUserAuthor(user, channel);
const stateFromStores = useStateFromStores([AccessibilityStore], () => AccessibilityStore.roleStyle);
let color = userAuthor?.colorString;
if (color == null) {
color = void 0;
}
let accessoryLabelNode = void 0;
if (stateFromStores === "dot") {
accessoryLabelNode = void 0;
if (color !== void 0) {
let colors = userAuthor?.colorStrings;
if (colors == null) {
colors = null;
}
accessoryLabelNode = <RoleDot color={color} colors={colors} containerStyles={styles2.newContainerRoleDot} />;
}
}
return <NotificationPressable icon={<ReactorNotificationIcon notification={notification} isMilestone={isReactionMilestoneNotification} />} accessoryLabelNode={accessoryLabelNode} header={useMemo(() => ({
type: "message",
channel,
parentChannel,
guild,
author: userAuthor,
locationTextColor: c17900_8 ? "mobile-text-heading-primary" : isReactionMilestoneNotification ? "mobile-text-heading-primary" : void 0
}), [channel, parentChannel, guild, userAuthor, renderAnnouncementText, isReactionMilestoneNotification])} onPress={useCallback(() => {
trackDismissed({
type: notification.type,
dismissReason: "notification_clicked",
guildId: guild_id,
channelId: id,
messageId: message2.id,
inAppNotificationId: notification.inAppNotificationId
});
ModalActionCreators.popAll();
transitionToMessage(channel.id, message2.id, {
navigationReplace: true
});
InAppNotificationActionCreators.clearNotification();
}, [channel.id, id, guild_id, message2.id, notification.inAppNotificationId, notification.type])} onSettingsPress={useCallback(() => ModalActionCreators.pushLazy(import("../../../components_native/InAppNotificationSettingsModal"), {
channelId: id
}), [id])} notification={notification} rightAccessory={<MediaPreviewRightAccessory message={message2} />}>
<View style={styles2.container}>
<ReactionNotificationBodyWrapper message={message2} reaction={reaction2} reactionCount={memo} renderAnnouncementText={renderAnnouncementText} isMilestone={isReactionMilestoneNotification} />
</View>
</NotificationPressable>;
};
@@ -0,0 +1,95 @@
// Metro module 10378 (f10379).
import { memo, useMemo, useCallback } from "react";
import { View } from "react-native";
import ChannelStore from "../../../stores/ChannelStore";
import GuildStore from "../../../stores/GuildStore";
import { IN_APP_NOTIFICATION_MAX_HEIGHT, NOTIFICATION_PREVIEW_LINE_CLAMP, RIGHT_ACCESSORY_LEFT_MARGIN } from "./InAppNotificationConstants";
import { AnalyticEvents } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { Avatar, AvatarSizes, CutoutDirection } from "../../../design/void/native";
import { ClockIcon } from "../../../design/components/Icon/native/redesign/generated/ClockIcon";
import Module712 from "../../../_bundle/Module712";
import { useHasPreviewableMedia, getMessagePreviewTextVariant } from "./InAppNotificationUtils";
import { MediaPreviewRightAccessory } from "./MediaPreviewRightAccessory";
import { useStateFromStores } from "../../../_bundle/Module589";
import { ChannelTypes } from "../../../_bundle/Module692";
import MessageNotificationHeader from "./MessageNotificationHeader";
import MessagePreviewText from "./MessagePreviewText";
import { ChannelRowPreview } from "../../main_tabs_v2/native/shared_components/ChannelRowPreview";
import { ChannelListLayoutTypes } from "../../main_tabs_v2/ChannelListLayoutTypes";
import Module38 from "../../../_bundle/Module38";
import { intl, t } from "../../../intl/index.native";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import { showForLaterModal } from "../../saved_messages/native/showForLaterModal";
import { SavedMessageSortTypes } from "../../saved_messages/SavedMessagesTypes";
import AnalyticsUtils from "../../../utils/AnalyticsUtils";
import { NotificationPressable } from "./Notification";
let useStyles, cutout, Component, NotificationBody;
const NotificationAvatar = function NotificationAvatar(props) {
const { user, guildId } = props;
const styles = useStyles();
return <View style={styles.avatarContainer}>
<Avatar user={user} guildId={guildId} size={AvatarSizes.NORMAL} cutout={cutout} />
<View style={styles.cutoutIconContainer}>
<ClockIcon size="xs" color={Module712.colors.ICON_SUBTLE} />
</View>
</View>;
};
NotificationBody = function NotificationBody(props) {
const { channel, message } = props;
const stateFromStores = useStateFromStores([GuildStore], () => GuildStore.getGuild(channel.guild_id));
const stateFromStores2 = useStateFromStores([ChannelStore], () => ChannelStore.getChannel(channel.parent_id));
const hasPreviewableMedia = useHasPreviewableMedia(message);
const r2 = channel.type === ChannelTypes.DM;
const lineClamp = r2 ? NOTIFICATION_PREVIEW_LINE_CLAMP : 1;
const messagePreviewTextVariant = getMessagePreviewTextVariant();
return <>
{r2 ? null : <MessageNotificationHeader channel={channel} parentChannel={stateFromStores2} guild={stateFromStores} author={null} />}
{!hasPreviewableMedia && message.poll == null ? <ChannelRowPreview channel={channel} message={message} color="text-default" layout={ChannelListLayoutTypes.COZY} variant={messagePreviewTextVariant} muted={false} lineClamp={lineClamp} /> : <MessagePreviewText message={message} lineClamp={lineClamp} showMessageAuthor maxHeight={IN_APP_NOTIFICATION_MAX_HEIGHT} />}
</>;
};
useStyles = createStyles({
cutoutIconContainer: {
position: "absolute",
right: 0,
bottom: 0
},
avatarContainer: {
position: "relative"
},
rightAccessoryContainer: {
marginLeft: RIGHT_ACCESSORY_LEFT_MARGIN
}
});
cutout = {
direction: CutoutDirection.BOTTOM_RIGHT,
radius: 10,
inset: -2
};
Component = memo(function({ message }) {
const styles = useStyles();
return useHasPreviewableMedia(message) ? <View style={styles.rightAccessoryContainer}>
<MediaPreviewRightAccessory message={message} />
</View> : null;
});
const r55 = memo(function ReminderNotification(props) {
const notification = props.notification;
const { savedMessage, author, channel: channel2 } = notification;
const message = savedMessage.message;
Module38(message != null, "Message in a notification should not be null.");
return <NotificationPressable icon={<NotificationAvatar user={author} guildId={channel2.guild_id} />} header={useMemo(() => ({
type: "simple",
text: intl.string(t.Whs8tE)
}), [])} onPress={useCallback(() => {
ModalActionCreators.popAll();
showForLaterModal(SavedMessageSortTypes.REMINDER);
AnalyticsUtils.track(AnalyticEvents.FOR_LATER_REMINDER_NOTIFICATION_CLICKED, {
message_id: notification.savedMessage.saveData.messageId,
message_author_id: notification.author.id,
notification_type: "IN_APP"
});
}, [notification])} notification={notification} rightAccessory={<Component message={message} />}>
<NotificationBody channel={channel2} message={message} />
</NotificationPressable>;
});
export default r55;
@@ -0,0 +1,45 @@
// Metro module 10379 (f10380).
import { memo, useMemo, useCallback } from "react";
import { View } from "react-native";
import { NOTIFICATION_PREVIEW_LINE_CLAMP } from "./InAppNotificationConstants";
import { InAppNotificationTypes, UserSettingsSections } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { ThemeDarkIcon } from "../../../design/components/Icon/native/redesign/generated/ThemeDarkIcon";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import InAppNotificationActionCreators from "../../../actions/native/InAppNotificationActionCreators";
import { openUserSettings } from "../../user_settings/core/native/openUserSettings";
import { NotificationPressable } from "./Notification";
import { Text } from "../../../design/components/Text/native/Text";
const useStyles = createStyles({
iconContainer: {
width: 48,
height: 48,
backgroundColor: Module712.colors.BACKGROUND_BRAND,
borderRadius: Module712.radii.round,
alignItems: "center",
justifyContent: "center"
}
});
const r44 = memo(function RestrictedHoursWarningNotification(props) {
const notification = props.notification;
const styles = useStyles();
const type = notification.type;
return <NotificationPressable icon={<View style={styles.iconContainer}>
<ThemeDarkIcon size="sm" color={Module712.colors.WHITE} />
</View>} header={useMemo(() => ({
type: "simple",
text: notification.title
}), [notification.title])} onPress={useCallback(() => {
if (type === InAppNotificationTypes.RESTRICTED_SCHEDULE_UPDATED) {
ModalActionCreators.popAll();
InAppNotificationActionCreators.clearNotification();
}
openUserSettings({
screen: UserSettingsSections.FAMILY_CENTER
});
}, [type])} notification={notification}>
<Text variant="redesign/message-preview/medium" color="text-subtle" lineClamp={NOTIFICATION_PREVIEW_LINE_CLAMP}>{notification.subtitle}</Text>
</NotificationPressable>;
});
export default r44;
@@ -0,0 +1,24 @@
// Metro module 10301 (f10302).
import { useMemo } from "react";
import MessageRecord, { MessageSnapshotRecord } from "../../../../records/MessageRecord";
import isForwardMessage from "../../../forwarding/isForwardMessage";
export function useGetInitialMessagePreview({ message }) {
return useMemo(() => {
const messageRecord = new MessageRecord(message);
messageRecord.attachments = [];
messageRecord.stickerItems = [];
if (messageRecord.embeds.length > 0) {
messageRecord.embeds = messageRecord.embeds.filter((embed) => embed.image == null && embed.thumbnail == null);
}
if (isForwardMessage(message)) {
messageRecord.messageSnapshots = messageRecord.messageSnapshots.map((messageSnapshot) => new MessageSnapshotRecord({
message: messageSnapshot.message.merge({
attachments: [],
embeds: [],
stickerItems: []
})
}));
}
return messageRecord;
}, [message]);
}
@@ -0,0 +1,147 @@
// Metro module 10295 (f10296).
import { useMemo } from "react";
import { View, StyleSheet } from "react-native";
import { MessageEmbedTypes, MessageFlags } from "../../../../Constants";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import { useToken } from "../../../../design/tokens/native/useToken";
import Module712 from "../../../../_bundle/Module712";
import Module8531, { Path } from "../../../../_bundle/Module8531";
import { CirclePlayIcon } from "../../../../design/components/Icon/native/redesign/generated/CirclePlayIcon";
import { WaveformIcon } from "../../../../design/components/Icon/native/redesign/generated/WaveformIcon";
import * as _MediaFormatTesters from "../../../messages/MediaFormatTesters";
import { isImageFile, isVideoFile } from "../../../messages/MediaFormatTesters";
import { FileIcon } from "../../../../design/components/Icon/native/redesign/generated/FileIcon";
import isForwardMessage from "../../../forwarding/isForwardMessage";
let c6878_10, useStyles, getBasePreviewableMedia;
const VoiceMessageIcon = function VoiceMessageIcon() {
const styles = useStyles();
return <>
<Module8531 width="100%" height="100%" viewBox="0 0 64 61" fill="none">
<Path d="M22.2188 59.8545C19.5607 61.6263 16.0003 59.7208 16 56.5264V48C7.16344 48 2.5772e-07 40.8366 0 32V16C0 7.16344 7.16344 0 16 0H48C56.8366 0 64 7.16344 64 16V32C64 40.8366 56.8366 48 48 48H40L22.2188 59.8545Z" fill={useToken(Module712.colors.BACKGROUND_MOD_STRONG)} stroke={useToken(Module712.colors.BACKGROUND_MOD_SUBTLE)} />
</Module8531>
<View style={styles.voiceMessageIconOverlay}>
<CirclePlayIcon size="md" color="background-brand" secondaryColor="white" />
<WaveformIcon size="md" color="background-brand" />
</View>
</>;
};
getBasePreviewableMedia = function getBasePreviewableMedia({ message: message2, isForward }) {
const r43 = [];
if (message2.attachments.length > 0) {
const hasFlag = message2.hasFlag(MessageFlags.IS_VOICE_MESSAGE);
const attachments = message2.attachments;
if (hasFlag) {
const media4 = attachments[0];
r43.push({
id: `${media4.id}-${c6878_10.VOICE_MESSAGE}`,
type: c6878_10.VOICE_MESSAGE,
media: media4,
icon: <VoiceMessageIcon />,
parentType: isForward ? "forward" : null
});
} else {
for (const item of attachments) {
const filename = item.filename;
if (isImageFile(filename)) {
const media3 = item;
r43.push({
id: `${media3.id}-${c6878_10.IMAGE}`,
type: c6878_10.IMAGE,
media: media3,
parentType: isForward ? "forward" : null
});
} else if (isVideoFile(filename)) {
const media2 = item;
r43.push({
id: `${media2.id}-${c6878_10.VIDEO}`,
type: c6878_10.VIDEO,
media: media2,
parentType: isForward ? "forward" : null
});
} else {
const isAudioFile = _MediaFormatTesters.isAudioFile(filename);
const r67 = {
id: null,
type: null,
media: null,
icon: null,
parentType: null
};
const media = item;
const id = media.id;
if (isAudioFile) {
r67.id = `${id}-${c6878_10.AUDIO}`;
r67.type = c6878_10.AUDIO;
r67.media = media;
r67.icon = <CirclePlayIcon size="lg" color="background-brand" secondaryColor="white" />;
r67.parentType = isForward ? "forward" : null;
r43.push(r67);
} else {
r67.id = `${id}-${c6878_10.FILE}`;
r67.type = c6878_10.FILE;
r67.media = media;
r67.icon = <FileIcon size="lg" color={Module712.colors.ICON_SUBTLE} />;
r67.parentType = isForward ? "forward" : null;
r43.push(r67);
}
}
}
}
}
for (const embed of message2.embeds) {
if (embed.type === MessageEmbedTypes.GIFV) {
r43.push({
id: `${embed.id}-${c6878_10.GIF}`,
type: c6878_10.GIF,
media: embed,
parentType: isForward ? "forward" : null
});
}
}
if (message2.stickerItems.length > 0) {
const media6 = message2.stickerItems[0];
r43.push({
id: `${media6.id}-${c6878_10.STICKER}`,
type: c6878_10.STICKER,
media: media6,
parentType: isForward ? "forward" : null
});
}
return r43;
};
c6878_10 = {
IMAGE: "image",
VIDEO: "video",
AUDIO: "audio",
FILE: "file",
STICKER: "sticker",
GIF: "gif",
VOICE_MESSAGE: "voice_message"
};
useStyles = createStyles({
voiceMessageIconOverlay: {
...StyleSheet.absoluteFillObject,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
paddingBottom: 13
}
});
export { c6878_10 as PreviewableMediaTypes };
export function usePreviewableMedia(a0) {
const message = a0;
return useMemo(() => {
const r3 = [];
r3.push.apply(r3, [...getBasePreviewableMedia({
message,
isForward: false
})]);
if (isForwardMessage(message) && message.messageSnapshots.length > 0) {
r3.push.apply(r3, [...getBasePreviewableMedia({
message: message.messageSnapshots[0].message,
isForward: true
})]);
}
return r3;
}, [a0]);
}
@@ -0,0 +1,125 @@
// Metro module 10300 (f10301).
import { useMemo } from "react";
import { PreviewableMediaTypes } from "./usePreviewableMedia";
import { intl, t } from "../../../../intl/index.native";
export function usePreviewableMediaText({ previewableMedia, author }) {
return useMemo(() => {
if (previewableMedia.length === 0) {
return {
text: null,
secondaryText: null
};
}
if (previewableMedia.length === 1) {
const r74 = previewableMedia[0];
const type = r74.type;
if (PreviewableMediaTypes.IMAGE === type) {
return author != null ? {
text: intl.formatToPlainString(t.pTiyNB, {
username: author.nick
}),
secondaryText: null
} : {
text: intl.string(t.tCcq5p),
secondaryText: null
};
}
if (PreviewableMediaTypes.VIDEO === type) {
return author != null ? {
text: intl.formatToPlainString(t.zqhHWH, {
username: author.nick
}),
secondaryText: null
} : {
text: intl.string(t.KxO2Yl),
secondaryText: null
};
}
if (PreviewableMediaTypes.AUDIO === type) {
return author != null ? {
text: intl.formatToPlainString(t.HADQ6n, {
username: author.nick
}),
secondaryText: r74.media.filename
} : {
text: intl.string(t.FWqQt5),
secondaryText: r74.media.filename
};
}
if (PreviewableMediaTypes.FILE === type) {
return author != null ? {
text: intl.formatToPlainString(t["ifW/ef"], {
username: author.nick
}),
secondaryText: r74.media.filename
} : {
text: intl.string(t.mX8M6i),
secondaryText: r74.media.filename
};
}
if (PreviewableMediaTypes.STICKER === type) {
return author != null ? {
text: intl.formatToPlainString(t["3iI/fs"], {
username: author.nick
}),
secondaryText: null
} : {
text: intl.string(t.dyquw8),
secondaryText: null
};
}
if (PreviewableMediaTypes.VOICE_MESSAGE === type) {
return author != null ? {
text: intl.formatToPlainString(t.Y7wlOj, {
username: author.nick
}),
secondaryText: null
} : {
text: intl.string(t.slFYgi),
secondaryText: null
};
}
if (PreviewableMediaTypes.GIF === type) {
return author != null ? {
text: intl.formatToPlainString(t.mikhon, {
username: author.nick
}),
secondaryText: null
} : {
text: intl.string(t.p0oZmy),
secondaryText: null
};
}
return author != null ? {
text: intl.formatToPlainString(t["7FJeVi"], {
username: author.nick
}),
secondaryText: null
} : {
text: intl.string(t.sDqZHL),
secondaryText: null
};
}
const r7 = previewableMedia.every((item) => item.type === PreviewableMediaTypes.FILE);
const length = previewableMedia.length;
const r29 = author != null ? intl.format(t["319zWs"], {
count: length,
username: author.nick
}) : intl.formatToPlainString(t.y0gZht, {
count: length
});
let text = author != null ? intl.format(t["1OSGGk"], {
count: length,
username: author.nick
}) : intl.formatToPlainString(t["8/qgDd"], {
count: length
});
if (r7) {
text = r29;
}
return {
text,
secondaryText: null
};
}, [author, previewableMedia]);
}
@@ -0,0 +1,19 @@
// Metro module 10280 (f10281).
import { useMemo } from "react";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import { useToken } from "../../../../design/tokens/native/useToken";
import Module712 from "../../../../_bundle/Module712";
import Module689 from "../../../../_bundle/Module689";
const useStyles = createStyles({
gradient: {
height: 40
}
});
export default function useTruncatedGradientColors() {
const styles = useStyles();
const token = useToken(Module712.colors.MOBILE_ALERT_BACKGROUND_DEFAULT);
return {
gradientColors: useMemo(() => [Module689(token).alpha(0).hex(), Module689(token).alpha(0.72).hex()], [token]),
gradientStyles: styles.gradient
};
};