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

447 lines
19 KiB
TypeScript

// Metro module 9994 (f9995).
import { useMemo, useCallback, useEffect } from "react";
import { Image as Image2, ScrollView, View } from "react-native";
import EmojiStore from "../../emojis/EmojiStore";
import GuildStore from "../../../stores/GuildStore";
import ReadStateStore from "../../../stores/ReadStateStore";
import SelectedGuildStore from "../../../stores/SelectedGuildStore";
import GuildOnboardingPromptsStore from "../GuildOnboardingPromptsStore";
import { GuildOnboardingTab, OnboardingPromptType } from "../GuildOnboardingPromptsConstants";
import { Fonts } from "../../../Constants";
import { EMOJI_URL_BASE_SIZE } from "../../emojis/EmojiConstants";
import { ReadStateTypes } from "../../read_states/ReadStateConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import TextStyles from "../../rebrand/native/TextStyles";
import * as _themes from "../../../design/utils/shared/themes";
import useTheme from "../../../hooks/useTheme";
import { useStateFromStores, useStateFromStoresArray } from "../../../_bundle/Module589";
import Module9995 from "../../../_bundle/Module9995";
import Module9996 from "../../../_bundle/Module9996";
import { LegacyText, TextBadge, BadgeColors } from "../../../design/void/native";
import { intl, t } from "../../../intl/index.native";
import { Text, Heading } from "../../../design/components/Text/native/Text";
import { getSelectedRoleIds, getSelectedChannelIds } from "../GuildOnboardingUtils";
import usePromptHelpText from "../usePromptHelpText";
import ConnectionCard from "./ConnectionCard";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import useSafeAreaInsets_native from "../../safe_area/useSafeAreaInsets.native";
import useSortedOnboardingPrompts from "../useSortedOnboardingPrompts";
import { fetchOnboardingPrompts } from "../GuildOnboardingPromptsActionCreators";
import { ackGuildFeature } from "../../../actions/ReadStateActionCreators";
import GuildOnboardingActionCreators from "../GuildOnboardingActionCreators";
import Emoji from "../../emojis/native/Emoji";
import AvatarUtils from "../../../utils/AvatarUtils";
import { isNotNullish } from "../../../utils/GlobalUtils";
import { useToken } from "../../../design/tokens/native/useToken";
import * as _ReanimatedRexport from "../../reanimated/ReanimatedRexport";
import ReanimatedRexport, { useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
import * as _timing from "../../../design/animation/reanimated/timing/timing";
import useBatchUpdateSelectOption from "../useBatchUpdateSelectOption";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import { PressableHighlight } from "../../../design/void/Pressables/native/Pressables";
import Module5505 from "../../../_bundle/Module5505";
import GuildOnboardingPromptOptionButton from "./GuildOnboardingPromptOptionButton";
let useStyles, PromptTitle, PromptHelpText, ConnectionsPrompt, DropdownOption, __initData, DropdownPrompt, __initData2, MultipleChoicePrompt;
const EmptyCustomizeCommunity = function EmptyCustomizeCommunity(props) {
const setTab = props.setTab;
const styles = useStyles();
const isThemeDark = _themes.isThemeDark(useTheme());
const stateFromStores = useStateFromStores([SelectedGuildStore], () => SelectedGuildStore.getGuildId());
return <View style={styles.emptyContainer}>
<Image2 style={styles.emptyContainerImage} source={isThemeDark ? Module9995 : Module9996} />
<LegacyText style={styles.emptyContainerHeader}>
{intl.string(t.leKHQz)}
</LegacyText>
<Text variant="text-sm/medium" color="text-subtle">
{intl.format(t["jH+ktB"], {
onBrowseChannels: function onBrowseChannels() {
if (stateFromStores != null) {
setTab(GuildOnboardingTab.BROWSE);
}
}
})}
</Text>
</View>;
};
PromptTitle = function PromptTitle(props) {
const item = props.item;
return <View style={useStyles().titleContainer}>
<Heading variant="text-md/semibold" color="mobile-text-heading-primary">
{item.title}
{item.required ? <Text variant="text-md/bold" color="text-feedback-critical">
{" "}
*
</Text> : null}
</Heading>
</View>;
};
PromptHelpText = function PromptHelpText(props) {
let c17598_2;
const { guildId, prompt: prompt3, selectedOptionIds } = props;
c17598_2 = void 0;
const styles = useStyles();
const stateFromStores3 = useStateFromStores([GuildStore], () => GuildStore.getGuild(guildId));
const r1 = prompt3 == null;
let r14 = void 0;
if (!r1) {
const options = prompt3.options;
r14 = options == null ? void 0 : options.filter((option) => selectedOptionIds.includes(option.id));
}
c17598_2 = r14;
const promptHelpText = usePromptHelpText({
guild: stateFromStores3,
prompt: prompt3,
selectedRoleIds: useMemo(() => c17598_2 != null ? getSelectedRoleIds(c17598_2) : new Set(), [r14]),
selectedChannelIds: useMemo(() => c17598_2 != null ? getSelectedChannelIds(c17598_2) : new Set(), [r14]),
itemHook: function itemHook(a0, a1) {
return <Text key={a1} variant="text-xs/medium" color="mobile-text-heading-primary">
{a0}
</Text>;
}
});
const { helpText, helpTextAdditional } = promptHelpText;
return helpText === "" ? helpTextAdditional !== "" ? <Text style={styles.helpText} variant="text-xs/medium" color="text-default">
{helpText}
{" "}
{helpTextAdditional}
</Text> : null : <Text style={styles.helpText} variant="text-xs/medium" color="text-default">
{helpText}
{" "}
{helpTextAdditional}
</Text>;
};
ConnectionsPrompt = function ConnectionsPrompt(props) {
const guildId2 = props.guildId;
const styles = useStyles();
const stateFromStores3 = useStateFromStores([GuildOnboardingPromptsStore], () => GuildOnboardingPromptsStore.getConnections(guildId2));
return stateFromStores3.length !== 0 ? <View style={styles.connectionsPromptContainer}>
<Text style={styles.connectionsTitle} variant="text-md/semibold" color="mobile-text-heading-primary">
{intl.string(t.eDVMrA)}
</Text>
<Text variant="text-xs/medium" color="text-muted">
{intl.string(t.BozOXu)}
</Text>
<View style={styles.connectionsContainer}>
{stateFromStores3.map((item, index) => <ConnectionCard key={index} connection={item} guildId={guildId2} location={AnalyticsLocation.CHANNELS_AND_ROLES} />)}
</View>
</View> : null;
};
DropdownOption = function DropdownOption(props) {
const option = props.option;
const styles = useStyles();
const stateFromStores3 = useStateFromStores([EmojiStore], () => option.emoji?.id != null ? EmojiStore.getUsableCustomEmojiById(option.emoji?.id) : null);
let r27 = option.emoji?.id != null || option.emoji?.name != null;
if (r27) {
const src = stateFromStores3 != null ? AvatarUtils.getEmojiURL({
id: stateFromStores3.id,
animated: stateFromStores3.animated,
size: EMOJI_URL_BASE_SIZE
}) : void 0;
let name = option.emoji?.name;
if (name == null) {
name = "";
}
r27 = <View style={styles.emojiContainer}>
<Emoji textEmojiStyle={styles.optionTextEmoji} fastImageStyle={styles.optionImageEmoji} src={src} name={name} />
</View>;
}
return <View style={styles.dropdownPill}>
{r27}
<Text variant="text-md/semibold">{option.title}</Text>
</View>;
};
DropdownPrompt = function DropdownPrompt(props) {
let token, handleSelectOption;
const { guildId: guildId3, prompt } = props;
token = void 0;
handleSelectOption = void 0;
const styles = useStyles();
const isNew = prompt.isNew;
const stateFromStoresArray = useStateFromStoresArray([GuildOnboardingPromptsStore], () => GuildOnboardingPromptsStore.getOnboardingResponsesForPrompt(guildId3, prompt.id));
const r16 = stateFromStoresArray.map((c26588_0) => prompt.options.find((option) => option.id === c26588_0)).filter(isNotNullish);
token = useToken(Module712.colors.BACKGROUND_BRAND);
const c = function c() {
const concat = HermesInternal.concat;
return {
borderColor: _ReanimatedRexport.withSequence(_timing.withTiming(isNew ? concat.call("", token, "FF") : concat.call("", token, "00"), {
duration: 1,
easing: _ReanimatedRexport.Easing.in(_ReanimatedRexport.Easing.ease)
}), _ReanimatedRexport.withDelay(500, _timing.withTiming(`${token}00`, {
duration: 300,
easing: _ReanimatedRexport.Easing.out(_ReanimatedRexport.Easing.ease)
})))
};
};
c.__closure = {
isNew,
brandColor: token,
withSequence: _ReanimatedRexport.withSequence,
withTiming: _timing.withTiming,
Easing: _ReanimatedRexport.Easing,
withDelay: _ReanimatedRexport.withDelay
};
c.__workletHash = 16609373875235;
c.__initData = __initData;
const animatedStyle = useAnimatedStyle(c);
handleSelectOption = useBatchUpdateSelectOption(guildId3).handleSelectOption;
const callback = useCallback(() => {
ActionSheetActionCreators.openLazy(import("./DropdownOptionsActionSheet"), "DropdownOptions", {
guildId: guildId3,
promptId: prompt.id,
onSelect: function onSelect(a0, a1) {
let r5 = a1;
if (!((a1 ? !a1 : prompt.required) && stateFromStoresArray.length === 1)) {
if (a1 == null) {
r5 = false;
}
handleSelectOption(prompt, a0, r5);
}
},
canBeNew: !prompt.isNew,
returnToCustomize: true
});
}, [guildId3, prompt, handleSelectOption, stateFromStoresArray.length]);
return <ReanimatedRexport.View style={[styles.promptContainer, animatedStyle]}>
{prompt.isNew && <TextBadge color={BadgeColors.BRAND} text={intl.string(t.y2b7CA)} style={styles.badge} textStyle={styles.badgeText} />}
<PromptTitle item={prompt} />
<PressableHighlight style={styles.dropdownContainer} onPress={callback}>
{r16.length === 0 && <Text style={styles.emptyDropdownText} variant="text-sm/normal" color="text-muted">
{intl.string(t.GmSvdA)}
</Text>}
{r16.map((item) => <DropdownOption key={item.id} option={item} />)}
<View style={styles.dropdownIconContainer}>
<Image2 style={styles.dropdownIcon} source={Module5505} />
</View>
</PressableHighlight>
<PromptHelpText guildId={guildId3} prompt={prompt} selectedOptionIds={stateFromStoresArray} />
</ReanimatedRexport.View>;
};
MultipleChoicePrompt = function MultipleChoicePrompt(props) {
let handleSelectOption2, token2;
const { guildId: guildId4, prompt: prompt2 } = props;
handleSelectOption2 = void 0;
token2 = void 0;
const styles = useStyles();
const isNew2 = prompt2.isNew;
const stateFromStoresArray2 = useStateFromStoresArray([GuildOnboardingPromptsStore], () => GuildOnboardingPromptsStore.getOnboardingResponsesForPrompt(guildId4, prompt2.id));
handleSelectOption2 = useBatchUpdateSelectOption(guildId4).handleSelectOption;
token2 = useToken(Module712.colors.BACKGROUND_BRAND);
const r38 = function() {
const concat = HermesInternal.concat;
return {
borderColor: _ReanimatedRexport.withSequence(_timing.withTiming(isNew2 ? concat.call("", token2, "FF") : concat.call("", token2, "00"), {
duration: 1,
easing: _ReanimatedRexport.Easing.in(_ReanimatedRexport.Easing.ease)
}), _ReanimatedRexport.withDelay(500, _timing.withTiming(`${token2}00`, {
duration: 300,
easing: _ReanimatedRexport.Easing.out(_ReanimatedRexport.Easing.ease)
})))
};
};
r38.__closure = {
isNew: isNew2,
brandColor: token2,
withSequence: _ReanimatedRexport.withSequence,
withTiming: _timing.withTiming,
Easing: _ReanimatedRexport.Easing,
withDelay: _ReanimatedRexport.withDelay
};
r38.__workletHash = 12802766002208;
r38.__initData = __initData2;
return <ReanimatedRexport.View style={[styles.promptContainer, useAnimatedStyle(r38)]}>
{prompt2.isNew && <TextBadge color={BadgeColors.BRAND} text={intl.string(t.y2b7CA)} style={styles.badge} textStyle={styles.badgeText} />}
<PromptTitle item={prompt2} />
{prompt2.options.map((a0) => {
return <GuildOnboardingPromptOptionButton key={a0.id} guildId={guildId4} option={a0} selected={stateFromStoresArray2.includes(a0.id)} onSelect={(event) => {
let r5 = event;
if (!((event ? !event : prompt2.required) && stateFromStoresArray2.length === 1)) {
if (event == null) {
r5 = false;
}
handleSelectOption2(prompt2, a0, r5);
}
}} suppressMemberCount canBeNew={!prompt2.isNew} />;
})}
<PromptHelpText guildId={guildId4} prompt={prompt2} selectedOptionIds={stateFromStoresArray2} />
</ReanimatedRexport.View>;
};
useStyles = createStyles({
container: {
paddingHorizontal: Module712.space.PX_16
},
sheetTitle: {
marginTop: Module712.space.PX_16
},
promptContainer: {
position: "relative",
backgroundColor: Module712.colors.BACKGROUND_SURFACE_HIGH,
marginTop: Module712.space.PX_12,
padding: Module712.space.PX_12,
borderRadius: Module712.radii.md,
borderWidth: 2,
borderStyle: "solid"
},
titleContainer: {
flexDirection: "row",
alignItems: "center",
marginBottom: Module712.space.PX_12
},
badge: {
position: "absolute",
top: -6,
right: -6
},
badgeText: {
fontWeight: "bold"
},
dropdownContainer: {
borderRadius: Module712.radii.lg,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWEST,
padding: Module712.space.PX_8,
paddingRight: Module712.space.PX_32,
minHeight: 48,
marginBottom: Module712.space.PX_12,
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
alignItems: "center",
position: "relative"
},
emptyDropdownText: {
marginVertical: Module712.space.PX_12,
marginLeft: Module712.space.PX_4
},
dropdownPill: {
borderRadius: Module712.radii.sm,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW,
padding: 6,
marginRight: Module712.space.PX_8,
marginTop: Module712.space.PX_8,
display: "flex",
flexDirection: "row",
alignItems: "center"
},
emojiContainer: {
display: "flex",
alignItems: "center"
},
dropdownIconContainer: {
position: "absolute",
right: Module712.space.PX_4,
top: Module712.space.PX_12
},
dropdownIcon: {
height: 32,
width: 32
},
optionTextEmoji: {
fontSize: 18,
lineHeight: 22,
marginRight: 6
},
optionImageEmoji: {
height: 22,
width: 22,
marginRight: 6
},
helpText: {
marginTop: Module712.space.PX_4
},
sectionSeparator: {
marginTop: Module712.space.PX_24,
marginBottom: Module712.space.PX_16,
height: 1,
backgroundColor: Module712.colors.BORDER_SUBTLE
},
emptyContainer: {
height: 400,
display: "flex",
alignItems: "center",
justifyContent: "center"
},
emptyContainerImage: {
width: 120,
height: 80,
marginBottom: Module712.space.PX_16
},
emptyContainerHeader: {
...TextStyles(Fonts.DISPLAY_SEMIBOLD, Module712.colors.MOBILE_TEXT_HEADING_PRIMARY, 18),
marginBottom: Module712.space.PX_4
},
connectionsContainer: {
marginTop: Module712.space.PX_12
},
connectionsPromptContainer: {
marginTop: Module712.space.PX_12
},
connectionsTitle: {
marginBottom: Module712.space.PX_4
}
});
__initData = {
code: "function CustomizeCommunityTsx1(){const{isNew,brandColor,withSequence,withTiming,Easing,withDelay}=this.__closure;const rawBorderColor=isNew?brandColor+\"FF\":brandColor+\"00\";const borderColor=withSequence(withTiming(rawBorderColor,{duration:1,easing:Easing.in(Easing.ease)}),withDelay(500,withTiming(brandColor+\"00\",{duration:300,easing:Easing.out(Easing.ease)})));return{borderColor:borderColor};}"
};
__initData2 = {
code: "function CustomizeCommunityTsx2(){const{isNew,brandColor,withSequence,withTiming,Easing,withDelay}=this.__closure;const rawBorderColor=isNew?brandColor+\"FF\":brandColor+\"00\";const borderColor=withSequence(withTiming(rawBorderColor,{duration:1,easing:Easing.in(Easing.ease)}),withDelay(500,withTiming(brandColor+\"00\",{duration:300,easing:Easing.out(Easing.ease)})));return{borderColor:borderColor};}"
};
export default function CustomizeCommunity(props) {
const { guildId: guildId5, setTab: setTab2 } = props;
const styles = useStyles();
const bottom = useSafeAreaInsets_native().bottom;
const stateFromStores2 = useStateFromStores([ReadStateStore], () => ReadStateStore.hasUnread(guildId5, ReadStateTypes.GUILD_ONBOARDING_QUESTION));
const stateFromStores3 = useStateFromStores([GuildStore], () => GuildStore.getGuild(guildId5)?.latestOnboardingQuestionId);
const sortedOnboardingPrompts = useSortedOnboardingPrompts(guildId5);
const { onboardingPromptsRaw, newOnboardingPrompts, onboardingPromptsWithNewAnswers, newAnswersCount, onboardingPrompts } = sortedOnboardingPrompts;
useEffect(() => {
if (guildId5 != null && (GuildOnboardingPromptsStore.shouldFetchPrompts(guildId5) || stateFromStores2)) {
fetchOnboardingPrompts(guildId5);
}
}, [guildId5, stateFromStores2, stateFromStores3]);
useEffect(() => {
if (guildId5 != null) {
return () => {
ackGuildFeature(guildId5, ReadStateTypes.GUILD_ONBOARDING_QUESTION, GuildOnboardingPromptsStore.ackIdForGuild(guildId5));
GuildOnboardingActionCreators.updateOnboardingResponses(guildId5);
};
}
}, [guildId5]);
const callback = useCallback((a0) => {
const type = a0.type;
if (OnboardingPromptType.MULTIPLE_CHOICE === type) {
return <MultipleChoicePrompt key={a0.id} guildId={guildId5} prompt={a0} />;
}
if (OnboardingPromptType.DROPDOWN === type) {
return <DropdownPrompt key={a0.id} guildId={guildId5} prompt={a0} />;
}
}, [guildId5]);
return onboardingPromptsRaw.length === 0 ? <ScrollView style={styles.container} contentContainerStyle={{
paddingBottom: bottom + Module712.space.PX_16
}}>
<EmptyCustomizeCommunity setTab={setTab2} />
</ScrollView> : <ScrollView style={styles.container} contentContainerStyle={{
paddingBottom: bottom + Module712.space.PX_16
}}>
{(newOnboardingPrompts.length > 0 || onboardingPromptsWithNewAnswers.length > 0) && <>
<Text style={styles.sheetTitle} variant="text-md/medium" color="mobile-text-heading-primary">
{intl.format(t.iB5Gqe, {
count: newOnboardingPrompts.length + newAnswersCount
})}
</Text>
{newOnboardingPrompts.map(callback)}
{onboardingPromptsWithNewAnswers.map(callback)}
<View style={styles.sectionSeparator} />
</>}
{onboardingPrompts.length > 0 && <>
<Text style={styles.sheetTitle} variant="text-md/medium" color="mobile-text-heading-primary">
{intl.string(t.BGkaer)}
</Text>
<Text variant="text-xs/medium" color="text-muted">
{intl.string(t.r6Vm8T)}
</Text>
{onboardingPrompts.map(callback)}
</>}
<ConnectionsPrompt guildId={guildId5} />
</ScrollView>;
};