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

475 lines
18 KiB
TypeScript

// Metro module 15320 (f15321).
import * as Module19 from "react";
import { useMemo, useLayoutEffect, useEffect, useRef, useCallback } from "react";
import { RefreshControl, View } from "react-native";
import AccessibilityStore from "../../a11y/AccessibilityStore";
import AuthenticationStore from "../../../stores/AuthenticationStore";
import GuildStore from "../../../stores/GuildStore";
import ICYMIFiltersStore from "../ICYMIFiltersStore";
import ICYMIStore from "../ICYMIStore";
import { NUM_GUILDS_EXTENDED_ONBOARDING } from "../ICYMIConstants";
import { ContentDismissActionType } from "../../dismissible_content/DismissibleContentConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { createICYMIStyles } from "./createICYMIStyles";
import { IconButton } from "../../../design/components/Button/native/IconButton.native";
import { FiltersHorizontalIcon } from "../../../design/components/Icon/native/redesign/generated/FiltersHorizontalIcon";
import ICYMIActionCreators from "../ICYMIActionCreators";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import { CircleInformationIcon } from "../../../design/components/Icon/native/redesign/generated/CircleInformationIcon";
import { pushICYMIInfoModal } from "./NativeICYMIUtils";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import useIsWindowLarge from "../../screen/native/useIsWindowLarge";
import { SafeAreaPaddingView } from "../../../components_native/common/SafeAreaView";
import ThemedGradient from "../../client_themes/native/ThemedGradient";
import { OverlayOpacity } from "../../client_themes/native/ClientThemesUtils";
import * as _Pressables from "../../../design/void/Pressables/native/Pressables";
import { goBack } from "../../main_tabs_v2/native/tabs/notifications/Notifications";
import { LeftBackIconWithBadge } from "../../main_tabs_v2/native/shared_components/BackIconWithBadge";
import { XSmallIcon } from "../../../design/components/Icon/native/redesign/generated/XSmallIcon";
import { hydrateNextPage, itemToType } from "../ICYMIUtils";
import useWindowDimensions_native from "../../screen/useWindowDimensions.native";
import useSafeAreaInsets_native from "../../safe_area/useSafeAreaInsets.native";
import { useIsFocused, useScrollToTop } from "../../../_bundle/Module1481";
import { trackAppUIViewed } from "../../tti_analytics/native/TTIAnalyticsUtils";
import { useStateFromStores } from "../../../_bundle/Module589";
import useICYMITabBadge from "../useICYMITabBadge";
import { useSharedICYMILogic } from "../useSharedICYMILogic";
import { useICYMIEmptyLoadingAnalytics } from "../useICYMIEmptyLoadingAnalytics";
import { useGetDismissibleContent } from "../../dismissible_content/useGetDismissibleContent";
import { DismissibleContent } from "../../../_bundle/Module1358";
import { useNavigation } from "../../../design/components/Navigator/native/useNavigation.native";
import { GravityICYMIDoubleTapBehavior } from "../ICYMITypes";
import { showForLaterModal } from "../../saved_messages/native/showForLaterModal";
import { SavedMessageSortTypes } from "../../saved_messages/SavedMessagesTypes";
import { useMobileQuestDockHeight } from "../../quests/native/QuestHooks.native";
import { ChannelTypes } from "../../../_bundle/Module692";
import AnnouncementMessageRow from "./AnnouncementMessageRow";
import ICYMIMessageRow from "./ICYMIMessageRow";
import ContentInventoryEntryRow from "./ContentInventoryEntryRow";
import { ICYMILoading } from "./ICYMILoading";
import { ICYMIBottomLoading } from "./ICYMIBottomLoading";
import CaughtUpRow from "./CaughtUpRow";
import ICYMIGuildEventRow from "./ICYMIGuildEventRow";
import { ICYMIServerRecommendationRow } from "./ICYMIServerRecommendationRow";
import ICYMIHeader from "./ICYMIHeader";
import { ICYMIForumThreadRow } from "./ICYMIForumThreadRow";
import { CardHeightMeasurer } from "./CardHeightMeasurer";
import { useClientThemesOverride } from "../../client_themes/native/ClientThemesOverrides";
import NewContentPill from "./NewContentPill";
import { FlashList } from "../../../_bundle/noop_6676";
import { isAndroid } from "../../../utils/PlatformUtils";
import { TTIFirstContentfulPaint } from "../../tti_analytics/native/TTIFirstContentfulPaint";
import useColorThemeBackground from "../../client_themes/native/useColorThemeBackground";
import AppFreezer from "../../panels/morphable/native/AppFreezer";
import { ICYMIContextProvider } from "./ICYMIContext";
import { ThemeContextProvider } from "../../../_bundle/Module3901";
let useStyles, styles, InfoButton, ICYMIHeaderTextWrapper, Component, handleEndReached, ICYMI, keyExtractor;
const SettingsButton = function SettingsButton() {
return <IconButton accessibilityLabel="button" variant="tertiary" size="sm" icon={<FiltersHorizontalIcon size="sm" />} onPress={() => {
ICYMIActionCreators.itemInteracted("filters_button", "filters_button", "press_info_button");
ICYMIActionCreators.feedPageActioned({
actionParameters: {
actionGestureType: "press",
actionTargetElement: "settings_button",
actionIntentType: "open",
actionDestinationType: null
}
});
ActionSheetActionCreators.openLazy(import("./ICYMISettingsActionSheet"), "ICYMISettingsActionSheet", {});
}} />;
};
InfoButton = function InfoButton() {
return <IconButton accessibilityLabel="button" variant="tertiary" size="sm" icon={<CircleInformationIcon size="sm" />} onPress={() => {
ICYMIActionCreators.itemInteracted("info_button", "info_button", "press_info_button");
ICYMIActionCreators.feedPageActioned({
actionParameters: {
actionGestureType: "press",
actionTargetElement: "info_button",
actionIntentType: "open",
actionDestinationType: null
}
});
pushICYMIInfoModal({
extendedOnboarding: true
});
}} />;
};
ICYMIHeaderTextWrapper = function ICYMIHeaderTextWrapper() {
return <View style={styles().headerText}>
{useMemo(() => <>
<Text color="mobile-text-heading-primary" variant="heading-lg/bold" maxFontSizeMultiplier={1.75} accessibilityRole="header">
{intl.string(t.SY4sdZ)}
</Text>
<Text color="text-brand" variant="text-xs/bold" style={{
marginTop: 4
}}>
{intl.string(t.Ac2OZA)}
</Text>
</>, [])}
</View>;
};
handleEndReached = function handleEndReached() {
hydrateNextPage();
};
ICYMI = function ICYMI(props) {
let stateFromStores, visibleItemIds, endVisible, handleOnRefresh, c21866_5, c21866_6, stateFromStores2, ref, ref2, stateFromStores3, callback;
const inNestedNavigator = props.inNestedNavigator;
stateFromStores = void 0;
visibleItemIds = void 0;
endVisible = void 0;
handleOnRefresh = void 0;
c21866_5 = void 0;
c21866_6 = void 0;
stateFromStores2 = void 0;
ref = void 0;
ref2 = void 0;
stateFromStores3 = void 0;
callback = void 0;
const r17 = styles();
const windowDimensions_native = useWindowDimensions_native();
const { height, width } = windowDimensions_native;
const top = useSafeAreaInsets_native().top;
const isFocused = useIsFocused();
useLayoutEffect(() => {
trackAppUIViewed();
});
stateFromStores = useStateFromStores([AccessibilityStore], () => AccessibilityStore.useReducedMotion);
const stateFromStores4 = useStateFromStores([ICYMIStore], () => ICYMIStore.notificationItem(), []);
const showDot = useICYMITabBadge().showDot;
useEffect(() => {
ICYMIActionCreators.setTabFocused(isFocused);
}, [isFocused]);
const sharedICYMILogic = useSharedICYMILogic({
showDot,
notificationItem: stateFromStores4
});
const { data, loading, version } = sharedICYMILogic;
visibleItemIds = sharedICYMILogic.visibleItemIds;
endVisible = sharedICYMILogic.endVisible;
const isRefreshing = sharedICYMILogic.isRefreshing;
handleOnRefresh = sharedICYMILogic.handleOnRefresh;
const { stickyHeaderIndices, viewabilityConfigCallbackPairs } = sharedICYMILogic;
useICYMIEmptyLoadingAnalytics(loading, isFocused);
const [r24, r87] = useGetDismissibleContent([DismissibleContent.ICYMI_ALPHA_UPSELL]);
c21866_5 = r24;
c21866_6 = r87;
stateFromStores2 = useStateFromStores([GuildStore], () => GuildStore.getGuildCount());
useEffect(() => {
if (c21866_5 != null) {
pushICYMIInfoModal({
extendedOnboarding: stateFromStores2 <= NUM_GUILDS_EXTENDED_ONBOARDING
});
c21866_6(ContentDismissActionType.USER_DISMISS);
}
}, [r24, r87, stateFromStores2]);
useEffect(() => {
let r6 = endVisible;
if (endVisible) {
r6 = ICYMIStore.hasOpenedEnoughTimes();
}
if (r6) {
ActionSheetActionCreators.openLazy(import("./ICYMIFeedbackSheet"), "ICYMIFeedbackSheet", {});
}
}, [endVisible]);
ref = useRef(null);
ref2 = useRef({
scrollToTop: () => {
const current = ref.current;
if (current != null) {
current.scrollToOffset({
offset: 0,
animated: !stateFromStores
});
}
}
});
useScrollToTop(ref2);
stateFromStores3 = useStateFromStores([ICYMIFiltersStore], () => ICYMIFiltersStore.getDoubleTapBehavior());
useEffect(() => {
if (stateFromStores3 === GravityICYMIDoubleTapBehavior.DEFAULT) {
ref2.current = {
scrollToTop: () => {
const current = ref.current;
if (current != null) {
current.scrollToOffset({
offset: 0,
animated: !stateFromStores
});
}
}
};
} else {
ref2.current = {
scrollToTop: () => {
showForLaterModal(SavedMessageSortTypes.BOOKMARK);
}
};
}
}, [stateFromStores3, useNavigation(), stateFromStores]);
callback = useCallback(() => {
const current = ref.current;
if (current != null) {
current.scrollToOffset({
offset: 0,
animated: !stateFromStores
});
}
}, [ref, stateFromStores]);
const mobileQuestDockHeight = useMobileQuestDockHeight();
const callback2 = useCallback(({ item }) => {
let r37;
const kind = item.data.kind;
if (kind === "message") {
r37 = item.channelType === ChannelTypes.GUILD_ANNOUNCEMENT ? <AnnouncementMessageRow unread={item.unread} message={item.data.message} visible={visibleItemIds.find((visibleItemId) => visibleItemId.item.id === item.id) != null} /> : <ICYMIMessageRow message={item.data.message} messageContext={item.data.messageContext} visible={visibleItemIds.find((visibleItemId) => visibleItemId.item.id === item.id) != null} />;
} else if (kind === "contentInventory") {
r37 = <ContentInventoryEntryRow visible={visibleItemIds.find((visibleItemId) => visibleItemId.item.id === item.id) != null} content={item.data.content} />;
} else {
if (kind === "loading") {
return <ICYMILoading />;
}
if (kind === "bottomLoading") {
return <ICYMIBottomLoading />;
}
if (kind === "end") {
return <CaughtUpRow visible={endVisible} />;
}
if (kind === "guildEvent") {
r37 = <ICYMIGuildEventRow eventId={item.data.eventId} />;
} else if (kind === "recommendedGuilds") {
r37 = <ICYMIServerRecommendationRow />;
} else {
if (kind === "icymiHeader") {
return <ICYMIHeader />;
}
if (kind !== "forumThread") {
return null;
}
r37 = <ICYMIForumThreadRow message={item.data.message} channel={item.data.threadChannel} visible={visibleItemIds.find((visibleItemId) => visibleItemId.item.id === item.id) != null} />;
}
}
return <CardHeightMeasurer itemId={item.id}>{r37}</CardHeightMeasurer>;
}, [visibleItemIds, endVisible]);
const memo = useMemo(() => ({
backgroundColor: "transparent"
}), []);
const clientThemesOverride = useClientThemesOverride();
const stateFromStores5 = useStateFromStores([ICYMIStore], () => ICYMIStore.hasNewContent(), []);
const r162 = [<Component inNestedNavigator={inNestedNavigator} />, ,];
const r176 = [<NewContentPill onPress={() => {
ICYMIActionCreators.itemInteracted("refresh_button", "refresh_button", "press_refresh_button");
ICYMIActionCreators.feedPageActioned({
actionParameters: {
actionGestureType: "press",
actionTargetElement: "new_content_pill",
actionIntentType: "refresh",
actionDestinationType: null
}
});
handleOnRefresh();
callback();
}} isRefreshing={isRefreshing} />, , ,];
const props2 = {
ref,
scrollEnabled: !loading,
extraData: {
endVisible
},
contentContainerStyle: memo,
accessibilityLabel: intl.string(t.OIgYlQ),
data,
refreshing: isRefreshing,
refreshControl: null,
onEndReachedThreshold: 3,
onEndReached: null,
keyExtractor: null,
renderItem: null,
getItemType: null,
drawDistance: 100,
stickyHeaderIndices: null,
viewabilityConfigCallbackPairs: null
};
let r196 = 1;
props2.refreshControl = <RefreshControl onRefresh={handleOnRefresh} refreshing={isRefreshing} tintColor={r17.refreshing.color} style={{
opacity: stateFromStores5 ? 0 : 1
}} />;
props2.onEndReached = handleEndReached;
props2.keyExtractor = keyExtractor;
props2.renderItem = callback2;
props2.getItemType = itemToType;
isAndroid();
props2.stickyHeaderIndices = stickyHeaderIndices;
props2.viewabilityConfigCallbackPairs = viewabilityConfigCallbackPairs;
if (!loading) {
r196 = version;
}
r176[1] = <FlashList key={`Version-${r196}`} {...props2} />;
r176[2] = <TTIFirstContentfulPaint label="icymi" />;
r162[1] = <View style={[r17.flashListWrapper, {
height: height - top - 32 - 24 - mobileQuestDockHeight,
width,
marginHorizontal: "auto"
}, clientThemesOverride]}>{r176}</View>;
return <View style={[r17.containerInPanels, r17.containerBackground]}>{r162}</View>;
};
keyExtractor = function keyExtractor(a0) {
return a0.id;
};
useStyles = createStyles((a0) => ({
containerOuterTablet: {
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWEST,
paddingHorizontal: Module712.space.PX_8,
overflow: "hidden",
flex: 1,
paddingTop: a0
}
}));
styles = createICYMIStyles((a0) => ({
container: {
flex: 1,
flexShrink: 1,
flexGrow: 1
},
containerInPanels: {
flex: 1,
flexShrink: 1,
flexGrow: 1,
overflow: "hidden",
borderTopLeftRadius: Module712.radii.sm,
borderTopRightRadius: Module712.radii.sm
},
containerBackground: {
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW
},
flashListWrapper: {
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW,
minHeight: 2,
flex: 1
},
refreshing: {
color: Module712.colors.INTERACTIVE_TEXT_DEFAULT
},
header: {
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW,
position: "relative",
overflow: "hidden",
width: "100%"
},
headerLeft: {
flexDirection: "row",
alignItems: "center"
},
headerClose: {
marginRight: Module712.space.PX_16,
height: Module712.space.PX_32,
width: Module712.space.PX_32,
alignItems: "center",
justifyContent: "center",
borderRadius: Module712.radii.lg
},
headerTitle: {
height: 56,
marginHorizontal: a0.margin,
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between"
},
headerText: {
flexDirection: "row",
alignItems: "center",
gap: 4
},
headerActions: {
flexDirection: "row",
alignItems: "center",
gap: Module712.space.PX_12
},
notificationBadge: {
height: 18,
width: 18,
borderRadius: Module712.radii.round
},
loading: {
flex: 1,
justifyContent: "center",
paddingTop: Module712.space.PX_96
},
headerBorder: {
position: "absolute",
bottom: 0,
left: 0,
right: 0,
backgroundColor: Module712.colors.BORDER_SUBTLE,
height: 1
}
}));
Component = Module19.memo(function({ inNestedNavigator }) {
let r43, PressableOpacity;
const r9 = styles();
const isWindowLarge = useIsWindowLarge();
const r38 = [<ThemedGradient absolute wide tall mix mixAmount={{
dark: OverlayOpacity.LEVEL_7,
light: OverlayOpacity.LEVEL_8
}} />, , ,];
if (!isWindowLarge) {
r43 = null;
if (inNestedNavigator) {
PressableOpacity = _Pressables.PressableOpacity;
r43 = <PressableOpacity style={r9.headerClose} accessibilityLabel={intl.string(t["13/7kX"])} onPress={goBack}>
{inNestedNavigator ? <LeftBackIconWithBadge includeNotificationsCount /> : <XSmallIcon color="interactive-text-default" />}
</PressableOpacity>;
}
} else {
PressableOpacity = _Pressables.PressableOpacity;
r43 = <PressableOpacity style={r9.headerClose} accessibilityLabel={intl.string(t["13/7kX"])} onPress={goBack}>
{inNestedNavigator ? <LeftBackIconWithBadge includeNotificationsCount /> : <XSmallIcon color="interactive-text-default" />}
</PressableOpacity>;
}
r38[1] = <View style={r9.headerTitle}>
<View style={r9.headerLeft}>
{r43}
<ICYMIHeaderTextWrapper />
</View>
<View style={r9.headerActions}>
<InfoButton />
<SettingsButton />
</View>
</View>;
r38[2] = <View style={r9.headerBorder} />;
return <SafeAreaPaddingView top={!isWindowLarge} style={r9.header}>{r38}</SafeAreaPaddingView>;
});
export function ICYMITab(props) {
let c21867_0, styles2;
const route = props.route;
c21867_0 = void 0;
styles2 = void 0;
const colorThemeBackground = useColorThemeBackground();
const stateFromStores4 = useStateFromStores([AuthenticationStore], () => AuthenticationStore.getId());
const isWindowLarge = useIsWindowLarge();
c21867_0 = isWindowLarge;
const top = useSafeAreaInsets_native().top;
const inNestedNavigator = route == null ? void 0 : route.params?.inNestedNavigator;
styles2 = useStyles(top);
const memo = useMemo(() => c21867_0 ? styles2.containerOuterTablet : void 0, [isWindowLarge, styles2.containerOuterTablet]);
return <AppFreezer>
<ICYMIContextProvider>
{isWindowLarge ? <View {...isWindowLarge ? {
style: memo
} : {}}>
<ThemedGradient absolute />
<ThemeContextProvider gradient={colorThemeBackground}>
<ICYMI key={`${stateFromStores4}`} inNestedNavigator={inNestedNavigator} />
</ThemeContextProvider>
</View> : <Module19.Fragment {...isWindowLarge ? {
style: memo
} : {}}>
<ThemedGradient absolute />
<ThemeContextProvider gradient={colorThemeBackground}>
<ICYMI key={`${stateFromStores4}`} inNestedNavigator={inNestedNavigator} />
</ThemeContextProvider>
</Module19.Fragment>}
</ICYMIContextProvider>
</AppFreezer>;
}