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

311 lines
14 KiB
TypeScript

// Metro module 15354 (f15355).
import { useCallback, useState, useRef, useEffect } from "react";
import { StyleSheet, View } from "react-native";
import AccessibilityStore from "../../../a11y/AccessibilityStore";
import GuildStore from "../../../../stores/GuildStore";
import ICYMIPopularGuildsStore from "../../ICYMIPopularGuildsStore";
import { GuildFeatures } from "../../../../Constants";
import { createICYMIStyles } from "../createICYMIStyles";
import Module712 from "../../../../_bundle/Module712";
import GuildIcon, { GuildIconSizes } from "../../../guild/native/GuildIcon";
import { ServerIcon } from "../../../../design/components/Icon/native/redesign/generated/ServerIcon";
import ReanimatedRexport, { useAnimatedStyle } from "../../../reanimated/ReanimatedRexport";
import * as _timing from "../../../../design/animation/reanimated/timing/timing";
import FastestList_android from "../../../fastest_list/FastestList.android";
import { useStateFromStores, useStateFromStoresArray } from "../../../../_bundle/Module589";
import AvatarUtils from "../../../../utils/AvatarUtils";
import ClipView, { CutoutShape } from "../../../../design/components/Icon/native/ClipView";
import FastImage from "../../../../components_native/common/FastImage";
import { PressableHighlight } from "../../../../design/void/Pressables/native/Pressables";
import { Text } from "../../../../design/components/Text/native/Text";
import { Button } from "../../../../design/components/Button/native/Button.native";
import { CircleCheckIcon } from "../../../../design/components/Icon/native/redesign/generated/CircleCheckIcon";
import { intl, t } from "../../../../intl/index.native";
import useSafeAreaInsets_native from "../../../safe_area/useSafeAreaInsets.native";
import { ICYMIAnalytics } from "../../ICYMIAnalytics";
import ICYMIActionCreators from "../../ICYMIActionCreators";
import ToastActionCreators from "../../../toast/native/ToastActionCreators";
import ModalActionCreators from "../../../../actions/ModalActionCreators";
import { ICYMI_INFO_MODAL_KEY, ICYMI_DISCOVERABLE_GUILDS_PAGE_SIZE } from "./ICYMIInfoModalTypes";
import { MasonryFlashList } from "../../../../_bundle/noop_6676";
let SELECTED_SERVER_SIZE_WITH_BORDER, styles, __initData, SelectedServersRow, CutoutGuildBanner, FeaturedServer;
const SelectedServerIcon = function SelectedServerIcon(props) {
const { guild: guild3, index } = props;
const r13 = styles();
const r2 = index < 3;
return <View style={[r13.selectedServerIcon, guild3 == null && r13.noServerContainer, guild3 == null && !r2 && r13.noServerExtraContainer]}>
{guild3 != null ? <GuildIcon style={r13.guildIconBorder} guild={guild3} size={GuildIconSizes.LARGE} /> : r2 ? <ServerIcon size="md" color={Module712.colors.ICON_MUTED} /> : null}
</View>;
};
SelectedServersRow = function SelectedServersRow(props) {
let state, setState, ref;
const selectedGuilds = props.selectedGuilds;
state = void 0;
setState = void 0;
ref = void 0;
const r7 = styles();
const callback2 = useCallback((a0, a1) => <SelectedServerIcon guild={a1 < selectedGuilds.length ? selectedGuilds[a1] : void 0} index={a1} />, [selectedGuilds]);
[state, setState] = useState(selectedGuilds.length);
ref = useRef(null);
useEffect(() => {
if (state < selectedGuilds.length) {
const current = ref.current;
if (current != null) {
current.scrollToLocation({
animated: true,
section: 0,
item: selectedGuilds.length
});
}
setState(selectedGuilds.length);
} else if (state !== selectedGuilds.length) {
setState(selectedGuilds.length);
}
}, [state, selectedGuilds.length]);
const _ = function _() {
return {
opacity: _timing.withTiming(selectedGuilds.length > 0 ? 1 : 0),
height: _timing.withTiming(selectedGuilds.length > 0 ? SELECTED_SERVER_SIZE_WITH_BORDER : 0),
marginTop: _timing.withTiming(selectedGuilds.length > 0 ? Module712.space.PX_24 : 0)
};
};
_.__closure = {
withTiming: _timing.withTiming,
selectedGuilds,
SELECTED_SERVER_SIZE_WITH_BORDER,
tokens: Module712
};
_.__workletHash = 2911488630455;
_.__initData = __initData;
return <ReanimatedRexport.View style={[r7.selectedServersRowContainer, useAnimatedStyle(_)]}>
<FastestList_android ref={ref} sections={[selectedGuilds.length >= 3 ? selectedGuilds.length + 1 : 3]} insetStart={Module712.space.PX_24} insetEnd={Module712.space.PX_12} renderItem={callback2} estimatedListSize="windowSize" itemSize={SELECTED_SERVER_SIZE_WITH_BORDER + Module712.space.PX_12} horizontal listId="selected-servers-list" showsHorizontalScrollIndicator={false} />
</ReanimatedRexport.View>;
};
CutoutGuildBanner = function CutoutGuildBanner(props) {
const guild = props.guild;
const r15 = styles();
const stateFromStores2 = useStateFromStores([AccessibilityStore], () => AccessibilityStore.useReducedMotion);
const r24 = stateFromStores2 ? !stateFromStores2 : guild.features.has(GuildFeatures.ANIMATED_BANNER);
const source = guild.banner != null ? AvatarUtils.getAnimatableSourceWithFallback(r24, (a0) => AvatarUtils.getGuildBannerSource({
id: guild.id,
banner: guild.banner
}, a0)) : void 0;
return <View style={r15.bannerImage}>
<ClipView cutouts={[{
shape: CutoutShape.RoundedRect,
x: 8,
y: 46,
width: 56,
height: 56,
cornerRadius: 20
}]}>
{guild.banner != null ? <FastImage style={r15.bannerImage} source={source} resizeMode="cover" /> : <View style={[r15.bannerImage, r15.emptyBanner]} />}
</ClipView>
<GuildIcon style={[r15.guildIcon, r15.guildIconBorder]} guild={guild} size={GuildIconSizes.LARGE} animate={!stateFromStores2} />
</View>;
};
FeaturedServer = function FeaturedServer(props) {
const { guild: guild2, selected, loading, handlePress } = props;
const r10 = styles();
const stateFromStores2 = useStateFromStores([GuildStore], () => GuildStore.getGuild(guild2.id) != null);
const callback2 = useCallback(() => {
handlePress(guild2);
}, [guild2, handlePress]);
const r42 = [<CutoutGuildBanner guild={guild2} />, ,];
const r50 = [<Text maxFontSizeMultiplier={1} style={r10.featuredServerTitle} variant="text-md/semibold" color="mobile-text-heading-primary">{guild2.name}</Text>, <Text maxFontSizeMultiplier={1} lineClamp={2} variant="text-xs/normal" color="text-default">{guild2.description}</Text>, <View style={r10.buttonContainer}>
<Button accessibilityHint="checkbox" accessibilityState={{
checked: selected
}} disabled={stateFromStores2} icon={selected ? <CircleCheckIcon size="sm" color={Module712.colors.CONTROL_CONNECTED_TEXT_DEFAULT} /> : void 0} text={stateFromStores2 && !loading ? intl.string(t.cEnaWx) : selected ? intl.string(t["TwueC+"]) : intl.string(t.XqMe3N)} size="sm" onPress={callback2} variant={stateFromStores2 ? "secondary" : selected ? "active" : "secondary"} grow />
</View>];
r42[1] = <View style={r10.featuredServerInnerContainer}>{r50}</View>;
return <PressableHighlight underlayColor={r10.pressableUnderlayColor.backgroundColor} unstable_pressDelay={50} style={r10.featuredServerContainer} onPress={callback2}>{r42}</PressableHighlight>;
};
SELECTED_SERVER_SIZE_WITH_BORDER = 50;
styles = createICYMIStyles((a0) => ({
container: {
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWER,
position: "relative",
flex: 1,
marginHorizontal: a0.margin
},
scrollContentContainer: {
paddingTop: Module712.space.PX_8
},
footer: {
position: "absolute",
bottom: 0,
left: Module712.space.PX_24,
right: Module712.space.PX_24,
paddingBottom: Module712.space.PX_8
},
title: {
marginTop: Module712.space.PX_24,
marginBottom: Module712.space.PX_8,
marginHorizontal: Module712.space.PX_24
},
subtitle: {
marginHorizontal: Module712.space.PX_24
},
separator: {
height: StyleSheet.hairlineWidth,
width: "100%",
backgroundColor: Module712.colors.BORDER_SUBTLE
},
featuredServerContainer: {
borderRadius: Module712.radii.lg,
backgroundColor: Module712.colors.CARD_BACKGROUND_DEFAULT,
overflow: "hidden",
marginHorizontal: Module712.space.PX_8,
marginVertical: Module712.space.PX_8
},
featuredServerInnerContainer: {
marginHorizontal: Module712.space.PX_12,
marginTop: 36
},
buttonContainer: {
marginBottom: Module712.space.PX_12,
marginTop: a0.margin
},
featuredServerTitle: {
marginBottom: Module712.space.PX_8
},
guildIcon: {
position: "absolute",
top: 50,
left: 12
},
bannerImage: {
height: 73,
width: "100%"
},
emptyBanner: {
backgroundColor: Module712.colors.BACKGROUND_MOD_SUBTLE
},
guildsScrollContainer: {
flex: 1,
marginHorizontal: Module712.space.PX_8
},
guildsColumn: {
flex: 1,
flexDirection: "column",
gap: Module712.space.PX_16
},
selectedServersRowContainer: {
height: SELECTED_SERVER_SIZE_WITH_BORDER,
width: "100%",
marginBottom: Module712.space.PX_24
},
selectedServerIcon: {
flex: 1,
width: SELECTED_SERVER_SIZE_WITH_BORDER,
height: SELECTED_SERVER_SIZE_WITH_BORDER,
alignItems: "center",
justifyContent: "center",
borderColor: Module712.colors.BORDER_STRONG,
borderRadius: Module712.radii.md,
borderWidth: 1
},
noServerContainer: {
backgroundColor: Module712.colors.BACKGROUND_MOD_MUTED,
borderStyle: "dashed"
},
noServerExtraContainer: {
opacity: 0.4
},
pressableUnderlayColor: {
backgroundColor: Module712.colors.INTERACTIVE_BACKGROUND_ACTIVE
},
guildIconBorder: {
borderRadius: Module712.radii.md
}
}));
__initData = {
code: "function ICYMIJoinGuildsScreenTsx1(){const{withTiming,selectedGuilds,SELECTED_SERVER_SIZE_WITH_BORDER,tokens}=this.__closure;return{opacity:withTiming(selectedGuilds.length>0?1:0),height:withTiming(selectedGuilds.length>0?SELECTED_SERVER_SIZE_WITH_BORDER:0),marginTop:withTiming(selectedGuilds.length>0?tokens.space.PX_24:0)};}"
};
export default function ICYMIJoinGuildsScreen() {
let stateFromStoresArray2, stateFromStores, callback;
const r12 = styles();
const bottom = useSafeAreaInsets_native().bottom;
const stateFromStoresArray = useStateFromStoresArray([ICYMIPopularGuildsStore], () => ICYMIPopularGuildsStore.getOnboardingGuilds());
stateFromStoresArray2 = useStateFromStoresArray([ICYMIPopularGuildsStore], () => ICYMIPopularGuildsStore.getOnboardingCategoryIds());
stateFromStores = useStateFromStores([ICYMIPopularGuildsStore], () => ICYMIPopularGuildsStore.getCurrentOnboardingGuildOffset());
const [state2, setState2] = useState(new Set());
let [selectedGuilds2, setState3] = useState([]);
const [state3, setState4] = useState(0);
callback = useCallback((a0) => {
ICYMIAnalytics.trackFeedOnboardingGuildToggled({
guildId: a0.id,
toggled: !state2.has(a0.id)
});
if (state2.has(a0.id)) {
setState2((prevState2) => {
prevState2.delete(a0.id);
return new Set(prevState2);
});
setState3((prevState3) => prevState3.filter((item) => a0.id !== item.id));
} else {
setState2((prevState2) => {
prevState2.add(a0.id);
return new Set(prevState2);
});
setState3((prevState3) => [...prevState3, a0]);
}
}, [state2]);
const [state4, setState5] = useState(false);
const callback2 = useCallback(async () => {
let c28005_0;
L16: {
c28005_0 = void 0;
setState5(true);
if (await ICYMIActionCreators.gravityJoinGuild(Array.from(state2), "icymi_info_modal")) {
await ICYMIActionCreators.fetchDehydrated({
isReloading: true,
forceRefresh: true
});
await ICYMIActionCreators.reloadICYMITab();
ICYMIActionCreators.getGuildChannelScores();
ICYMIActionCreators.getRecommendedGuilds();
ModalActionCreators.popWithKey(ICYMI_INFO_MODAL_KEY);
break L16;
}
ToastActionCreators.open({
key: "ICYMIInfoModal",
content: intl.string(t.CG4Hks)
});
ICYMIActionCreators.fetchDehydrated();
ICYMIActionCreators.getGuildChannelScores();
ICYMIActionCreators.getRecommendedGuilds();
ModalActionCreators.popWithKey(ICYMI_INFO_MODAL_KEY);
return void 0;
}
}, [state2]);
const callback3 = useCallback(() => {
if (!(state3 > stateFromStores) && !(stateFromStoresArray.length >= 150)) {
const r13 = stateFromStores + ICYMI_DISCOVERABLE_GUILDS_PAGE_SIZE;
setState4(r13);
ICYMIActionCreators.fetchPopularGuildsFromCategories(stateFromStoresArray2, r13);
}
}, [stateFromStoresArray2, stateFromStores, state3, stateFromStoresArray.length]);
const callback4 = useCallback(({ item }) => <FeaturedServer key={item.id} guild={item} loading={state4} selected={state2.has(item.id)} handlePress={callback} />, [state4, state2, callback]);
return <>
<Text variant="heading-xl/semibold" color="mobile-text-heading-primary" style={r12.title}>
{intl.string(t["19ldCF"])}
</Text>
<Text variant="text-sm/normal" color="text-muted" style={r12.subtitle}>
{intl.string(t.u0KPUS)}
</Text>
<SelectedServersRow selectedGuilds={selectedGuilds2} />
<View style={r12.separator} />
<View style={r12.guildsScrollContainer}>
<MasonryFlashList data={stateFromStoresArray} extraData={state2} contentContainerStyle={r12.scrollContentContainer} contentInset={{
bottom: 72 + bottom
}} numColumns={2} onEndReached={callback3} onEndReachedThreshold={0.5} showsHorizontalScrollIndicator={false} showsVerticalScrollIndicator={false} renderItem={callback4} />
</View>
{state2.size >= 1 && <View style={[{
marginBottom: bottom
}, r12.footer]}>
<Button loading={state4} size="lg" text={intl.string(t.K50GHd)} onPress={callback2} />
</View>}
</>;
};