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,98 @@
// Metro module 9594 (f9595).
import { memo, useEffect, useRef, useCallback } from "react";
import { View, StyleSheet } from "react-native";
import { AnalyticEvents, ChatInputComponentViewedTypes, VerticalGradient } from "../../../../Constants";
import { EmojiIntention } from "../../../emojis/EmojiConstants";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import AnalyticsUtils from "../../../../utils/AnalyticsUtils";
import { useSharedValue } from "../../../reanimated/ReanimatedRexport";
import { useEmojiCategories } from "../../EmojiPickerUtils";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../../app_analytics/useAnalyticsLocations";
import AnalyticsLocation from "../../../app_analytics/AnalyticsLocation";
import useEmojiPickerSearchState from "./useEmojiPickerSearchState";
import useExpressionPickerInsets from "../../../expression_picker/native/useExpressionPickerInsets";
import { SearchField } from "../../../../design/components/TextField/native/SearchField.native";
import { intl, t } from "../../../../intl/index.native";
import EmojiPickerList from "./EmojiPickerList";
import { openEmojiActionSheet } from "./openEmojiActionSheet";
import Module4611 from "../../../../_bundle/Module4611";
import { hexOpacityToRgba } from "../../../../utils/ColorUtils";
import EmojiPickerCategories from "./categories/EmojiPickerCategories";
const useStyles = createStyles({
container: {
flex: 1
},
list: {
overflow: "hidden",
flex: 1
},
header: {
flexDirection: "row",
paddingTop: Module712.space.PX_8,
paddingBottom: 1,
gap: Module712.space.PX_12
},
headerGradientColor: {
color: Module712.colors.MOBILE_EXPRESSION_PICKER_BACKGROUND_DEFAULT
},
headerGradient: {
...StyleSheet.absoluteFillObject,
height: Module712.space.PX_8 + 1,
bottom: void 0,
top: -1
}
});
const r66 = memo(function EmojiPicker(props) {
let ref, handleTextChange;
const { bottomSheetRef, bottomSheetIndex, channel, onPressEmoji, onBackspace, inPortalKeyboard } = props;
ref = void 0;
handleTextChange = void 0;
const styles = useStyles();
useEffect(() => {
AnalyticsUtils.track(AnalyticEvents.CHAT_INPUT_COMPONENT_VIEWED, {
type: ChatInputComponentViewedTypes.EMOJI,
channel_id: channel.id,
guild_id: channel.guild_id
});
}, [channel.id, channel.guild_id]);
const sharedValue = useSharedValue(0);
const emojiCategories = useEmojiCategories(EmojiIntention.CHAT, channel);
const ref2 = useRef(null);
ref = useRef(null);
const analyticsLocations = useAnalyticsLocations(AnalyticsLocation.EMOJI_PICKER).analyticsLocations;
const emojiPickerSearchState = useEmojiPickerSearchState(channel, sharedValue, EmojiIntention.CHAT);
handleTextChange = emojiPickerSearchState.handleTextChange;
const { searchQueryRef, searchResults } = emojiPickerSearchState;
const callback2 = useCallback(() => {
AnalyticsUtils.track(AnalyticEvents.CHAT_INPUT_COMPONENT_VIEWED, {
type: ChatInputComponentViewedTypes.EMOJI_SEARCH,
channel_id: channel.id,
guild_id: channel.guild_id
});
}, [channel]);
const callback = useCallback(() => {
const current = ref.current;
if (current != null) {
current.setText("");
}
handleTextChange("");
}, [handleTextChange]);
const expressionPickerInsets = useExpressionPickerInsets({
hasCategories: true
});
const { safeAreaStyle, safeAreaBottomKeyboardAware } = expressionPickerInsets;
return <AnalyticsLocationProvider value={analyticsLocations}>
<View style={styles.container}>
<View style={styles.header}>
<SearchField ref={ref} size="md" placeholder={intl.string(t.KgK5qg)} onChange={handleTextChange} onFocus={callback2} isRound />
</View>
<View style={styles.list}>
<EmojiPickerList bottomSheetIndex={bottomSheetIndex} emojiPickerListRef={ref2} categories={emojiCategories} categoryIndexActive={sharedValue} emojis={searchResults} onPressEmoji={onPressEmoji} onLongPressEmoji={openEmojiActionSheet} channel={channel} emojiPickerIntention={EmojiIntention.CHAT} insetBottom={safeAreaBottomKeyboardAware} inPortalKeyboard={inPortalKeyboard} searchQueryRef={searchQueryRef} />
<Module4611 style={styles.headerGradient} start={VerticalGradient.START} end={VerticalGradient.END} colors={[hexOpacityToRgba(styles.headerGradientColor.color, 100), hexOpacityToRgba(styles.headerGradientColor.color, 0)]} />
</View>
<EmojiPickerCategories bottomSheetRef={bottomSheetRef} bottomSheetIndex={bottomSheetIndex} style={safeAreaStyle} emojiPickerListRef={ref2} categories={emojiCategories} categoryIndexActive={sharedValue} onBackspace={onBackspace} inPortalKeyboard={inPortalKeyboard} isSearching={searchResults != null} onClearSearch={callback} />
</View>
</AnalyticsLocationProvider>;
});
export default r66;
@@ -0,0 +1,165 @@
// Metro module 9338 (f9339).
import { useState, useRef, useCallback, useMemo } from "react";
import { View } from "react-native";
import UserStore from "../../../../stores/UserStore";
import { EmojiPickerSource } from "./EmojiPickerListConstants";
import { EXPRESSION_FOOTER_HEIGHT } from "../../../../Constants";
import { EmojiIntention } from "../../../emojis/EmojiConstants";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { ReactionTypes } from "../../../messages/MessageReactionsTypes";
import { useSharedValue } from "../../../reanimated/ReanimatedRexport";
import { useEmojiCategories, getSearchPlaceholder } from "../../EmojiPickerUtils";
import useSafeAreaInsetsKeyboardAware_native from "../../../safe_area/useSafeAreaInsetsKeyboardAware.native";
import useSafeAreaInsets_native from "../../../safe_area/useSafeAreaInsets.native";
import { isAndroid, isIOS } from "../../../../utils/PlatformUtils";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../../app_analytics/useAnalyticsLocations";
import AnalyticsLocation from "../../../app_analytics/AnalyticsLocation";
import useEmojiPickerSearchState from "./useEmojiPickerSearchState";
import ActionSheetActionCreators from "../../../action_sheet/native/ActionSheetActionCreators";
import { EMOJI_PICKER_ACTION_SHEET_KEY } from "../openEmojiPickerActionSheet";
import { maybeShowDoubleTapReminderToast } from "../../../double_tap_to_react/native/DoubleTapReminderToast";
import { Text } from "../../../../design/components/Text/native/Text";
import { intl, t } from "../../../../intl/index.native";
import { SearchField } from "../../../../design/components/TextField/native/SearchField.native";
import BurstReactionToggle from "../../../reactions/native/BurstReactionToggle";
import { isPremium } from "../../../../utils/PremiumUtils";
import { triggerHapticFeedback } from "../../../haptics/HapticUtils.native";
import HapticFeedbackTypes from "../../../haptics/HapticFeedbackTypes";
import PortalKeyboardFooterIOS_ios from "../../../keyboard/native/PortalKeyboardFooterIOS.ios";
import { BottomSheet } from "../../../../design/components/Sheet/native/BottomSheet.native";
import { PortalHost } from "../../../../_bundle/Module4060";
import EmojiPickerList from "./EmojiPickerList";
import { openEmojiActionSheet } from "./openEmojiActionSheet";
import EmojiPickerCategories from "./categories/EmojiPickerCategories";
const portalHostName = "EmojiPickerActionSheet";
const useStyles = createStyles({
header: {
flexDirection: "column"
},
searchContainer: {
display: "flex",
flexDirection: "row",
marginBottom: -Module712.space.PX_16
},
content: {
paddingHorizontal: Module712.space.PX_8,
backgroundColor: Module712.colors.MOBILE_EXPRESSION_PICKER_BACKGROUND_DEFAULT
},
background: {
backgroundColor: Module712.colors.MOBILE_EXPRESSION_PICKER_BACKGROUND_DEFAULT
},
headerText: {
flexDirection: "column",
alignItems: "center",
marginBottom: Module712.space.PX_16
},
headerSpacer: {
marginTop: Module712.space.PX_8
},
burstReaction: {
borderColor: Module712.colors.BACKGROUND_BRAND
}
});
export default function EmojiPickerActionSheet(props) {
let ref, ref2, memo;
const { onClose, channel, guildId, onPressEmoji, pickerIntention, autoFocus = true, startExpanded = true, analyticsObject, messageId, source } = props;
ref = void 0;
ref2 = void 0;
memo = void 0;
const styles = useStyles();
const [state, setState] = useState(ReactionTypes.NORMAL);
const isActive = state === ReactionTypes.BURST;
const ref3 = useRef(null);
const sharedValue = useSharedValue(0);
const emojiCategories = useEmojiCategories(pickerIntention, channel, guildId);
let bottom2 = useSafeAreaInsetsKeyboardAware_native().insets.bottom;
const bottom = useSafeAreaInsets_native().bottom;
if (isAndroid()) {
bottom2 = bottom;
}
const marginBottom = bottom2 + EXPRESSION_FOOTER_HEIGHT;
const insetBottom = marginBottom + Module712.space.PX_16;
const analyticsLocations = useAnalyticsLocations(AnalyticsLocation.EMOJI_PICKER).analyticsLocations;
const emojiPickerSearchState = useEmojiPickerSearchState(channel, sharedValue, pickerIntention);
const { handleTextChange, searchQueryRef, searchResults } = emojiPickerSearchState;
const callback3 = useCallback(() => {
if (onClose != null) {
onClose();
}
}, [onClose]);
const callback = useCallback((a0) => {
if (onPressEmoji != null) {
onPressEmoji(a0, isActive);
}
ActionSheetActionCreators.hideActionSheet(EMOJI_PICKER_ACTION_SHEET_KEY);
if (!(pickerIntention !== EmojiIntention.REACTION || source === EmojiPickerSource.NOTIFICATION || isActive)) {
maybeShowDoubleTapReminderToast(a0);
}
}, [onPressEmoji, isActive, pickerIntention, source]);
const memo3 = useMemo(() => {
const marginLeft = isActive ? 2 : 0;
const marginRight = isActive ? 2 : 0;
let paddingRight = 2;
const paddingLeft = isActive ? 0 : 2;
if (isActive) {
paddingRight = 0;
}
return {
marginLeft,
marginRight,
paddingLeft,
paddingRight,
paddingBottom: bottom
};
}, [isActive, bottom]);
ref = useRef(null);
ref2 = useRef(autoFocus);
const callback2 = useCallback(() => {
if (ref2.current) {
const current = ref.current;
if (current != null) {
current.focus();
}
ref2.current = false;
}
}, []);
const callback4 = useCallback(() => {
const current = ref.current;
if (current != null) {
current.setText("");
}
}, []);
memo = useMemo(() => pickerIntention === EmojiIntention.DEFAULT_REACT_EMOJI ? <View style={styles.headerText}>
<Text variant="heading-lg/bold" color="mobile-text-heading-primary">
{intl.string(t.wHTk2C)}
</Text>
<Text variant="text-sm/medium" color="text-muted">
{intl.string(t.VrWSNn)}
</Text>
</View> : null, [pickerIntention, styles]);
const memo2 = useMemo(() => <View style={styles.header}>
{memo}
<View style={[styles.searchContainer, memo === null ? styles.headerSpacer : null]}>
<SearchField ref={ref} size="md" isRound onChange={handleTextChange} placeholder={getSearchPlaceholder(pickerIntention, isActive)} />
{pickerIntention === EmojiIntention.REACTION && source !== EmojiPickerSource.NOTIFICATION && <BurstReactionToggle onPress={() => {
if (isPremium(UserStore.getCurrentUser())) {
triggerHapticFeedback(HapticFeedbackTypes.IMPACT_LIGHT);
setState(isActive ? ReactionTypes.NORMAL : ReactionTypes.BURST);
return void 0;
}
return ActionSheetActionCreators.openLazy(import("../../../messages/native/burst_reactions/SuperReactionUpsellActionSheet"), "SuperReactionUpsellActionSheet");
}} isActive={isActive} />}
</View>
</View>, [styles, handleTextChange, isActive, pickerIntention, memo, source]);
const borderGradient = isActive ? [styles.burstReaction.borderColor, Module712.unsafe_rawColors.TRANSPARENT] : [Module712.unsafe_rawColors.TRANSPARENT, Module712.unsafe_rawColors.TRANSPARENT];
const sharedValue2 = useSharedValue(-1);
const ref4 = useRef(null);
const r152 = [isIOS() && <PortalKeyboardFooterIOS_ios portalHostName={portalHostName} animatedSheetIndex={sharedValue2} followSystemKeyboard />, <BottomSheet backgroundStyles={styles.background} ref={ref4} scrollable header={memo2} footer={isAndroid() ? <PortalHost name={portalHostName} /> : void 0} startExpanded={startExpanded} onDismiss={callback3} animatedIndex={sharedValue2} onExpand={callback2} borderGradient={borderGradient} contentStyles={[styles.content, {
marginBottom
}]}>
<EmojiPickerList bottomSheetIndex={sharedValue2} onPressEmoji={callback} onLongPressEmoji={openEmojiActionSheet} emojiPickerListRef={ref3} categories={emojiCategories} categoryIndexActive={sharedValue} emojis={searchResults} emojiPickerIntention={pickerIntention} channel={channel} guildId={guildId} searchQueryRef={searchQueryRef} insetBottom={insetBottom} analyticsObject={analyticsObject} messageId={messageId} />
<EmojiPickerCategories bottomSheetRef={ref4} bottomSheetIndex={sharedValue2} style={memo3} categories={emojiCategories} categoryIndexActive={sharedValue} emojiPickerListRef={ref3} portalHostName={portalHostName} renderAhead={isIOS() ? pickerIntention === EmojiIntention.STATUS ? "full" : void 0 : void 0} isSearching={searchResults != null} onClearSearch={callback4} />
</BottomSheet>];
return <AnalyticsLocationProvider value={analyticsLocations}>{r152}</AnalyticsLocationProvider>;
};
@@ -0,0 +1,196 @@
// Metro module 9353 (f9354).
import { memo, useEffect, useCallback } from "react";
import { IMAGE_SIZE } from "./EmojiPickerListConstants";
import { AnalyticsObjects, AnalyticsPages, AnalyticsSections, UpsellTypes } from "../../../../Constants";
import { EmojiDisabledReasons, EmojiIntention } from "../../../emojis/EmojiConstants";
import { MIN_MARGIN } from "../../../expression_picker/ExpressionPickerConstants";
import { PremiumUpsellTypes } from "../../../premium/PremiumConstants";
import useAnalyticsLocations from "../../../app_analytics/useAnalyticsLocations";
import AnalyticsLocation from "../../../app_analytics/AnalyticsLocation";
import useExpressionPickerListWidth_native from "../../../expression_picker/native/useExpressionPickerListWidth.native";
import useTopAndNewlyAddedEmojis from "../../hooks/useTopAndNewlyAddedEmojis";
import { updateNewlyAddedLastSeen } from "../../../emojis/top_emojis/TopEmojisActionCreators";
import useNativeAndroidEmojiPickerEnabled from "./useNativeAndroidEmojiPickerEnabled";
import { useTrackOnEmojiPickerOpenedForReactions } from "../../analytics/trackOnEmojiPickerOpened";
import useComputeEmojiPickerFunctions from "./useComputeEmojiPickerFunctions";
import PremiumUpsellUtils, { usePremiumUpsellConfig } from "../../../../utils/native/PremiumUpsellUtils";
import { getUpsellType } from "../../../premium/roadblocks/native/utils/PremiumFeatureUpsellUtils";
import { EntitlementFeatureNames } from "../../../../_bundle/Module6201";
import { triggerHapticFeedback } from "../../../haptics/HapticUtils.native";
import HapticFeedbackTypes from "../../../haptics/HapticFeedbackTypes";
import EmojiUtils from "../../../../utils/EmojiUtils";
import { dismissKeyboard } from "../../../../utils/native/ChatInputUtils";
import RoleSubscriptionUpsellUtils from "../../../guild_role_subscriptions/native/RoleSubscriptionUpsellUtils";
import ToastActionCreators from "../../../toast/native/ToastActionCreators";
import { intl, t } from "../../../../intl/index.native";
import { trackEmojiSearchSelect, trackEmojiSelect } from "../../EmojiPickerUtils";
import useEmojiPickerData, { EmojiPickerItemType } from "./data/useEmojiPickerData";
import { AnimateEmoji } from "../../../user_settings/UserSettings";
import { Section, NSFWRow } from "./EmojiPickerListComponents";
import PremiumUpsellSectionDivider from "../../../premium/roadblocks/native/views/PremiumUpsellSectionDivider";
import { EmojiPickerListRow } from "./EmojiPickerListRow";
import { PremiumSearchUpsell } from "./EmojiPickerPremiumSearchUpsell";
import { PremiumUpsellGradientBackground } from "../../../premium/roadblocks/native/views/PremiumUpsellGradientBackground";
import useShowNitroUpsellCallback from "../../../premium/roadblocks/native/hooks/useShowNitroUpsellCallback";
import EmojiPickerListComponentEmpty from "./EmojiPickerListComponentEmpty";
import EmojiPickerListComponent_android from "./EmojiPickerListComponent.android";
import EmojiPickerListComponent_ios from "./EmojiPickerListComponent.ios";
import PremiumEmojiFeatureUpsell from "../../../premium/roadblocks/native/views/PremiumEmojiFeatureUpsell";
const r41 = memo(function EmojiPickerList(props) {
let useTier0UpsellContent, callback, callback2, setting;
const { bottomSheetIndex, categories, categoryIndexActive, emojiPickerListRef, emojis, channel, guildId, onPressEmoji, onLongPressEmoji, emojiPickerIntention, insetBottom = 0, insetTop = 0, inPortalKeyboard = false, searchQueryRef, analyticsObject, messageId } = props;
useTier0UpsellContent = void 0;
callback = void 0;
callback2 = void 0;
setting = void 0;
const analyticsLocations = useAnalyticsLocations(AnalyticsLocation.EMOJI).analyticsLocations;
const containerWidth = useExpressionPickerListWidth_native(inPortalKeyboard);
const rowSize = Math.floor((containerWidth - MIN_MARGIN) / (IMAGE_SIZE + MIN_MARGIN));
const newlyAddedEmojis = useTopAndNewlyAddedEmojis(guildId, emojiPickerIntention).newlyAddedEmojis;
const r3 = newlyAddedEmojis.length > 0;
const id = r3 ? newlyAddedEmojis[0].id : null;
useEffect(() => {
updateNewlyAddedLastSeen(guildId, id);
}, [id, guildId]);
const nativeAndroidEmojiPickerEnabled = useNativeAndroidEmojiPickerEnabled();
useTrackOnEmojiPickerOpenedForReactions({
intention: emojiPickerIntention,
rowSize,
analyticsObject
});
const computeEmojiPickerFunctions = useComputeEmojiPickerFunctions();
const { computeCategories, computeSearchResults } = computeEmojiPickerFunctions;
const emojiSections = emojis != null ? computeSearchResults({
emojis,
rowSize,
limit: nativeAndroidEmojiPickerEnabled ? 200 : void 0
}) : computeCategories({
categories,
rowSize,
isNativeEmojiPickerEnabled: nativeAndroidEmojiPickerEnabled
});
useTier0UpsellContent = usePremiumUpsellConfig(getUpsellType(EntitlementFeatureNames.EMOJIS_EVERYWHERE)).useTier0UpsellContent;
callback = useCallback((a0, a1) => {
let searchQuery = searchQueryRef?.current;
if (searchQuery == null) {
searchQuery = "";
}
const has_search_query = searchQuery.length > 0;
triggerHapticFeedback(HapticFeedbackTypes.IMPACT_LIGHT);
const emojiUnavailableReason = EmojiUtils.getEmojiUnavailableReason({
emoji: a0,
channel,
intention: emojiPickerIntention,
guildId
});
if (emojiUnavailableReason === null) {
if (onPressEmoji != null) {
onPressEmoji(a0);
}
} else if (EmojiDisabledReasons.ROLE_SUBSCRIPTION_LOCKED === emojiUnavailableReason) {
dismissKeyboard();
if (a0.guildId != null) {
RoleSubscriptionUpsellUtils.handleShowEmojiUpsellAlert({
guildId: a0.guildId
});
}
} else if (EmojiDisabledReasons.PREMIUM_LOCKED === emojiUnavailableReason) {
PremiumUpsellUtils.handleShowUpsellAlert({
initialUpsellKey: a0.animated ? UpsellTypes.ANIMATED_EMOJI : UpsellTypes.GLOBAL_EMOJI,
analyticsLocation: {
page: channel?.guild_id != null ? AnalyticsPages.GUILD_CHANNEL : AnalyticsPages.DM_CHANNEL,
section: AnalyticsSections.EMOJI_PICKER_POPOUT,
object: AnalyticsObjects.EMOJI
},
analyticsLocations,
analyticsProperties: {
type: emojiPickerIntention === EmojiIntention.REACTION ? PremiumUpsellTypes.EMOJI_PICKER_REACTION_EMOJI_CLICKED : PremiumUpsellTypes.EMOJI_PICKER_EMOJI_CLICKED,
is_animated: a0.animated,
is_external: a0.guildId != null && a0.guildId !== channel?.guild_id,
has_search_query
}
});
} else {
ToastActionCreators.open({
key: "EMOJI_PICKER_LIST_PRESS_DISABLED",
content: intl.string(t.VsE5yG)
});
}
if (has_search_query) {
trackEmojiSearchSelect({
emoji: a0,
location: {
page: channel?.guild_id != null ? AnalyticsPages.GUILD_CHANNEL : AnalyticsPages.DM_CHANNEL,
section: AnalyticsSections.EMOJI_PICKER_POPOUT,
object: AnalyticsObjects.EMOJI
},
searchQuery,
intention: emojiPickerIntention,
messageId
});
} else {
trackEmojiSelect({
emoji: a0,
pickerIntention: emojiPickerIntention,
category: a1,
location: {
page: channel?.guild_id != null ? AnalyticsPages.GUILD_CHANNEL : AnalyticsPages.DM_CHANNEL,
section: AnalyticsSections.EMOJI_PICKER_POPOUT,
object: AnalyticsObjects.EMOJI
},
messageId
});
}
}, [searchQueryRef, channel, emojiPickerIntention, guildId, onPressEmoji, analyticsLocations, messageId]);
callback2 = useCallback((a0) => {
if (onLongPressEmoji != null) {
onLongPressEmoji(a0);
}
}, [onLongPressEmoji]);
const emojiPickerData = useEmojiPickerData({
emojiSections,
rowSize,
isNativeEmojiPickerEnabled: nativeAndroidEmojiPickerEnabled
});
setting = AnimateEmoji.useSetting();
const callback3 = useCallback(({ item, target, index }) => {
let r13;
const type = item.type;
if (EmojiPickerItemType.NATIVE_SECTION !== type && EmojiPickerItemType.PLACEHOLDER !== type && EmojiPickerItemType.EMOJI_ROW_SLIM !== type) {
if (EmojiPickerItemType.TITLE === type) {
const title = item.title;
if (target === "StickyHeader") {
const current = emojiPickerListRef.current;
if (current != null) {
current.onStickyHeaderRendered(index);
}
}
return <Section label={title} isSectionNitroLocked={item.isSectionNitroLocked} useTier0UpsellContent={useTier0UpsellContent} />;
}
if (EmojiPickerItemType.PREMIUM_INLINE_ROADBLOCK === type) {
return <PremiumUpsellSectionDivider position={item.position} useTier0UpsellContent={useTier0UpsellContent} />;
}
if (EmojiPickerItemType.EMOJI_ROW === type) {
const emojis = item.emojis;
r13 = <EmojiPickerListRow emojis={emojis} emojisDisabled={item.emojisDisabled} category={item.footer} rowSize={rowSize} containerWidth={containerWidth} onPressEmoji={callback} onLongPressEmoji={callback2} animateEmoji={setting} row={item.row} isSectionNitroLocked={item.isSectionNitroLocked} />;
} else {
r13 = EmojiPickerItemType.EMOJI_ROW_NSFW === type ? <NSFWRow /> : EmojiPickerItemType.FOOTER_UPSELL === type ? <PremiumSearchUpsell guildId={channel?.guild_id} analyticsLocations={analyticsLocations} useTier0UpsellContent={useTier0UpsellContent} /> : void 0;
}
return <>
{item.isSectionNitroLocked === true && <PremiumUpsellGradientBackground useTier0UpsellContent={useTier0UpsellContent} />}
{r13}
</>;
}
return null;
}, [analyticsLocations, callback, callback2, channel, rowSize, containerWidth, setting, emojiPickerListRef, useTier0UpsellContent]);
const showNitroUpsellCallback = useShowNitroUpsellCallback();
const { shouldShowUpsell, onShowNitroUpsell } = showNitroUpsellCallback;
if (emojiSections.length === 0) {
return <EmojiPickerListComponentEmpty inActionSheet insetTop={insetTop} insetBottom={insetBottom} />;
}
return <>
{nativeAndroidEmojiPickerEnabled ? <EmojiPickerListComponent_android analyticsLocations={analyticsLocations} animateEmoji={setting} bottomSheetIndex={bottomSheetIndex} categoryIndexActive={categoryIndexActive} data={emojiPickerData} guildId={guildId == null ? channel?.guild_id : guildId} inPortalKeyboard={inPortalKeyboard} onPressEmoji={callback} onLongPressEmoji={callback2} onShowNitroUpsell={onShowNitroUpsell} paddingBottom={insetBottom} paddingTop={insetTop} ref={emojiPickerListRef} renderItem={callback3} useTier0UpsellContent={useTier0UpsellContent} /> : <EmojiPickerListComponent_ios analyticsLocations={analyticsLocations} animateEmoji={setting} bottomSheetIndex={bottomSheetIndex} categoryIndexActive={categoryIndexActive} data={emojiPickerData} guildId={guildId == null ? channel?.guild_id : guildId} inPortalKeyboard={inPortalKeyboard} onPressEmoji={callback} onLongPressEmoji={callback2} onShowNitroUpsell={onShowNitroUpsell} paddingBottom={insetBottom} paddingTop={insetTop} ref={emojiPickerListRef} renderItem={callback3} useTier0UpsellContent={useTier0UpsellContent} />}
<PremiumEmojiFeatureUpsell bottomSheetIndex={bottomSheetIndex} inPortalKeyboard={inPortalKeyboard} shouldShow={shouldShowUpsell} />
</>;
});
export default r41;
@@ -0,0 +1,109 @@
// Metro module 9399 (f9400).
import { forwardRef, useRef, useEffect, useCallback, useImperativeHandle, useMemo } from "react";
import EmojiStore from "../../../emojis/EmojiStore";
import { EmojiCategoryTypes } from "../../EmojiPickerConstants";
import { IMAGE_SIZE } from "./EmojiPickerListConstants";
import { PADDING_VERTICAL } from "../../../expression_picker/ExpressionPickerConstants";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import * as _ReanimatedRexport from "../../../reanimated/ReanimatedRexport";
import ReanimatedRexport, { useAnimatedReaction } from "../../../reanimated/ReanimatedRexport";
import Module9400, { Commands } from "../../../../_bundle/Module9400";
import { createBottomSheetScrollableComponent, SCROLLABLE_TYPE } from "../../../../_bundle/Module5245";
import * as _MetaQuestUtils_android from "../../../device/MetaQuestUtils.android";
import UnicodeEmojis from "../../../emojis/UnicodeEmojis";
import PortalToNativeView_native from "../../../portals/PortalToNativeView.native";
import { PremiumSearchUpsell } from "./EmojiPickerPremiumSearchUpsell";
const useStyles = createStyles({
container: {
flex: 1
}
});
const BottomSheetScrollableComponent = createBottomSheetScrollableComponent(SCROLLABLE_TYPE.SCROLLVIEW, ReanimatedRexport.createAnimatedComponent(Module9400));
const isMetaQuest = _MetaQuestUtils_android.isMetaQuest();
const __initData = {
code: "function EmojiPickerListComponentAndroidTsx1(){const{bottomSheetIndex}=this.__closure;return bottomSheetIndex.get();}"
};
const __initData2 = {
code: "function EmojiPickerListComponentAndroidTsx2(index){const{inPortalKeyboard,IS_META_QUEST,runOnJS,scrollingEnabled}=this.__closure;if(!inPortalKeyboard||index<0||IS_META_QUEST){return;}if(index===0){runOnJS(scrollingEnabled)(false);}else if(index===1){runOnJS(scrollingEnabled)(true);}}"
};
const r59 = forwardRef(function({ analyticsLocations, bottomSheetIndex, categoryIndexActive, data, animateEmoji, guildId, inPortalKeyboard, paddingTop, paddingBottom, onPressEmoji, onLongPressEmoji, onShowNitroUpsell, useTier0UpsellContent }, a1) {
let callback, callback2;
callback = void 0;
callback2 = void 0;
const styles = useStyles();
const ref = useRef(null);
useEffect(() => {
if (ref.current != null && data.hasGuildData) {
Commands.refreshEmojis(ref.current);
}
}, [ref, data]);
callback = useCallback((a0) => {
if (ref.current != null) {
Commands.scrollingEnabled(ref.current, a0);
}
}, []);
const H = () => bottomSheetIndex.get();
H.__closure = {
bottomSheetIndex
};
H.__workletHash = 10656486632396;
H.__initData = __initData;
const D = function D(a0) {
if (!((inPortalKeyboard ? a0 < 0 : !inPortalKeyboard) || isMetaQuest)) {
if (a0 === 0) {
_ReanimatedRexport.runOnJS(callback)(false);
} else if (a0 === 1) {
_ReanimatedRexport.runOnJS(callback)(true);
}
}
};
D.__closure = {
inPortalKeyboard,
IS_META_QUEST: isMetaQuest,
runOnJS: _ReanimatedRexport.runOnJS,
scrollingEnabled: callback
};
D.__workletHash = 2460528828147;
D.__initData = __initData2;
useAnimatedReaction(H, D);
callback2 = useCallback(({ emojiId, emojiName }) => emojiId != null ? EmojiStore.getDisambiguatedEmojiContext(guildId).getById(emojiId) : UnicodeEmojis.getByName(emojiName), [guildId]);
const callback3 = useCallback((a0) => {
const r6 = callback2(a0.nativeEvent);
if (r6 != null) {
onPressEmoji(r6);
}
}, [onPressEmoji, callback2]);
const callback4 = useCallback((a0) => {
const r6 = callback2(a0.nativeEvent);
if (r6 != null) {
onLongPressEmoji(r6);
}
}, [onLongPressEmoji, callback2]);
const callback5 = useCallback((a0) => {
categoryIndexActive.set(a0.nativeEvent.index);
}, [categoryIndexActive]);
const callback6 = useCallback((a0) => {
onShowNitroUpsell(a0.nativeEvent.showNitroUpsell);
}, [onShowNitroUpsell]);
useImperativeHandle(a1, () => ({
scrollToHeaderIndex: ({ index, animated = true }) => {
if (ref.current != null) {
Commands.scrollToHeaderIndex(ref.current, index, animated);
}
},
forceUpdate: () => {},
onStickyHeaderRendered: () => {}
}));
return <>
<BottomSheetScrollableComponent config={useMemo(() => ({
animateEmoji,
scrollFastOptimizationEnabled: true,
scrollFastVelocity: 8000,
disableAnimationsOnScroll: true
}), [animateEmoji])} emojiData={data} emojiMargin={PADDING_VERTICAL} emojiSize={IMAGE_SIZE} onPressEmoji={callback3} onLongPressEmoji={callback4} onStickyHeaderRender={callback5} onShowNitroUpsell={callback6} paddingTop={paddingTop} paddingBottom={paddingBottom} useTier0UpsellContent={useTier0UpsellContent} ref={ref} style={styles.container} />
{useMemo(() => data.hasSearchUpsell ? <PortalToNativeView_native portalId={EmojiCategoryTypes.PREMIUM_UPSELL}>
<PremiumSearchUpsell guildId={guildId} analyticsLocations={analyticsLocations} useTier0UpsellContent={useTier0UpsellContent} />
</PortalToNativeView_native> : null, [guildId, analyticsLocations, useTier0UpsellContent, data.hasSearchUpsell])}
</>;
});
export default r59;
@@ -0,0 +1,82 @@
// Metro module 9401 (f9402).
import { forwardRef, useRef, useMemo, useCallback, useImperativeHandle } from "react";
import { LABEL_BOTTOM_PADDING, LABEL_HEIGHT, LABEL_TOP_PADDING, ROW_HEIGHT } from "./EmojiPickerListConstants";
import { EmojiPickerItemType } from "./data/useEmojiPickerData";
import { EMOJI_PICKER_PREMIUM_UPSELL_HEIGHT } from "./EmojiPickerPremiumSearchUpsell";
import useEmojiPickerViewableItemsCallback from "../../../premium/roadblocks/native/hooks/useEmojiPickerViewableItemsCallback";
import { useIsPortalKeyboardInModal } from "../../../keyboard/native/PortalKeyboardModalContext";
import { BottomSheetFlashList } from "../../../../_bundle/noop_6676";
const r26 = forwardRef(function(a0, a1) {
const { categoryIndexActive, data: data2 } = a0;
const { data, headerIndices } = data2;
const { onShowNitroUpsell, paddingTop, paddingBottom, renderItem } = a0;
const ref = useRef(null);
const memo = useMemo(() => ({
paddingTop,
paddingBottom
}), [paddingTop, paddingBottom]);
const callback = useCallback((a0) => a0.type, []);
const callback2 = useCallback((a0, a1) => `${a0.type}-${a1}`, []);
const callback3 = useCallback((a0, a1) => {
L9: {
const type = a1.type;
if (EmojiPickerItemType.PLACEHOLDER === type) {
a0.size = 0;
} else if (EmojiPickerItemType.TITLE === type) {
a0.size = LABEL_HEIGHT + LABEL_TOP_PADDING + LABEL_BOTTOM_PADDING;
} else {
if (EmojiPickerItemType.EMOJI_ROW !== type && EmojiPickerItemType.EMOJI_ROW_NSFW !== type) {
if (EmojiPickerItemType.FOOTER_UPSELL !== type) {
break L9;
}
a0.size = EMOJI_PICKER_PREMIUM_UPSELL_HEIGHT;
break L9;
}
a0.size = ROW_HEIGHT;
}
}
}, []);
useImperativeHandle(a1, () => ({
scrollToHeaderIndex: ({ index, animated = true }) => {
const current = ref.current;
if (current != null) {
let index2 = headerIndices[index];
if (index2 == null) {
index2 = 0;
}
current.scrollToIndex({
index: index2,
animated
});
}
},
forceUpdate: () => {
const current = ref.current;
if (current.forceUpdate != null) {
current.forceUpdate();
}
},
onStickyHeaderRendered: (a0) => {
let length2;
const length = headerIndices.length;
let r4 = 0;
const r6 = 0 < length;
let r1 = 0;
let r2 = 0;
if (r6) {
do {
const r10 = headerIndices[r1];
const r3 = r1;
const r0 = a0 >= r10 ? r3 : r2;
r1 = r3 + 1;
length2 = headerIndices.length;
r2 = r0;
r4 = r2;
} while (r1 < length2);
}
categoryIndexActive.set(r4);
}
}));
return <BottomSheetFlashList contentContainerStyle={memo} data={data} getItemType={callback} keyboardShouldPersistTaps="always" keyExtractor={callback2} onViewableItemsChanged={useEmojiPickerViewableItemsCallback(onShowNitroUpsell).onViewableItemsChanged} overrideItemLayout={callback3} preventNativeModalDismiss={useIsPortalKeyboardInModal()} ref={ref} renderItem={renderItem} stickyHeaderIndices={headerIndices} />;
});
export default r26;
@@ -0,0 +1,41 @@
// Metro module 9392 (f9393).
import * as Module19 from "react";
import { useMemo } from "react";
import { ScrollView } from "react-native";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { useSearchEmptySource } from "../../../../design/components/Illustration/native/redesign/generated/SearchEmpty";
import { useModalDismissGuardRefreshControl } from "../../../keyboard/native/useModalDismissGuardRefreshControl";
import { BottomSheetScrollView } from "../../../../_bundle/Module5245";
import { RefreshEmptyState } from "../../../../design/void/native";
import { intl, t } from "../../../../intl/index.native";
const useStyles = createStyles({
emptyStateContainer: {
padding: 0,
flex: 1
},
emptyStateBody: {
color: Module712.colors.TEXT_SUBTLE
},
emptyStateImage: {
marginBottom: Module712.space.PX_8,
marginTop: 0
}
});
const r39 = Module19.memo(function EmojiPickerListComponentEmpty(props) {
const { inActionSheet, insetTop, insetBottom } = props;
const styles = useStyles();
const memo = useMemo(() => ({
marginBottom: insetBottom,
marginTop: insetTop,
flex: 1
}), [insetBottom, insetTop]);
const searchEmptySource = useSearchEmptySource();
const modalDismissGuardRefreshControl = useModalDismissGuardRefreshControl();
return inActionSheet ? <BottomSheetScrollView contentContainerStyle={memo} keyboardShouldPersistTaps="always" refreshControl={inActionSheet ? modalDismissGuardRefreshControl : void 0}>
<RefreshEmptyState source={searchEmptySource} body={intl.string(t.IxxiKF)} bodyStyle={styles.emptyStateBody} containerStyle={styles.emptyStateContainer} imageStyle={styles.emptyStateImage} />
</BottomSheetScrollView> : <ScrollView contentContainerStyle={memo} keyboardShouldPersistTaps="always" refreshControl={inActionSheet ? modalDismissGuardRefreshControl : void 0}>
<RefreshEmptyState source={searchEmptySource} body={intl.string(t.IxxiKF)} bodyStyle={styles.emptyStateBody} containerStyle={styles.emptyStateContainer} imageStyle={styles.emptyStateImage} />
</ScrollView>;
});
export default r39;
@@ -0,0 +1,60 @@
// Metro module 9385 (f9386).
import { memo } from "react";
import { View } from "react-native";
import * as _EmojiPickerListConstants from "./EmojiPickerListConstants";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { Icon } from "../../../../design/void/native";
import Module7934 from "../../../../_bundle/Module7934";
import { Text } from "../../../../design/components/Text/native/Text";
import { intl, t } from "../../../../intl/index.native";
import { PremiumUpsellGradientBackground } from "../../../premium/roadblocks/native/views/PremiumUpsellGradientBackground";
const { LABEL_BOTTOM_PADDING, LABEL_TOP_PADDING, NSFW_ROW_HEIGHT } = _EmojiPickerListConstants;
const useStyles = createStyles({
section: {
justifyContent: "center",
overflow: "hidden",
backgroundColor: Module712.colors.MOBILE_EXPRESSION_PICKER_BACKGROUND_DEFAULT,
paddingTop: LABEL_TOP_PADDING,
paddingBottom: LABEL_BOTTOM_PADDING
},
nsfwContainer: {
flexDirection: "row",
height: NSFW_ROW_HEIGHT,
alignItems: "center",
justifyContent: "center",
borderRadius: Module712.radii.sm,
marginLeft: 12,
marginRight: 12,
backgroundColor: Module712.colors.BACKGROUND_MOD_NORMAL
},
nsfwText: {
marginLeft: 4,
textAlign: "center"
}
});
const r49 = memo(function() {
const styles = useStyles();
return <View style={styles.nsfwContainer}>
<Icon source={Module7934} size={Icon.Sizes.SMALL} />
<Text style={styles.nsfwText} variant="text-sm/normal" color="interactive-text-active">
{intl.string(t.SLzV5z)}
</Text>
</View>;
});
const r52 = memo(function(a0) {
const label = a0.label;
let isSectionNitroLocked = a0.isSectionNitroLocked;
const useTier0UpsellContent = a0.useTier0UpsellContent;
const props = {
style: useStyles().section,
children: null
};
if (isSectionNitroLocked) {
isSectionNitroLocked = <PremiumUpsellGradientBackground useTier0UpsellContent={useTier0UpsellContent} />;
}
props.children = [isSectionNitroLocked, label !== "" ? <Text lineClamp={1} color="interactive-text-default" variant="heading-sm/semibold">{label}</Text> : null];
return <View {...props} />;
});
export { r49 as NSFWRow };
export { r52 as Section };
@@ -0,0 +1,22 @@
// Metro module 9339 (f9340).
import { PADDING_VERTICAL } from "../../../expression_picker/ExpressionPickerConstants";
const r2 = 2 * PADDING_VERTICAL;
const r16 = {
EMOJI: 0,
0: "EMOJI",
NSFW: 1,
1: "NSFW",
NATIVE_SECTION: 2,
2: "NATIVE_SECTION"
};
const r21 = {
NOTIFICATION: "notification"
};
export const IMAGE_SIZE = 33;
export const LABEL_TOP_PADDING = 8;
export const LABEL_HEIGHT = 16;
export const LABEL_BOTTOM_PADDING = 4;
export const ROW_HEIGHT = 33 + r2;
export { r16 as EmojiPickerRenderingDataType };
export const NSFW_ROW_HEIGHT = 40;
export { r21 as EmojiPickerSource };
@@ -0,0 +1,207 @@
// Metro module 9386 (f9387).
import { memo } from "react";
import { View, StyleSheet } from "react-native";
import ThemeStore from "../../../user_settings/ThemeStore";
import { IMAGE_SIZE, ROW_HEIGHT } from "./EmojiPickerListConstants";
import { PADDING_VERTICAL } from "../../../expression_picker/ExpressionPickerConstants";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { isAndroid } from "../../../../utils/PlatformUtils";
import Module689 from "../../../../_bundle/Module689";
import AvatarUtils from "../../../../utils/AvatarUtils";
import { LockIcon } from "../../../../design/components/Icon/native/redesign/generated/LockIcon";
import { PressableOpacity } from "../../../../design/void/Pressables/native/Pressables";
import FastImage from "../../../../components_native/common/FastImage";
import { isThemeDark } from "../../../../design/shared";
import Module5207 from "../../../../_bundle/Module5207";
import Module5208 from "../../../../_bundle/Module5208";
import { LegacyText } from "../../../../design/void/native";
import EmojiPickerListRowView from "./EmojiPickerListRowView";
import { HermesBuiltin } from "../../../../_hermes/prelude";
let useStyles, EmojiItem, Component, Component2;
const EmojiItemLockedOverlay = function EmojiItemLockedOverlay() {
const styles = useStyles();
return <View style={styles.lockContainer}>
<LockIcon style={styles.lock} />
</View>;
};
EmojiItem = function EmojiItem(props) {
let uri;
const { emoji, category } = props;
let disabled = props.disabled;
const { onPressEmoji: onPressEmoji2, onLongPressEmoji: onLongPressEmoji2 } = props;
let animateEmoji = props.animateEmoji;
const isSectionNitroLocked = props.isSectionNitroLocked;
const styles = useStyles();
if (emoji.id == null) {
let url = emoji.url;
if (url == null) {
url = "";
}
uri = url;
} else {
if (animateEmoji) {
animateEmoji = emoji.animated;
}
uri = AvatarUtils.getEmojiURL({
id: emoji.id,
animated: animateEmoji,
size: IMAGE_SIZE
});
}
if (disabled) {
disabled = !isSectionNitroLocked;
}
const props2 = {
accessibilityRole: "button",
accessibilityLabel: emoji.name,
style: [styles.surrogatesFrame, disabled ? styles.disabledOverlay : disabled],
onPress: () => onPressEmoji2(emoji, category),
onLongPress: () => onLongPressEmoji2(emoji),
children: null
};
const children = [emoji.id != null ? <FastImage resizeMode="contain" style={styles.image} placeholder={isThemeDark(ThemeStore.theme) ? Module5207 : Module5208} source={{
uri
}} usesSmallCache /> : <LegacyText allowFontScaling={false} style={styles.surrogates}>{emoji.surrogates}</LegacyText>, ,];
if (disabled) {
disabled = <EmojiItemLockedOverlay />;
}
children[1] = disabled;
props2.children = children;
return <PressableOpacity {...props2} />;
};
useStyles = createStyles({
image: {
height: IMAGE_SIZE,
width: IMAGE_SIZE
},
surrogatesFrame: {
height: IMAGE_SIZE,
width: IMAGE_SIZE,
alignItems: "center",
justifyContent: "center"
},
disabledOverlay: {
borderRadius: Module712.radii.sm,
overflow: "hidden"
},
surrogates: {
fontSize: isAndroid() ? 26 : 28,
color: Module712.colors.TEXT_DEFAULT
},
row: {
height: ROW_HEIGHT,
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between"
},
lockContainer: {
backgroundColor: Module689("#000000").alpha(0.2).hex(),
alignItems: "center",
justifyContent: "center",
...StyleSheet.absoluteFillObject
},
lock: {
width: 16,
height: 16,
tintColor: "white"
}
});
Component = memo(function({ emojis, emojisDisabled, category: category2, rowSize, containerWidth, row, onPressEmoji: onPressEmoji3, onLongPressEmoji: onLongPressEmoji3, animateEmoji, isSectionNitroLocked }) {
let url2;
const styles = useStyles();
const items = [];
const r12 = row * rowSize;
const r27 = r12 + rowSize;
let r29 = r12;
if (r29 < r27) {
do {
const r20 = emojis[r29];
const r30 = r29;
if (r20 === void 0) {
items.push({
id: null,
name: "",
url: "",
animated: false,
disabled: false
});
} else {
let id = r20.id;
if (id == null) {
id = null;
}
let name = r20.name;
if (name == null) {
name = "";
}
if (r20.id == null) {
let url = r20.url;
if (url == null) {
url = "";
}
url2 = url;
} else {
url2 = AvatarUtils.getEmojiURL({
id: r20.id,
animated: animateEmoji ? r20.animated : animateEmoji,
size: IMAGE_SIZE
});
}
items.push({
id,
name,
url: url2,
animated: r20.animated === true && animateEmoji,
disabled: r20.id != null && emojisDisabled.has(r20.id)
});
}
r29 = r30 + 1;
} while (r29 < r12 + rowSize);
}
return <EmojiPickerListRowView style={styles.row} rowData={{
rowContentWidth: containerWidth,
rowContentPaddingVertical: PADDING_VERTICAL,
itemSize: IMAGE_SIZE,
items,
isSectionNitroLocked
}} onPressEmoji={(c26431_0) => {
const r7 = emojis.find((emoji) => emoji.name === c26431_0.nativeEvent.emojiName);
if (r7 != null) {
onPressEmoji3(r7, category2);
}
}} onLongPressEmoji={(c26432_0) => {
const r7 = emojis.find((emoji) => emoji.name === c26432_0.nativeEvent.emojiName);
if (r7 != null) {
onLongPressEmoji3(r7);
}
}} />;
});
Component2 = memo(function({ emojis: emojis2, emojisDisabled, category: category3, rowSize, row, onPressEmoji: onPressEmoji4, onLongPressEmoji: onLongPressEmoji4, animateEmoji, isSectionNitroLocked }) {
const styles = useStyles();
const r5 = [];
const r7 = row * rowSize;
const r24 = r7 + rowSize;
let r25 = r7;
if (r25 < r24) {
do {
const emoji2 = emojis2[r25];
const key = r25;
if (emoji2 === void 0) {
r5.push(<View key={key} style={styles.image} />);
} else {
r5.push(<EmojiItem key={key} emoji={emoji2} category={category3} animateEmoji={animateEmoji} disabled={emoji2.id != null && emojisDisabled.has(emoji2.id)} onPressEmoji={onPressEmoji4} onLongPressEmoji={onLongPressEmoji4} isSectionNitroLocked={isSectionNitroLocked} />);
}
r25 = key + 1;
} while (r25 < r7 + rowSize);
}
return <View style={styles.row}>{r5}</View>;
});
const r81 = memo(function(a0) {
const { nativeRow = isAndroid(), ...rest } = a0;
return nativeRow ? <Component {...rest} /> : <Component2 {...HermesBuiltin.copyDataProperties({}, a0, {
__proto__: null,
nativeRow: 0
})} />;
});
export { r81 as EmojiPickerListRow };
@@ -0,0 +1,9 @@
// Metro module 9387 (f9388).
import * as _Module17 from "react-native";
import { isAndroid } from "../../../../utils/PlatformUtils";
import Module9388 from "../../../../_bundle/Module9388";
let View = _Module17.View;
if (isAndroid()) {
View = Module9388;
}
export default View;
@@ -0,0 +1,156 @@
// Metro module 9389 (f9390).
import { memo, useCallback, useRef, useEffect } from "react";
import { View } from "react-native";
import "../../../../stores/UserStore";
import "../../../../Constants";
import { SubscriptionPlans } from "../../../premium/PremiumConstants";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { getTierDisplayNameByPlanId } from "../../../../utils/PremiumUtils";
import { Icon } from "../../../../design/void/native";
import Module9390 from "../../../../_bundle/Module9390";
import { Text } from "../../../../design/components/Text/native/Text";
import { intl, t } from "../../../../intl/index.native";
import { PressableOpacity } from "../../../../design/void/Pressables/native/Pressables";
function $mk82411($env) {
return () => {
const r5 = $env;
const r1 = r5[3];
if (!r1.current) {
r1.current = true;
const r6 = $env.$parent;
const r4 = (0, r6[1])(r6[2][8]);
const PREMIUM_UPSELL_VIEWED = r6[6].PREMIUM_UPSELL_VIEWED;
const page = r5[0] != null ? r6[7].GUILD_CHANNEL : r6[7].DM_CHANNEL;
const r25 = r5[2];
const r26 = r6[9];
r4.track(PREMIUM_UPSELL_VIEWED, {
type: r6[10].EMOJI_PICKER_SEARCH,
location: {
page,
section: r6[8].EMOJI_PICKER_POPOUT
},
location_stack: r5[1],
sku_id: r25 ? r26.TIER_0 : r26.TIER_2
});
}
};
}
function $mk82412($env) {
return () => {
const r5 = $env.$parent;
const currentUser = r5[5].getCurrentUser();
if (!(currentUser == null || (0, r5[1])(r5[2][9]).canUseEmojisEverywhere(currentUser))) {
const r13 = $env;
const r14 = r5[1];
const r15 = r5[2];
r14(r15[10]).hideActionSheet();
const r21 = r14(r15[11]);
const r24 = r13[1];
const PremiumFeatureCardOrder = (0, r5[0])(r15[12]).PremiumFeatureCardOrder;
r21({
analyticsLocations: r13[0],
premiumFeatureCardOrder: r24 ? PremiumFeatureCardOrder.TIER_0_LEADING : PremiumFeatureCardOrder.TIER_2_LEADING
});
}
};
}
let env6186 = {};
const useStyles = createStyles({
container: {
paddingTop: Module712.space.PX_8
},
premiumSearchUpsell: {
height: 56,
padding: Module712.space.PX_8,
borderRadius: Module712.radii.xs,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWEST,
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
alignContent: "center"
},
premiumSearchUpsellContent: {
flex: 0.8,
flexDirection: "row"
},
nitroIcon: {
marginRight: 8,
alignSelf: "center"
}
});
const r62 = memo(function(a0) {
let env17186;
let env17187;
const styles = useStyles();
const r21 = env17186 = {
$parent: env6186
};
env17186[0] = void 0;
env17186[1] = void 0;
const analyticsLocations = a0.analyticsLocations;
env17186[0] = analyticsLocations;
const useTier0UpsellContent = a0.useTier0UpsellContent;
env17186[1] = useTier0UpsellContent;
const callback = useCallback($mk82412(r21), [analyticsLocations, useTier0UpsellContent]);
const r24 = env17187 = {
$parent: env6186
};
env17187[0] = void 0;
env17187[1] = void 0;
env17187[2] = void 0;
const guildId = a0.guildId;
env17187[0] = guildId;
const analyticsLocations2 = a0.analyticsLocations;
env17187[1] = analyticsLocations2;
const useTier0UpsellContent2 = a0.useTier0UpsellContent;
env17187[2] = useTier0UpsellContent2;
env17187[3] = void 0;
const ref = useRef(false);
env17187[3] = ref;
useEffect($mk82411(r24), [analyticsLocations2, guildId, useTier0UpsellContent2, ref]);
return <View style={styles.container} collapsable={false}>
<PressableOpacity style={styles.premiumSearchUpsell} accessibilityRole="button" onPress={callback}>
<View style={styles.premiumSearchUpsellContent}>
<Icon style={styles.nitroIcon} source={Module9390} disableColor size={Icon.Sizes.MEDIUM} />
<Text lineClamp={2} variant="text-sm/medium" color="interactive-text-active">
{a0.useTier0UpsellContent ? intl.formatToPlainString(t.kWBwlJ, {
planName: getTierDisplayNameByPlanId(SubscriptionPlans.PREMIUM_MONTH_TIER_0)
}) : intl.string(t["5t3lw+"])}
</Text>
</View>
<Text variant="text-sm/medium" color="text-link">
{a0.useTier0UpsellContent ? intl.string(t["9CM5v9"]) : intl.string(t.pj0XBN)}
</Text>
</PressableOpacity>
</View>;
});
export const EMOJI_PICKER_PREMIUM_UPSELL_HEIGHT = 56;
export function useEmojiPickerPremiumSearchUpsellViewed(a0) {
let env17184;
const r2 = env17184 = {
$parent: env6186
};
const guildId = a0.guildId;
env17184[0] = guildId;
const analyticsLocations = a0.analyticsLocations;
env17184[1] = analyticsLocations;
const useTier0UpsellContent = a0.useTier0UpsellContent;
env17184[2] = useTier0UpsellContent;
env17184[3] = void 0;
const ref = useRef(false);
env17184[3] = ref;
useEffect($mk82411(r2), [analyticsLocations, guildId, useTier0UpsellContent, ref]);
}
export function useEmojiPickerPremiumSearchUpsellClick(a0) {
let env17185;
const r0 = env17185 = {
$parent: env6186
};
const analyticsLocations = a0.analyticsLocations;
env17185[0] = analyticsLocations;
const useTier0UpsellContent = a0.useTier0UpsellContent;
env17185[1] = useTier0UpsellContent;
return useCallback($mk82412(r0), [analyticsLocations, useTier0UpsellContent]);
}
export { r62 as PremiumSearchUpsell };
@@ -0,0 +1,258 @@
// Metro module 9430 (f9431).
import * as Module19 from "react";
import { useRef, useMemo, useCallback, useEffect } from "react";
import { EmojiCategoryTypes } from "../../../EmojiPickerConstants";
import { AnalyticEvents, AnalyticsPages, EXPRESSION_FOOTER_HEIGHT, CATEGORY_ICON_SIZE } from "../../../../../Constants";
import { ExpressionPickerViewType } from "../../../../expression_picker/ExpressionPickerConstants";
import { createStyles } from "../../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../../_bundle/Module712";
import * as _ReanimatedRexport from "../../../../reanimated/ReanimatedRexport";
import { useSharedValue, useAnimatedReaction, useDerivedValue } from "../../../../reanimated/ReanimatedRexport";
import AnalyticsUtils from "../../../../../utils/AnalyticsUtils";
import { triggerHapticFeedback } from "../../../../haptics/HapticUtils.native";
import HapticFeedbackTypes from "../../../../haptics/HapticFeedbackTypes";
import EmojiPickerCategoriesItem from "./EmojiPickerCategoriesItem";
import useExpressionPickerCategoriesPlaceholderConfig from "../../../../expression_picker/native/categories/useExpressionPickerCategoriesPlaceholderConfig";
import { GestureDetector, Gesture } from "../../../../../_bundle/Module5273";
import ExpressionPickerCategories from "../../../../expression_picker/native/categories/ExpressionPickerCategories";
import FastestList_android from "../../../../fastest_list/FastestList.android";
import EmojiPickerCategoriesUnicodeShortcutItem from "./EmojiPickerCategoriesUnicodeShortcutItem";
import EmojiPickerCategoriesBackspaceItem from "./EmojiPickerCategoriesBackspaceItem";
const useStyles = createStyles({
list: {
flex: 1,
height: EXPRESSION_FOOTER_HEIGHT
},
listPlaceholder: {
backgroundColor: Module712.colors.BACKGROUND_MOD_MUTED
},
item: {
height: EXPRESSION_FOOTER_HEIGHT,
width: EXPRESSION_FOOTER_HEIGHT,
justifyContent: "center",
alignItems: "center"
},
keyboardItem: {
height: CATEGORY_ICON_SIZE,
width: CATEGORY_ICON_SIZE
}
});
const __initData = {
code: "function EmojiPickerCategoriesTsx1(){const{categoryIndexActive}=this.__closure;return categoryIndexActive.get();}"
};
const __initData2 = {
code: "function EmojiPickerCategoriesTsx2(categoryIndex,categoryIndexPrev){const{blockRef,EXPRESSION_FOOTER_HEIGHT,runOnJS,scrollToCategoryIndex}=this.__closure;const Ref=blockRef.get();if(categoryIndexPrev==null||categoryIndex===categoryIndexPrev||Ref==null){return;}const categoryScrollPos=categoryIndex*EXPRESSION_FOOTER_HEIGHT;if(categoryScrollPos>Ref.end||categoryScrollPos<Ref.start){runOnJS(scrollToCategoryIndex)(categoryIndex);}}"
};
const __initData3 = {
code: "function EmojiPickerCategoriesTsx3(){const{inPortalKeyboard,bottomSheetIndex}=this.__closure;return inPortalKeyboard?bottomSheetIndex.get()===1:bottomSheetIndex.get()===0;}"
};
const __initData4 = {
code: "function EmojiPickerCategoriesTsx4(){const{bottomSheetOpen}=this.__closure;return bottomSheetOpen.get();}"
};
const __initData5 = {
code: "function EmojiPickerCategoriesTsx5(open){const{runOnJS,handleScrollToCategoryIndex}=this.__closure;if(!open){return;}runOnJS(handleScrollToCategoryIndex)();}"
};
const r52 = Module19.memo(function EmojiPickerCategories(props) {
let callback, derivedValue, ref3, ref4, callback2, callback3;
const { bottomSheetRef, bottomSheetIndex, categories, categoryIndexActive, style, emojiPickerListRef, onBackspace, portalHostName = "expression-footer", inPortalKeyboard = false } = props;
let c17213_5 = inPortalKeyboard;
const { renderAhead, isSearching = false } = props;
let c17213_6 = isSearching;
const onClearSearch = props.onClearSearch;
callback = void 0;
derivedValue = void 0;
ref3 = void 0;
ref4 = void 0;
callback2 = void 0;
callback3 = void 0;
const styles = useStyles();
const sharedValue = useSharedValue(void 0);
const Ref = useRef(void 0);
const ref2 = useRef(null);
const memo = useMemo(() => {
const length = categories.length;
let r0 = 0;
if (0 < length) {
do {
const firstUnicodeCategory = categories[r0];
const type = firstUnicodeCategory.type;
const UNICODE = EmojiCategoryTypes.UNICODE;
const firstUnicodeCategoryIndex = r0;
if (type === UNICODE) {
return {
sections: [categories.length],
firstUnicodeCategory,
firstUnicodeCategoryIndex
};
}
r0 = firstUnicodeCategoryIndex + 1;
} while (r0 < categories.length);
}
return {
sections: [categories.length]
};
}, [categories]);
const { sections, firstUnicodeCategory, firstUnicodeCategoryIndex } = memo;
callback = useCallback((a0) => {
if (Ref.current != null) {
const current = ref2.current;
if (current != null) {
current.scrollToLocation({
section: 0,
item: a0,
animated: false
});
}
}
}, []);
const w = () => categoryIndexActive.get();
w.__closure = {
categoryIndexActive
};
w.__workletHash = 2293356797932;
w.__initData = __initData;
const j = function j(a0, a1) {
const r8 = sharedValue.get();
if (a1 != null && a0 !== a1 && r8 != null) {
const r11 = a0 * EXPRESSION_FOOTER_HEIGHT;
if (r11 > r8.end || r11 < r8.start) {
_ReanimatedRexport.runOnJS(callback)(a0);
}
}
};
j.__closure = {
blockRef: sharedValue,
EXPRESSION_FOOTER_HEIGHT,
runOnJS: _ReanimatedRexport.runOnJS,
scrollToCategoryIndex: callback
};
j.__workletHash = 7148256102464;
j.__initData = __initData2;
useAnimatedReaction(w, j);
const callback4 = useCallback((a0) => {
if (Ref.current != null) {
sharedValue.set({
start: a0.nativeEvent.contentOffset.x,
end: a0.nativeEvent.contentOffset.x + Ref.current
});
}
}, [sharedValue]);
const X = () => {
const r7 = bottomSheetIndex.get();
return c17213_5 ? r7 === 1 : r7 === 0;
};
X.__closure = {
inPortalKeyboard,
bottomSheetIndex
};
X.__workletHash = 15413192314561;
X.__initData = __initData3;
derivedValue = useDerivedValue(X);
ref3 = useRef(void 0);
ref4 = useRef(false);
callback2 = useCallback(function(current2 = ref3.current) {
if (current2 != null) {
if (!derivedValue.get() && c17213_5) {
if (bottomSheetRef != null) {
const current = bottomSheetRef.current;
if (current != null) {
current.expandActionSheet();
}
}
ref3.current = current2;
ref4.current = false;
} else if (c17213_6 && onClearSearch != null) {
ref3.current = current2;
ref4.current = true;
onClearSearch();
} else if (emojiPickerListRef.current != null) {
ref3.current = void 0;
ref4.current = false;
emojiPickerListRef.current.scrollToHeaderIndex({
index: current2
});
}
return void 0;
}
}, [derivedValue, bottomSheetRef, emojiPickerListRef, inPortalKeyboard, isSearching, onClearSearch]);
const B = () => derivedValue.get();
B.__closure = {
bottomSheetOpen: derivedValue
};
B.__workletHash = 13172461706889;
B.__initData = __initData4;
const z = function z(a0) {
if (a0) {
_ReanimatedRexport.runOnJS(callback2)();
}
};
z.__closure = {
runOnJS: _ReanimatedRexport.runOnJS,
handleScrollToCategoryIndex: callback2
};
z.__workletHash = 13670816929775;
z.__initData = __initData5;
useAnimatedReaction(B, z);
useEffect(() => {
if (!c17213_6 && ref4.current && ref3.current != null) {
const current = ref3.current;
ref3.current = void 0;
ref4.current = false;
categoryIndexActive.set(current);
const current2 = emojiPickerListRef.current;
if (current2 != null) {
current2.scrollToHeaderIndex({
index: current
});
}
}
}, [isSearching, categoryIndexActive, emojiPickerListRef]);
callback3 = useCallback((a0, a1) => {
if (a1.type === EmojiCategoryTypes.GUILD) {
const guild = a1.guild;
if (guild != null) {
AnalyticsUtils.track(AnalyticEvents.EXPRESSION_PICKER_CATEGORY_SELECTED, {
location: {
page: AnalyticsPages.EXPRESSION_PICKER
},
tab: ExpressionPickerViewType.EMOJI,
guild_id: guild.id
});
}
}
callback2(a0);
triggerHapticFeedback(HapticFeedbackTypes.IMPACT_LIGHT);
}, [callback2]);
const callback5 = useCallback((a0, a1) => {
callback3(a0, a1);
callback(a0);
}, [callback3, callback]);
const callback6 = useCallback((a0) => {
Ref.current = a0.nativeEvent.layout.width;
const r9 = sharedValue.get();
let start = r9?.start;
if (start == null) {
start = 0;
}
let r17 = r9?.start;
if (r17 == null) {
r17 = 0;
}
sharedValue.set({
start,
end: r17 + Ref.current
});
}, [sharedValue]);
const callback7 = useCallback((a0, a1) => <EmojiPickerCategoriesItem category={categories[a1]} categoryIndexActive={categoryIndexActive} index={a1} handlePressCategory={callback3} loadingStyle={styles.listPlaceholder} locked={categories[a1].isNitroLocked} style={styles.item} />, [categories, categoryIndexActive, callback3, styles]);
const expressionPickerCategoriesPlaceholderConfig = useExpressionPickerCategoriesPlaceholderConfig();
return <ExpressionPickerCategories portalHostName={portalHostName} style={style}>
<>
<GestureDetector gesture={useMemo(() => Gesture.Native().disallowInterruption(true), [])}>
<FastestList_android estimatedListSize="windowSize" horizontal itemSize={EXPRESSION_FOOTER_HEIGHT} keyboardShouldPersistTaps="always" listId={ExpressionPickerViewType.EMOJI} onLayout={callback6} onScroll={callback4} placeholderConfig={expressionPickerCategoriesPlaceholderConfig} Ref={ref2} renderAhead={renderAhead} renderItem={callback7} scrollReporting="callbacks" sections={sections} showsHorizontalScrollIndicator={false} style={styles.list} />
</GestureDetector>
{firstUnicodeCategory != null ? <EmojiPickerCategoriesUnicodeShortcutItem blockRef={sharedValue} category={firstUnicodeCategory} categoryIndex={firstUnicodeCategoryIndex} onPress={callback5} style={styles.item} /> : null}
{onBackspace != null ? <EmojiPickerCategoriesBackspaceItem style={styles.item} iconStyle={styles.keyboardItem} onBackspace={onBackspace} /> : null}
</>
</ExpressionPickerCategories>;
});
export default r52;
@@ -0,0 +1,42 @@
// Metro module 9448 (f9449).
import { useRef, useCallback, useEffect } from "react";
import { Pressable } from "react-native";
import { NODE_MARGIN } from "../../../../../Constants";
import { Interval, DelayedCall } from "../../../../../_bundle/Timeout";
import { intl, t } from "../../../../../intl/index.native";
import { BackspaceIcon } from "../../../../../design/components/Icon/native/redesign/generated/BackspaceIcon";
export default function EmojiPickerCategoriesBackspaceItem(props) {
const { style, iconStyle, onBackspace } = props;
const ref = useRef(new Interval());
const ref2 = useRef(new DelayedCall(500, function() {
ref2.current.cancel();
ref.current.start(50, onBackspace);
}));
const callback = useCallback(() => {
onBackspace();
ref2.current.delay();
}, [onBackspace]);
const callback2 = useCallback(() => {
ref2.current.cancel();
ref.current.stop();
onBackspace();
}, [onBackspace]);
useEffect(() => {
const current = ref.current;
const current2 = ref2.current;
return () => {
current.stop();
current2.cancel();
};
});
return <Pressable hitSlop={{
top: NODE_MARGIN,
bottom: NODE_MARGIN,
right: NODE_MARGIN,
left: NODE_MARGIN
}} style={style} accessibilityRole="keyboardkey" accessibilityLabel={intl.string(t["4SnBzF"])} delayLongPress={500} onPressOut={callback2} onLongPress={callback}>
<BackspaceIcon style={[iconStyle, {
opacity: 0.5
}]} />
</Pressable>;
};
@@ -0,0 +1,123 @@
// Metro module 9431 (f9432).
import { memo, useState, useCallback } from "react";
import { View } from "react-native";
import { EmojiCategoryTypes } from "../../../EmojiPickerConstants";
import * as _Constants from "../../../../../Constants";
import { CATEGORY_ICON_RIPPLE_CONFIG } from "../../../../../Constants";
import { createStyles } from "../../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../../_bundle/Module712";
import * as _ReanimatedRexport from "../../../../reanimated/ReanimatedRexport";
import ReanimatedRexport, { useAnimatedStyle, useAnimatedReaction } from "../../../../reanimated/ReanimatedRexport";
import * as _timing from "../../../../../design/animation/reanimated/timing/timing";
import * as _timingPresets from "../../../../../design/animation/reanimated/timing/timingPresets";
import { PressableOpacity } from "../../../../../design/void/Pressables/native/Pressables";
import GuildIcon, { GuildIconSizes } from "../../../../guild/native/GuildIcon";
import EmojiPickerCategoryIcon from "./EmojiPickerCategoryIcon";
import { LockIcon } from "../../../../../design/components/Icon/native/redesign/generated/LockIcon";
const { CATEGORY_ICON_SIZE, NODE_SIZE } = _Constants;
const useStyles = createStyles({
itemInner: {
justifyContent: "center",
alignItems: "center",
height: NODE_SIZE,
width: NODE_SIZE,
borderRadius: NODE_SIZE / 2
},
fadedItem: {
backgroundColor: Module712.colors.ICON_TRANSPARENT
},
activeItem: {
backgroundColor: Module712.colors.INTERACTIVE_BACKGROUND_ACTIVE
},
guildItem: {
height: CATEGORY_ICON_SIZE,
width: CATEGORY_ICON_SIZE,
borderRadius: CATEGORY_ICON_SIZE / 2
},
lockContainer: {
width: 12,
height: 12,
position: "absolute",
bottom: 0,
end: 0,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW,
borderRadius: Module712.radii.round,
alignItems: "center",
justifyContent: "center"
},
lock: {
width: 7.5,
height: 7.5,
tintColor: Module712.colors.TEXT_DEFAULT
}
});
const __initData = {
code: "function EmojiPickerCategoriesItemTsx1(){const{withTiming,categoryIndexActive,index,timingStandard,styleColorActive,styleColorTransparent}=this.__closure;return{opacity:withTiming(categoryIndexActive.get()===index?1:0.5,timingStandard),backgroundColor:categoryIndexActive.get()===index?styleColorActive:styleColorTransparent};}"
};
const __initData2 = {
code: "function EmojiPickerCategoriesItemTsx2(){const{categoryIndexActive,index}=this.__closure;return categoryIndexActive.get()===index;}"
};
const __initData3 = {
code: "function EmojiPickerCategoriesItemTsx3(active,prev){const{runOnJS,setIsSelected}=this.__closure;if(active!==prev){runOnJS(setIsSelected)(active);}}"
};
const r71 = memo(function EmojiPickerCategoriesItem(props) {
let setState;
const { category, categoryIndexActive, handlePressCategory, index, loadingStyle } = props;
let locked = props.locked;
const style = props.style;
setState = void 0;
const styles = useStyles();
const backgroundColor = styles.activeItem.backgroundColor;
const backgroundColor2 = styles.fadedItem.backgroundColor;
const T = () => ({
opacity: _timing.withTiming(categoryIndexActive.get() === index ? 1 : 0.5, _timingPresets.timingStandard),
backgroundColor: categoryIndexActive.get() === index ? backgroundColor : backgroundColor2
});
T.__closure = {
withTiming: _timing.withTiming,
categoryIndexActive,
index,
timingStandard: _timingPresets.timingStandard,
styleColorActive: backgroundColor,
styleColorTransparent: backgroundColor2
};
T.__workletHash = 3335518235623;
T.__initData = __initData;
const animatedStyle = useAnimatedStyle(T);
let selected;
[selected, setState] = useState(() => categoryIndexActive.get() === index);
const r46 = () => categoryIndexActive.get() === index;
r46.__closure = {
categoryIndexActive,
index
};
r46.__workletHash = 12996370114251;
r46.__initData = __initData2;
const E = function E(a0, a1) {
if (a0 !== a1) {
_ReanimatedRexport.runOnJS(setState)(a0);
}
};
E.__closure = {
runOnJS: _ReanimatedRexport.runOnJS,
setIsSelected: setState
};
E.__workletHash = 6056273557261;
E.__initData = __initData3;
useAnimatedReaction(r46, E);
const callback = useCallback(() => handlePressCategory(index, category), [handlePressCategory, index, category]);
const accessibilityLabel = category.type === EmojiCategoryTypes.GUILD ? category.guild.name : category.name;
const r97 = [category.type === EmojiCategoryTypes.GUILD ? <GuildIcon guild={category.guild} loadingStyle={loadingStyle} size={GuildIconSizes.XSMALL} style={styles.guildItem} /> : <EmojiPickerCategoryIcon id={category.id} />, ,];
if (locked) {
locked = <View style={styles.lockContainer}>
<LockIcon style={styles.lock} />
</View>;
}
r97[1] = locked;
return <PressableOpacity androidRippleConfig={CATEGORY_ICON_RIPPLE_CONFIG} style={style} onPress={callback} accessibilityRole="tab" accessibilityLabel={accessibilityLabel} accessibilityState={{
selected
}}>
<ReanimatedRexport.View style={[styles.itemInner, animatedStyle]}>{r97}</ReanimatedRexport.View>
</PressableOpacity>;
});
export default r71;
@@ -0,0 +1,68 @@
// Metro module 9446 (f9447).
import { useState, useCallback } from "react";
import { View } from "react-native";
import { EXPRESSION_FOOTER_HEIGHT, NODE_SIZE } from "../../../../../Constants";
import { createStyles } from "../../../../../design/components/Styles/native/createStyles";
import * as _ReanimatedRexport from "../../../../reanimated/ReanimatedRexport";
import { useAnimatedReaction } from "../../../../reanimated/ReanimatedRexport";
import * as _cheapWorkletShallowEqual from "../../../../reanimated/native/cheapWorkletShallowEqual";
import { PressableOpacity } from "../../../../../design/void/Pressables/native/Pressables";
import { intl, t } from "../../../../../intl/index.native";
import EmojiPickerCategoryIcon from "./EmojiPickerCategoryIcon";
const useStyles = createStyles({
itemInner: {
justifyContent: "center",
alignItems: "center",
height: NODE_SIZE,
width: NODE_SIZE,
borderRadius: NODE_SIZE / 2
},
fadedItemOpacity: {
opacity: 0.5
}
});
const __initData = {
code: "function EmojiPickerCategoriesUnicodeShortcutItemTsx1(){const{blockRef}=this.__closure;return blockRef.get();}"
};
const __initData2 = {
code: "function EmojiPickerCategoriesUnicodeShortcutItemTsx2(blockRef,previous){const{cheapWorkletShallowEqual,categoryIndex,EXPRESSION_FOOTER_HEIGHT,unicodeShortcutVisible,runOnJS,setUnicodeShortcutVisible}=this.__closure;if(blockRef==null||cheapWorkletShallowEqual(blockRef,previous!==null&&previous!==void 0?previous:undefined)){return;}const categoryScrollPos=categoryIndex*EXPRESSION_FOOTER_HEIGHT;const categoryUnicodeShortcutVisible=categoryScrollPos>blockRef.end-(unicodeShortcutVisible?0:EXPRESSION_FOOTER_HEIGHT);runOnJS(setUnicodeShortcutVisible)(categoryUnicodeShortcutVisible);}"
};
export default function EmojiPickerCategoriesUnicodeShortcutItem(props) {
const { blockRef, category, categoryIndex, onPress, style } = props;
const [state, setState] = useState(false);
const f = () => blockRef.get();
f.__closure = {
blockRef
};
f.__workletHash = 805688584630;
f.__initData = __initData;
const b = function b(a0, a1) {
if (a0 != null) {
if (!_cheapWorkletShallowEqual.cheapWorkletShallowEqual(a0, a1 == null ? void 0 : a1)) {
const r15 = categoryIndex * EXPRESSION_FOOTER_HEIGHT;
const r18 = a0.end - (state ? 0 : EXPRESSION_FOOTER_HEIGHT);
_ReanimatedRexport.runOnJS(setState)(r15 > r18);
}
}
};
b.__closure = {
cheapWorkletShallowEqual: _cheapWorkletShallowEqual.cheapWorkletShallowEqual,
categoryIndex,
EXPRESSION_FOOTER_HEIGHT,
unicodeShortcutVisible: state,
runOnJS: _ReanimatedRexport.runOnJS,
setUnicodeShortcutVisible: setState
};
b.__workletHash = 4994136030029;
b.__initData = __initData2;
useAnimatedReaction(f, b);
const styles = useStyles();
const callback = useCallback(() => {
onPress(categoryIndex, category);
}, [categoryIndex, category, onPress]);
return state ? <PressableOpacity style={style} onPress={callback} accessibilityRole="button" accessibilityLabel={intl.string(t.gg3lOG)}>
<View style={[styles.itemInner, styles.fadedItemOpacity]}>
<EmojiPickerCategoryIcon id={category.id} />
</View>
</PressableOpacity> : null;
};
@@ -0,0 +1,56 @@
// Metro module 9432 (f9433).
import { memo } from "react";
import { EmojiCategories } from "../../../EmojiPickerConstants";
import { TrophyIcon } from "../../../../../design/components/Icon/native/redesign/generated/TrophyIcon";
import { StarIcon } from "../../../../../design/components/Icon/native/redesign/generated/StarIcon";
import { ClockIcon } from "../../../../../design/components/Icon/native/redesign/generated/ClockIcon";
import { ReactionIcon } from "../../../../../design/components/Icon/native/redesign/generated/ReactionIcon";
import { NatureIcon } from "../../../../../design/components/Icon/native/redesign/generated/NatureIcon";
import { FoodIcon } from "../../../../../design/components/Icon/native/redesign/generated/FoodIcon";
import { GameControllerIcon } from "../../../../../design/components/Icon/native/redesign/generated/GameControllerIcon";
import { BicycleIcon } from "../../../../../design/components/Icon/native/redesign/generated/BicycleIcon";
import { ObjectIcon } from "../../../../../design/components/Icon/native/redesign/generated/ObjectIcon";
import { HeartIcon } from "../../../../../design/components/Icon/native/redesign/generated/HeartIcon";
import { FlagIcon } from "../../../../../design/components/Icon/native/redesign/generated/FlagIcon";
import { NitroWheelIcon } from "../../../../../design/components/Icon/native/redesign/generated/NitroWheelIcon";
const r22 = memo(function EmojiPickerCategoryIcon(props) {
const id = props.id;
if (EmojiCategories.TOP_GUILD_EMOJI === id) {
return <TrophyIcon />;
}
if (EmojiCategories.FAVORITES === id) {
return <StarIcon />;
}
if (EmojiCategories.RECENT === id) {
return <ClockIcon />;
}
if (EmojiCategories.PEOPLE === id) {
return <ReactionIcon />;
}
if (EmojiCategories.NATURE === id) {
return <NatureIcon />;
}
if (EmojiCategories.FOOD === id) {
return <FoodIcon />;
}
if (EmojiCategories.ACTIVITY === id) {
return <GameControllerIcon />;
}
if (EmojiCategories.TRAVEL === id) {
return <BicycleIcon />;
}
if (EmojiCategories.OBJECTS === id) {
return <ObjectIcon />;
}
if (EmojiCategories.SYMBOLS === id) {
return <HeartIcon />;
}
if (EmojiCategories.FLAGS === id) {
return <FlagIcon />;
}
if (EmojiCategories.CUSTOM !== id) {
EmojiCategories.PREMIUM_UPSELL;
}
return <NitroWheelIcon />;
});
export default r22;
@@ -0,0 +1,15 @@
// Metro module 9380 (f9381).
import { EmojiPickerItemType } from "./useEmojiPickerData";
export default function getEmojiPickerDataRowItemNativeSection({ label, guildId, emojiCount, emojisDisabled, emojisHidden, isSectionNitroLocked = false }, a1, a2) {
return {
type: EmojiPickerItemType.NATIVE_SECTION,
title: label,
guildId,
emojiCount,
emojisDisabled: isSectionNitroLocked ? [] : Array.from(emojisDisabled),
emojisHidden: Array.from(emojisHidden),
isSectionNitroLocked,
hasPremiumInlineRoadblockHeader: a1,
hasPremiumInlineRoadblockFooter: a2
};
};
@@ -0,0 +1,35 @@
// Metro module 9384 (f9385).
import { EmojiPickerItemType } from "./useEmojiPickerData";
import { EmojiTypes } from "../../../../emojis/EmojiTypes";
export default function getEmojiPickerDataRowItemSlimEmoji(a0) {
return {
type: EmojiPickerItemType.EMOJI_ROW_SLIM,
emojis: a0.emojis.map((emoji) => {
if (emoji.type === EmojiTypes.UNICODE) {
return {
name: emoji.name,
surrogates: emoji.surrogates
};
}
const r15 = a0.emojisDisabled.has(emoji.id);
return emoji.animated && r15 ? {
id: emoji.id,
name: emoji.name,
animated: true,
disabled: true
} : emoji.animated ? {
id: emoji.id,
name: emoji.name,
animated: true
} : r15 ? {
id: emoji.id,
name: emoji.name,
disabled: true
} : {
id: emoji.id,
name: emoji.name
};
}),
isSectionNitroLocked: a0.isSectionNitroLocked === true
};
};
@@ -0,0 +1,9 @@
// Metro module 9381 (f9382).
import { EmojiPickerItemType } from "./useEmojiPickerData";
export default function getEmojiPickerDataRowPremiumInlineRoadblock(a0) {
return {
type: EmojiPickerItemType.PREMIUM_INLINE_ROADBLOCK,
position: a0,
isSectionNitroLocked: true
};
};
@@ -0,0 +1,115 @@
// Metro module 9379 (f9380).
import { useMemo } from "react";
import EmojiStore, { LoadState } from "../../../../emojis/EmojiStore";
import { EmojiCategoryTypes } from "../../../EmojiPickerConstants";
import { EmojiPickerRenderingDataType } from "../EmojiPickerListConstants";
import { useStateFromStores } from "../../../../../_bundle/Module589";
import getEmojiPickerDataRowItemNativeSection from "./getEmojiPickerDataRowItemNativeSection";
import getEmojiPickerDataRowPremiumInlineRoadblock from "./getEmojiPickerDataRowPremiumInlineRoadblock";
import { PremiumUpsellSectionDividerPosition } from "../../../../premium/roadblocks/native/views/PremiumUpsellSectionDivider";
import getEmojiPickerDataRowItemSlimEmoji from "./getEmojiPickerDataRowItemSlimEmoji";
let c6177_8 = {
PLACEHOLDER: 0,
0: "PLACEHOLDER",
TITLE: 1,
1: "TITLE",
EMOJI_ROW: 2,
2: "EMOJI_ROW",
EMOJI_ROW_SLIM: 3,
3: "EMOJI_ROW_SLIM",
EMOJI_ROW_NSFW: 4,
4: "EMOJI_ROW_NSFW",
FOOTER_UPSELL: 5,
5: "FOOTER_UPSELL",
PREMIUM_INLINE_ROADBLOCK: 6,
6: "PREMIUM_INLINE_ROADBLOCK",
NATIVE_SECTION: 7,
7: "NATIVE_SECTION"
};
export default function useEmojiPickerData({ emojiSections, rowSize, isNativeEmojiPickerEnabled }) {
const stateFromStores = useStateFromStores([EmojiStore], () => EmojiStore.loadState === LoadState.Loaded || !isNativeEmojiPickerEnabled);
return useMemo(() => {
const data = [{
type: c6177_8.PLACEHOLDER,
isSectionNitroLocked: false
}];
let c26430_0 = data;
const r7 = {
data,
rowSize,
headerIndices: [],
hasGuildData: stateFromStores,
hasSearchData: false,
hasSearchUpsell: false
};
let c26430_1 = r7;
emojiSections.forEach((emojiSection, index) => {
const isSectionNitroLocked = emojiSection.isSectionNitroLocked === true;
let r6 = !!isSectionNitroLocked;
const r19 = r6 ? emojiSections[index - 1]?.isSectionNitroLocked !== true : r6;
if (r6) {
r6 = emojiSections[index + 1]?.isSectionNitroLocked !== true;
}
if (emojiSection.type !== EmojiPickerRenderingDataType.NATIVE_SECTION) {
if (r19) {
c26430_0.push(getEmojiPickerDataRowPremiumInlineRoadblock(PremiumUpsellSectionDividerPosition.START));
}
if (emojiSection.label != null) {
c26430_0.push({
type: c6177_8.TITLE,
title: emojiSection.label,
isSectionNitroLocked
});
c26430_1.headerIndices.push(c26430_0.length - 1);
}
const r81 = Math.ceil(emojiSection.emojis.length / rowSize);
const r82 = 0 < r81;
let r84 = 0;
if (r82) {
do {
const row = r84;
if (isNativeEmojiPickerEnabled) {
if (row === 0 ? emojiSection.type === EmojiPickerRenderingDataType.EMOJI : row === 0) {
c26430_1.hasSearchData = c26430_1.hasSearchData || emojiSection.footer === EmojiCategoryTypes.SEARCH_RESULTS || emojiSection.footer === EmojiCategoryTypes.PREMIUM_UPSELL;
c26430_0.push(getEmojiPickerDataRowItemSlimEmoji(emojiSection));
}
} else {
const type = emojiSection.type;
if (EmojiPickerRenderingDataType.EMOJI === type) {
c26430_0.push({
type: c6177_8.EMOJI_ROW,
row,
emojis: emojiSection.emojis,
emojisDisabled: emojiSection.emojisDisabled,
footer: emojiSection.footer,
isSectionNitroLocked
});
} else if (EmojiPickerRenderingDataType.NSFW === type) {
c26430_0.push({
type: c6177_8.EMOJI_ROW_NSFW,
isSectionNitroLocked
});
}
}
r84 = row + 1;
} while (r84 < r81);
}
if (emojiSection.footer === EmojiCategoryTypes.PREMIUM_UPSELL) {
c26430_1.hasSearchUpsell = true;
c26430_0.push({
type: c6177_8.FOOTER_UPSELL,
id: EmojiCategoryTypes.PREMIUM_UPSELL,
isSectionNitroLocked
});
}
if (r6) {
c26430_0.push(getEmojiPickerDataRowPremiumInlineRoadblock(PremiumUpsellSectionDividerPosition.END));
}
} else {
c26430_0.push(getEmojiPickerDataRowItemNativeSection(emojiSection, r19, r6));
}
});
return r7;
}, [stateFromStores, emojiSections, rowSize, isNativeEmojiPickerEnabled]);
};
export { c6177_8 as EmojiPickerItemType };
@@ -0,0 +1,24 @@
// Metro module 9408 (f9409).
import { EMOJI_URL_BASE_SIZE } from "../../../emojis/EmojiConstants";
import AvatarUtils from "../../../../utils/AvatarUtils";
import { dismissGlobalKeyboard } from "../../../../utils/native/KeyboardManagerUtils";
import ActionSheetActionCreators from "../../../action_sheet/native/ActionSheetActionCreators";
export function openEmojiActionSheet(a0) {
const alt = a0.uniqueName != null && a0.uniqueName !== "" ? a0.uniqueName : a0.name;
const emojiNode = a0.id == null && a0.surrogates != null ? {
surrogate: a0.surrogates,
content: `:${alt}:`
} : {
id: a0.id,
alt,
src: a0.id != null ? AvatarUtils.getEmojiURL({
id: a0.id,
animated: a0.animated,
size: EMOJI_URL_BASE_SIZE
}) : a0.url
};
dismissGlobalKeyboard();
ActionSheetActionCreators.openLazy(import("../../../messages/native/emoji/MessageEmojiActionSheet"), "MessageEmojiActionSheet", {
emojiNode
}, "stack");
}
@@ -0,0 +1,181 @@
// Metro module 9357 (f9358).
import _slicedToArray from "../../../../_bundle/_slicedToArray";
import { useState } from "react";
import { EmojiCategories, EmojiCategoryTypes } from "../../EmojiPickerConstants";
import { EmojiPickerRenderingDataType } from "./EmojiPickerListConstants";
import { shouldNSFWGateGuild } from "../../../age_gate/native/AgeGateUtils";
import UnicodeEmojis from "../../../emojis/UnicodeEmojis";
import Module12 from "../../../../_bundle/Module12";
import { getStringForEmojiCategory } from "../../EmojiPickerUtils";
import { cachedFunction } from "../../../../utils/FunctionUtils";
let _computeSearchResults, pushCategory, pushNativeCategory;
const _computeCategories = function _computeCategories({ categories, rowSize, isNativeEmojiPickerEnabled }) {
const emojiSections = [];
for (const item of categories) {
const type = item.type;
if (EmojiCategoryTypes.TOP_GUILD_EMOJI === type) {
pushCategory({
emojiSections,
renderingData: {
type: EmojiPickerRenderingDataType.EMOJI,
emojis: item.emojis.slice(0, rowSize),
emojisDisabled: item.emojisDisabled,
label: item.name,
footer: EmojiCategoryTypes.TOP_GUILD_EMOJI
},
rowSize
});
} else if (EmojiCategoryTypes.FAVORITES === type) {
pushCategory({
emojiSections,
renderingData: {
type: EmojiPickerRenderingDataType.EMOJI,
emojis: item.emojis,
emojisDisabled: item.emojisDisabled,
label: item.name,
footer: EmojiCategoryTypes.FAVORITES
},
rowSize
});
} else if (EmojiCategoryTypes.RECENT === type) {
pushCategory({
emojiSections,
renderingData: {
type: EmojiPickerRenderingDataType.EMOJI,
emojisDisabled: item.emojisDisabled,
emojis: item.emojis,
label: item.name,
footer: EmojiCategoryTypes.RECENT
},
rowSize
});
} else if (EmojiCategoryTypes.GUILD === type) {
const { guild, emojis, emojisDisabled, emojisHidden } = item;
if (isNativeEmojiPickerEnabled) {
pushNativeCategory({
emojiSections,
renderingData: {
type: EmojiPickerRenderingDataType.NATIVE_SECTION,
label: guild.name,
guildId: guild.id,
emojiCount: emojis.length,
emojisDisabled,
emojisHidden,
isSectionNitroLocked: item.isNitroLocked
}
});
} else if (shouldNSFWGateGuild(guild.id)) {
emojiSections.push({
type: EmojiPickerRenderingDataType.NSFW,
label: guild.name,
footer: EmojiCategoryTypes.GUILD,
emojis: [],
isSectionNitroLocked: item.isNitroLocked
});
} else {
pushCategory({
emojiSections,
renderingData: {
type: EmojiPickerRenderingDataType.EMOJI,
emojis,
emojisDisabled,
label: guild.name,
footer: EmojiCategoryTypes.GUILD,
isSectionNitroLocked: item.isNitroLocked
},
rowSize
});
}
} else if (EmojiCategoryTypes.UNICODE === type) {
const byCategory = UnicodeEmojis.getByCategory(item.name);
if (isNativeEmojiPickerEnabled) {
const renderingData = {
type: EmojiPickerRenderingDataType.NATIVE_SECTION,
label: Module12.capitalize(item.name),
emojiCount: null,
emojisDisabled: null,
emojisHidden: null
};
let emojiCount = byCategory?.length;
if (emojiCount == null) {
emojiCount = 0;
}
renderingData.emojiCount = emojiCount;
renderingData.emojisDisabled = new Set();
renderingData.emojisHidden = new Set();
pushNativeCategory({
emojiSections,
renderingData
});
} else {
let emojis2 = byCategory;
if (emojis2 == null) {
emojis2 = [];
}
pushCategory({
emojiSections,
renderingData: {
type: EmojiPickerRenderingDataType.EMOJI,
emojis: emojis2,
emojisDisabled: new Set(),
label: Module12.capitalize(item.name),
footer: EmojiCategoryTypes.UNICODE
},
rowSize
});
}
}
}
return emojiSections;
};
_computeSearchResults = function _computeSearchResults(a0) {
const emojis = a0.emojis;
const { locked, unlocked } = emojis;
const { rowSize, limit = Number.MAX_SAFE_INTEGER } = a0;
const emojiSections = [];
pushCategory({
emojiSections,
renderingData: {
type: EmojiPickerRenderingDataType.EMOJI,
emojis: unlocked.length > limit ? unlocked.slice(0, limit) : unlocked,
emojisDisabled: new Set(),
label: "",
footer: EmojiCategoryTypes.SEARCH_RESULTS
},
rowSize
});
const emojis2 = locked.length > limit ? locked.slice(0, limit) : locked;
const set = new Set();
for (const item of locked) {
if (item.id != null) {
set.add(item.id);
}
}
pushCategory({
emojiSections,
renderingData: {
type: EmojiPickerRenderingDataType.EMOJI,
emojis: emojis2,
emojisDisabled: set,
label: getStringForEmojiCategory(EmojiCategories.PREMIUM_UPSELL),
footer: EmojiCategoryTypes.PREMIUM_UPSELL
},
rowSize
});
return emojiSections;
};
pushCategory = function pushCategory(a0) {
const emojis = a0.renderingData.emojis;
if (emojis != null && emojis.length !== 0) {
a0.emojiSections.push(a0.renderingData);
}
};
pushNativeCategory = function pushNativeCategory(a0) {
a0.emojiSections.push(a0.renderingData);
};
export default function useComputeEmojiPickerFunctions() {
return _slicedToArray(useState(() => ({
computeCategories: cachedFunction(_computeCategories),
computeSearchResults: cachedFunction(_computeSearchResults)
})), 1)[0];
};
@@ -0,0 +1,39 @@
// Metro module 9347 (f9348).
import { useRef, useState, useCallback } from "react";
import EmojiStore from "../../../emojis/EmojiStore";
import { batchUpdates } from "../../../../_bundle/Module705";
import { FrecencyUserSettingsActionCreators } from "../../../user_settings/UserSettingsProtoActionCreators";
export default function useEmojiPickerSearchState(a0, a1, a2) {
const channel = a0;
const intention = a2;
const ref = useRef("");
const [searchResults, setState] = useState(null);
return {
handleTextChange: useCallback((a0) => {
let c26429_1;
const current = a0;
if (a0 !== "") {
const query = a0[0] === ":" ? a0.slice(1) : a0;
FrecencyUserSettingsActionCreators.loadIfNecessary();
c26429_1 = EmojiStore.searchWithoutFetchingLatest({
channel,
query,
count: 0,
intention
});
batchUpdates(() => {
ref.current = current;
setState(c26429_1);
});
} else {
batchUpdates(() => {
ref.current = "";
setState(null);
a1.set(0);
});
}
}, [a1, a0, a2]),
searchQueryRef: ref,
searchResults
};
};
@@ -0,0 +1,7 @@
// Metro module 9355 (f9356).
import AuthenticationStore from "../../../../stores/AuthenticationStore";
import { isAndroid } from "../../../../utils/PlatformUtils";
import DatabaseManager from "../../../app_database/system/DatabaseManager";
export default function useNativeAndroidEmojiPickerEnabled() {
return isAndroid() && DatabaseManager.database(AuthenticationStore.getId()) != null;
};