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

243 lines
10 KiB
TypeScript

// Metro module 10462 (f10463).
import { useEffect, useCallback } from "react";
import { View, StyleSheet } from "react-native";
import GatewayConnectionStore from "../../gateway/GatewayConnectionStore";
import ReadStateStore from "../../../stores/ReadStateStore";
import { ChatOverlays } from "../ChatOverlayConstants";
import { AnalyticEvents, AnalyticsObjectTypes, AnalyticsObjects, AnalyticsSections } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import useShowChannelOptInNotice from "../../opt_in_channels/useShowChannelOptInNotice";
import useAllowedChatOverlays from "../useAllowedChatOverlays";
import { useStateFromStores, useStateFromStoresObject } from "../../../_bundle/Module589";
import SnowflakeUtils from "../../../utils/SnowflakeUtils";
import MobileVisualRefreshExperiment from "../../themes/experiments/MobileVisualRefreshExperiment";
import AnalyticsUtils from "../../../utils/AnalyticsUtils";
import { collectGuildAnalyticsMetadata, collectChannelAnalyticsMetadata } from "../../app_analytics/AppAnalyticsUtils";
import { setOptInChannel } from "../../opt_in_channels/OptInChannelsActionCreators";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import { Button } from "../../../design/components/Button/native/Button.native";
import { useCanUnarchiveThread, useIsThreadModerator } from "../../threads/ThreadHooks";
import ThreadActionCreators from "../../threads/ThreadActionCreators";
import { PressableOpacity } from "../../../design/void/Pressables/native/Pressables";
import { ack } from "../../../actions/ReadStateActionCreators";
import { XSmallBoldIcon } from "../../../design/components/Icon/native/redesign/generated/XSmallBoldIcon";
let useStyles, ArchivedLockedThreadChatBanner, LockedThreadChatBanner, NewMessagesChatBar;
const OptInChannelBanner = function OptInChannelBanner(props) {
const { channel, ctaProps, topBorder } = props;
const styles = useStyles();
const r12 = MobileVisualRefreshExperiment("OptInChannelBanner");
useEffect(() => {
AnalyticsUtils.track(AnalyticEvents.CHANNEL_BANNER_VIEWED, {
...collectGuildAnalyticsMetadata(channel.getGuildId()),
...collectChannelAnalyticsMetadata(channel),
banner_type: "channel_opt_in"
});
}, [channel]);
const callback = useCallback(() => {
AnalyticsUtils.track(AnalyticEvents.CHANNEL_BANNER_CTA_CLICKED, {
...collectGuildAnalyticsMetadata(channel.getGuildId()),
...collectChannelAnalyticsMetadata(channel),
banner_type: "channel_opt_in",
cta_type: "add channel"
});
setOptInChannel(channel.guild_id, channel.id, true, {
section: AnalyticsSections.CHANNEL
});
}, [channel]);
return <View style={[styles.optInChannelBannerContainer, r12 ? null : styles.optInChannelBannerLegacyBorder, topBorder ? styles.topBorder : null]}>
<Text lineClamp={2} style={styles.optInChannelBannerText} variant="text-sm/semibold">
{intl.string(t.iOWmmB)}
</Text>
<View style={styles.optInChannelBannerButtonContainer}>
<Button {...ctaProps} onPress={callback} size="sm" text={intl.string(t["TD/+zP"])} />
</View>
</View>;
};
ArchivedLockedThreadChatBanner = function ArchivedLockedThreadChatBanner(props) {
const channel2 = props.channel;
const styles = useStyles();
useEffect(() => {
AnalyticsUtils.track(AnalyticEvents.CHANNEL_BANNER_VIEWED, {
...collectGuildAnalyticsMetadata(channel2.getGuildId()),
...collectChannelAnalyticsMetadata(channel2),
banner_type: "thread"
});
}, [channel2]);
let r22 = useCanUnarchiveThread(channel2);
const r41 = [<Text lineClamp={4} style={styles.threadBannerTitle} variant="text-sm/medium" color="text-default">
{channel2.isForumPost() ? intl.string(t["833FDn"]) : intl.string(t.rEeodK)}
</Text>, ,];
if (r22) {
r22 = <View style={styles.threadBannerButton}>
<Button variant="secondary" size="sm" text={intl.string(t["0dvvEi"])} onPress={function onPress() {
AnalyticsUtils.track(AnalyticEvents.CHANNEL_BANNER_CTA_CLICKED, {
...collectGuildAnalyticsMetadata(channel2.getGuildId()),
...collectChannelAnalyticsMetadata(channel2),
banner_type: "thread",
cta_type: "unarchive"
});
ThreadActionCreators.unarchiveThread(channel2, false);
}} />
</View>;
}
r41[1] = r22;
return <View style={styles.threadBannerContainer}>{r41}</View>;
};
LockedThreadChatBanner = function LockedThreadChatBanner(props) {
const channel3 = props.channel;
const styles = useStyles();
useEffect(() => {
AnalyticsUtils.track(AnalyticEvents.CHANNEL_BANNER_VIEWED, {
...collectGuildAnalyticsMetadata(channel3.getGuildId()),
...collectChannelAnalyticsMetadata(channel3),
banner_type: "thread"
});
}, [channel3]);
let r22 = useIsThreadModerator(channel3);
const r41 = [<Text lineClamp={4} style={styles.threadBannerTitle} variant="text-sm/medium" color="text-default">
{channel3.isForumPost() ? intl.string(t.E7oO8u) : intl.string(t["V/JF2N"])}
</Text>, ,];
if (r22) {
r22 = <View style={styles.threadBannerButton}>
<Button variant="secondary" size="sm" text={intl.string(t.zA9d1J)} onPress={function onPress() {
AnalyticsUtils.track(AnalyticEvents.CHANNEL_BANNER_CTA_CLICKED, {
...collectGuildAnalyticsMetadata(channel3.getGuildId()),
...collectChannelAnalyticsMetadata(channel3),
banner_type: "thread",
cta_type: "unlock"
});
ThreadActionCreators.unlockThread(channel3);
}} />
</View>;
}
r41[1] = r22;
return <View style={styles.threadBannerContainer}>{r41}</View>;
};
NewMessagesChatBar = function NewMessagesChatBar(props) {
const { channel: channel4, unreadCount, oldestUnreadTimestamp, handleScrollToNewMessages } = props;
const styles = useStyles();
return useStateFromStores([GatewayConnectionStore], () => GatewayConnectionStore.isConnected(), []) ? unreadCount <= 0 ? null : <View style={styles.newMessageBar}>
<PressableOpacity accessibilityRole="button" style={styles.newMessageBarTextContainer} onPress={handleScrollToNewMessages}>
<Text variant="text-sm/semibold" color="text-overlay-light">
{intl.format(ReadStateStore.isEstimated(channel4.id) ? t.wvtbbG : t["BctFH/"], {
count: unreadCount,
timestamp: oldestUnreadTimestamp
})}
</Text>
</PressableOpacity>
<PressableOpacity style={styles.newMessageBarCloseButton} accessibilityRole="button" accessibilityLabel={intl.string(t.e6RscS)} onPress={() => ack(channel4.id, {
section: AnalyticsSections.NEW_MESSAGES_BANNER,
object: AnalyticsObjects.MARK_CHANNEL_AS_READ_BUTTON,
objectType: AnalyticsObjectTypes.ACK_MANUAL
})}>
<XSmallBoldIcon size="sm" color={Module712.colors.WHITE} />
</PressableOpacity>
</View> : null;
};
useStyles = createStyles({
threadBannerContainer: {
alignSelf: "stretch",
minHeight: 60,
flexDirection: "row",
paddingHorizontal: 16,
paddingVertical: 12,
alignItems: "center",
flexGrow: 0,
zIndex: 100,
backgroundColor: Module712.colors.BACKGROUND_SURFACE_HIGH
},
threadBannerTitle: {
flex: 1,
lineHeight: 18
},
threadBannerButton: {
flexGrow: 0,
paddingVertical: 7,
paddingHorizontal: 16,
marginLeft: 16
},
newMessageBar: {
backgroundColor: Module712.colors.BACKGROUND_BRAND,
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
overflow: "hidden",
zIndex: 100,
minHeight: 45
},
newMessageBarTextContainer: {
flex: 1,
paddingLeft: 16,
paddingVertical: 10
},
newMessageBarCloseButton: {
paddingHorizontal: 12
},
optInChannelBannerContainer: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
overflow: "hidden",
padding: 8,
paddingLeft: 16,
paddingRight: 16,
zIndex: 100,
backgroundColor: Module712.colors.CHAT_BANNER_BG,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: Module712.colors.CHAT_BORDER
},
optInChannelBannerLegacyBorder: {
borderBottomWidth: 1,
borderBottomColor: Module712.colors.BORDER_SUBTLE
},
topBorder: {
borderTopWidth: StyleSheet.hairlineWidth,
borderTopColor: Module712.colors.CHAT_BORDER
},
optInChannelBannerText: {
flex: 1
},
optInChannelBannerButtonContainer: {
flexShrink: 0,
marginLeft: 8
}
});
export default function ChatBanner(props) {
let r36;
let channel5;
L13: {
channel5 = props.channel;
const handleScrollToNewMessages = props.handleScrollToNewMessages;
const showChannelOptInNotice = useShowChannelOptInNotice(channel5);
const allowedChatOverlays = useAllowedChatOverlays();
const stateFromStoresObject = useStateFromStoresObject([ReadStateStore], () => {
let oldestUnreadTimestamp = ReadStateStore.getOldestUnreadTimestamp(channel5.id);
const r12 = {
unreadCount: ReadStateStore.getUnreadCount(channel5.id),
oldestUnreadTimestamp: null
};
if (oldestUnreadTimestamp === 0) {
oldestUnreadTimestamp = SnowflakeUtils.extractTimestamp(channel5.id);
}
r12.oldestUnreadTimestamp = oldestUnreadTimestamp;
return r12;
}, [channel5.id]);
const { unreadCount, oldestUnreadTimestamp } = stateFromStoresObject;
if (channel5.isArchivedLockedThread()) {
r36 = <ArchivedLockedThreadChatBanner channel={channel5} />;
} else if (channel5.isLockedThread()) {
r36 = <LockedThreadChatBanner channel={channel5} />;
} else {
if (unreadCount > 0 && allowedChatOverlays.includes(ChatOverlays.NEW_MESSAGES)) {
r36 = <NewMessagesChatBar unreadCount={unreadCount} oldestUnreadTimestamp={oldestUnreadTimestamp} channel={channel5} handleScrollToNewMessages={handleScrollToNewMessages} />;
break L13;
}
r36 = showChannelOptInNotice ? allowedChatOverlays.includes(ChatOverlays.OPT_IN_CHANNEL) ? <OptInChannelBanner channel={channel5} /> : null : null;
}
}
return r36;
};
export { OptInChannelBanner };