Files
discord-decomp/modules/in_app_notifications/native/ReactionNotification.tsx
T
2026-11-01 12:12:55 +02:00

315 lines
13 KiB
TypeScript

// 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>;
};