Files
discord-decomp/modules/collectibles/native/tooling/CollectiblesTool.tsx
T
2026-11-01 12:12:55 +02:00

263 lines
10 KiB
TypeScript

// Metro module 14819 (f14820).
import { useState, useLayoutEffect, useEffect } from "react";
import { ScrollView, View } from "react-native";
import CollectiblesCategoryStore from "../../CollectiblesCategoryStore";
import CollectiblesPurchaseStore from "../../CollectiblesPurchaseStore";
import { useFramePreviewOverrideStore } from "../../profile_frames/native/tooling/FramePreviewOverrideStore";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import CollectiblesShopCardV2 from "../CollectiblesShopCardV2";
import { Text } from "../../../../design/components/Text/native/Text";
import { BaseTextButton } from "../../../../design/components/Button/native/BaseTextButton.native";
import { useStateFromStores } from "../../../../_bundle/defaultAreStatesEqual";
import useFetchCollectiblesCategoriesAndPurchases from "../../hooks/useFetchCollectiblesCategoriesAndPurchases";
import { ShopSkipCategoriesFilter } from "./ShopSkipCategoriesFilter";
import { TextInput } from "../../../../design/void/native";
import ProductPurchaseSuccessActionCreators from "../ProductPurchaseSuccessActionCreators";
let useStyles, UnpurchasedCollectiblesShopCardV2;
const FramePreviewOverrideSection = function FramePreviewOverrideSection() {
let r37;
let framePreviewOverrideStore;
const styles = useStyles();
const framePreviewOverrideStore3 = useFramePreviewOverrideStore((a0) => a0.override);
const framePreviewOverrideStore2 = useFramePreviewOverrideStore((a0) => a0.status);
let r5 = useFramePreviewOverrideStore((a0) => a0.error);
framePreviewOverrideStore = useFramePreviewOverrideStore((a0) => a0.loadFromDevice);
const framePreviewOverrideStore4 = useFramePreviewOverrideStore((a0) => a0.clear);
const r3 = framePreviewOverrideStore2 === "error";
const r19 = r3 ? styles.statusError : framePreviewOverrideStore2 === "loading" ? styles.statusLoading : styles.statusSuccess;
let r17 = "Loading…";
if (framePreviewOverrideStore2 !== "loading") {
if (r3) {
if (r5 == null) {
r5 = "Failed to load";
}
r37 = r5;
} else {
r37 = framePreviewOverrideStore3 != null ? `Showing "${framePreviewOverrideStore3.frameKey}" · ${framePreviewOverrideStore3.layers.length} layer${framePreviewOverrideStore3.layers.length === 1 ? "" : "s"}` : "No frame loaded";
}
r17 = r37;
}
return <View style={styles.section}>
<View style={styles.sectionHeader}>
<Text variant="heading-md/semibold" style={styles.sectionTitle}>Frame Preview Override</Text>
</View>
<Text variant="text-sm/normal" style={styles.description}>Overrides every profile-frame preview with a frame pushed to this device. Tap Load after Cap (or pushFrameOverride.mjs) pushes one.</Text>
<Text variant="text-xs/normal" style={[styles.statusText, r19]}>{r17}</Text>
<BaseTextButton pillStyle={styles.secondaryButton} text="Load from device" onPress={() => {
framePreviewOverrideStore();
}} />
{framePreviewOverrideStore3 != null && <BaseTextButton pillStyle={styles.secondaryButton} text="Clear override" onPress={framePreviewOverrideStore4} />}
</View>;
};
useStyles = createStyles({
container: {
flex: 1,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW
},
scrollContainer: {
padding: Module712.space.PX_16,
paddingBottom: Module712.space.PX_32
},
section: {
backgroundColor: Module712.colors.BACKGROUND_SURFACE_HIGH,
borderRadius: Module712.radii.lg,
padding: Module712.space.PX_16,
marginBottom: Module712.space.PX_16,
borderWidth: 1,
borderColor: Module712.colors.BORDER_MUTED
},
sectionHeader: {
flexDirection: "row",
alignItems: "center",
marginBottom: Module712.space.PX_16
},
sectionTitle: {
flex: 1,
color: Module712.colors.TEXT_DEFAULT
},
inputContainer: {
marginBottom: Module712.space.PX_16
},
inputWrapper: {
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW,
borderRadius: Module712.radii.md,
borderWidth: 1,
borderColor: Module712.colors.BORDER_MUTED,
padding: Module712.space.PX_4
},
inputLabel: {
marginBottom: Module712.space.PX_8,
color: Module712.colors.TEXT_DEFAULT,
fontWeight: "600"
},
statusText: {
marginTop: Module712.space.PX_8,
fontSize: 12,
fontWeight: "500"
},
statusSuccess: {
color: Module712.colors.TEXT_FEEDBACK_POSITIVE
},
statusError: {
color: Module712.colors.TEXT_FEEDBACK_CRITICAL
},
statusLoading: {
color: Module712.colors.TEXT_MUTED
},
previewContainer: {
marginBottom: Module712.space.PX_16
},
previewButton: {
backgroundColor: "#23a55a",
borderRadius: Module712.radii.md,
paddingVertical: Module712.space.PX_12,
alignItems: "center"
},
secondaryButton: {
backgroundColor: Module712.colors.BACKGROUND_MOD_NORMAL,
borderRadius: Module712.radii.md,
paddingVertical: Module712.space.PX_12,
alignItems: "center",
marginTop: Module712.space.PX_8
},
description: {
color: Module712.colors.TEXT_MUTED,
marginBottom: Module712.space.PX_12
},
placeholder: {
backgroundColor: Module712.colors.BACKGROUND_MOD_NORMAL,
borderRadius: Module712.radii.md,
borderWidth: 2,
borderStyle: "dashed",
borderColor: Module712.colors.BORDER_MUTED,
padding: Module712.space.PX_32,
alignItems: "center",
justifyContent: "center",
minHeight: 120
},
placeholderText: {
color: Module712.colors.TEXT_MUTED,
textAlign: "center",
fontSize: 14
}
});
UnpurchasedCollectiblesShopCardV2 = (props) => {
const [key, setState] = useState(0);
useLayoutEffect(() => {
const getPurchase = CollectiblesPurchaseStore.getPurchase;
CollectiblesPurchaseStore.getPurchase = () => {};
CollectiblesPurchaseStore.emitChange();
setState(1);
return () => {
CollectiblesPurchaseStore.getPurchase = getPurchase;
CollectiblesPurchaseStore.emitChange();
};
}, []);
return <CollectiblesShopCardV2 key={key} {...props} />;
};
export default () => {
const styles = useStyles();
const stateFromStores = useStateFromStores([CollectiblesCategoryStore], () => CollectiblesCategoryStore.categories);
const stateFromStores2 = useStateFromStores([CollectiblesPurchaseStore], () => CollectiblesPurchaseStore.purchases);
const stateFromStores3 = useStateFromStores([CollectiblesCategoryStore], () => CollectiblesCategoryStore.lastSuccessfulFetch);
const noOp = stateFromStores.size > 0 && stateFromStores2.size > 0 && stateFromStores3 != null;
const fetchCollectiblesCategoriesAndPurchases = useFetchCollectiblesCategoriesAndPurchases({
logPerf: false,
stalePurchasesOK: true,
noOp
});
const isFetching = fetchCollectiblesCategoriesAndPurchases.isFetching;
let categories = fetchCollectiblesCategoriesAndPurchases.categories;
let r21 = noOp;
if (!r21) {
let r54 = !isFetching;
if (!isFetching) {
if (noOp) {
categories = stateFromStores;
}
r54 = categories.size > 0;
}
r21 = r54;
}
let c21374_0 = r21;
const [state, onChangeText] = useState("");
const [state2, setState2] = useState(null);
const [state3, setState3] = useState(null);
useEffect(() => {
if (state.trim() !== "" && c21374_0) {
const product = CollectiblesCategoryStore.getProduct(state);
const categoryForProduct = CollectiblesCategoryStore.getCategoryForProduct(state);
if (product != null && categoryForProduct != null) {
setState2(product);
setState3(categoryForProduct);
} else {
setState2(null);
setState3(null);
}
return void 0;
}
setState2(null);
setState3(null);
}, [state, r21]);
const r96 = [<View style={styles.section}>
<View style={styles.sectionHeader}>
<Text variant="heading-md/semibold" style={styles.sectionTitle}>Shop Settings</Text>
</View>
<ShopSkipCategoriesFilter />
</View>, , , ,];
const r107 = [<View style={styles.sectionHeader}>
<Text variant="heading-md/semibold" style={styles.sectionTitle}>Product Configuration</Text>
</View>, ,];
const r115 = [<Text variant="text-md/semibold" style={styles.inputLabel}>Primary Product SKU ID</Text>, <View style={styles.inputWrapper}>
<TextInput value={state} onChangeText={onChangeText} placeholder="Enter product SKU ID (e.g., 1366494385482502184)" returnKeyType="done" style={{
fontSize: 14,
padding: Module712.space.PX_12
}} />
</View>, (r21 ? !r21 : state.trim() !== "") && <Text variant="text-xs/normal" style={[styles.statusText, styles.statusLoading]}>Loading products...</Text>, , ,];
if (r21) {
r21 = state.trim() !== "";
}
if (r21) {
r21 = state2 == null;
}
if (r21) {
r21 = <Text variant="text-xs/normal" style={[styles.statusText, styles.statusError]}>Product not found</Text>;
}
r115[3] = r21;
r115[4] = state2 != null && <Text variant="text-xs/normal" style={[styles.statusText, styles.statusSuccess]}>
{"Found: "}
{state2.name}
</Text>;
r107[1] = <View style={styles.inputContainer}>{r115}</View>;
r96[1] = <View style={styles.section}>{r107}</View>;
r96[2] = <View style={styles.section}>
<View style={styles.sectionHeader}>
<Text variant="heading-md/semibold" style={styles.sectionTitle}>Product Preview</Text>
</View>
{state2 != null && state3 != null ? <View>
<View style={styles.previewContainer}>
<UnpurchasedCollectiblesShopCardV2 product={state2} />
</View>
<BaseTextButton pillStyle={styles.previewButton} text="Show Collectibles Modal" onPress={function onPress() {
if (state2 != null) {
ProductPurchaseSuccessActionCreators.open({
product: state2,
useCategoryImage: true
});
}
}} />
</View> : <View style={styles.placeholder}>
<Text variant="text-sm/normal" style={styles.placeholderText}>
Enter a valid product SKU ID above
{"\n"}
to see the product preview
</Text>
</View>}
</View>;
r96[3] = <FramePreviewOverrideSection />;
return <View style={styles.container}>
<ScrollView contentContainerStyle={styles.scrollContainer} showsVerticalScrollIndicator={false}>{r96}</ScrollView>
</View>;
};