Files
discord-decomp/design/components/Coachmark/native/Coachmark.native.tsx
T
2026-11-01 12:12:55 +02:00

238 lines
8.5 KiB
TypeScript

// Metro module 8439 (f8440).
import { useRef, useState, useCallback, useMemo } from "react";
import { Image as Image2, Pressable, View } from "react-native";
import ReanimatedRexport, { useSharedValue } from "../../../../modules/reanimated/ReanimatedRexport";
import { createStyles } from "../../Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import useTooltipPosition_native from "../../Tooltip/native/useTooltipPosition.native";
import { useButtonPressAnimationProps } from "../../Button/native/ButtonHooks.native";
import { Graphic } from "../../Graphic/native/Graphic.native";
import MobileVisualRefreshExperiment from "../../../../modules/themes/experiments/MobileVisualRefreshExperiment";
import { setAccessibilityFocus } from "../../../../modules/a11y/native/setAccessibilityFocus.android";
import { Text } from "../../Text/native/Text";
import { Button } from "../../Button/native/Button.native";
import { intl, t } from "../../../../intl/index.native";
import { XSmallIcon } from "../../Icon/native/redesign/generated/XSmallIcon";
import { BackgroundBlurView } from "../../experimental/native";
import { ExpressiveGradient } from "../../ExpressiveGradient/native/ExpressiveGradient.native";
import { isIOS, isAndroid } from "../../../../utils/PlatformUtils";
import { useThemeContext, ThemeContextProvider } from "../../../../_bundle/Module3901";
let _excluded, AnimatedComponent, useStyles, c5404_15, Cursor;
const Coachmark = function Coachmark(props) {
let props2;
const { targetMeasurements, surfaceMeasurements, title, description, offsetY = 0, graphic, imgSource, position, onDismiss, buttonLabel } = props;
let buttonVariant = props.buttonVariant;
const { onButtonPress, gradientColor, experimental_withBlurBackground, renderImgComponent, enterExitAnimatedStyles } = props;
const styles = useStyles();
const ref = useRef(null);
const [state, setState] = useState(null);
const tooltipPosition_native = useTooltipPosition_native(state, surfaceMeasurements, targetMeasurements, position, -8 + offsetY);
const { adjustmentX, tooltipX, tooltipY } = tooltipPosition_native;
const sharedValue = useSharedValue(0);
const callback2 = useCallback(() => {
sharedValue.set(1);
}, [sharedValue]);
const callback = useCallback(() => {
sharedValue.set(0);
}, [sharedValue]);
const buttonPressAnimationProps = useButtonPressAnimationProps(sharedValue);
const { style, ...rest } = buttonPressAnimationProps;
const memo = useMemo(() => {
if (graphic != null) {
let aspectRatio = graphic.aspectRatio;
if (aspectRatio == null) {
aspectRatio = "1/1";
}
return <View style={[styles.bottomMargin]}>
<Graphic {...graphic} style={{
height: c5404_15[aspectRatio],
width: "auto"
}} />
</View>;
}
let r7 = renderImgComponent != null ? renderImgComponent() : null;
if (imgSource != null) {
r7 = <Image2 source={imgSource} style={styles.image} />;
}
return r7 == null ? null : <View style={styles.bottomMargin}>{r7}</View>;
}, [graphic, imgSource, renderImgComponent, styles]);
const r84 = MobileVisualRefreshExperiment("Coachmark");
const r109 = [<View ref={ref} accessibilityRole="alert" style={styles.center} accessible onLayout={() => {
setAccessibilityFocus({
ref,
delay: 100
});
}}>
{memo}
<View style={r84 ? styles.textGap : void 0}>
<Text style={[styles.text, graphic == null ? styles.textOnlyPadding : void 0]} variant={r84 ? "text-md/semibold" : "heading-md/bold"} color="mobile-text-heading-primary">{title}</Text>
<Text style={styles.text} variant="text-sm/medium" color={r84 ? "text-subtle" : "text-default"}>{description}</Text>
</View>
</View>, , ,];
const r110 = buttonLabel != null;
let r111 = null;
if (r110) {
const r112 = onButtonPress != null;
r111 = null;
if (r112) {
const r116 = [<View style={styles.buttonSpacing} />, ,];
if (experimental_withBlurBackground) {
props2 = {
variant: "secondary-overlay",
size: "lg",
text: buttonLabel,
onPress: onButtonPress,
grow: true
};
} else {
if (buttonVariant == null) {
buttonVariant = "secondary";
}
props2 = {
variant: buttonVariant,
size: r84 ? "sm" : "lg",
text: buttonLabel,
onPress: onButtonPress,
grow: true
};
}
r116[1] = <Button {...props2} />;
r111 = <>{r116}</>;
}
}
r109[1] = r111;
r109[2] = <Pressable accessibilityRole="button" accessibilityLabel={intl.string(t.cpT0Cq)} style={styles.closeButton} onPress={onDismiss} onPressIn={callback2} onPressOut={callback}>
<XSmallIcon {...r84 ? {
size: "xs",
color: Module712.colors.ICON_STRONG
} : {}} />
</Pressable>;
const r149 = <>{r109}</>;
const r166 = experimental_withBlurBackground ? <BackgroundBlurView style={styles.bodyContainer} blurTheme="dark" pressed={sharedValue}>{r149}</BackgroundBlurView> : <View style={[styles.bodyContainer, styles.bodyBgColor]}>
{r84 ? gradientColor != null ? <ExpressiveGradient style={styles.gradient} color={gradientColor} backgroundColor={Module712.colors.MOBILE_COACHMARK_BACKGROUND_DEFAULT} /> : null : null}
{r149}
</View>;
return <View onLayout={({ nativeEvent }) => {
setState({
width: nativeEvent.layout.width,
height: nativeEvent.layout.height
});
}} style={[styles.container, isIOS() ? styles.shadow : void 0, {
opacity: state != null ? 1 : 0,
top: tooltipY,
left: tooltipX
}]}>
{position === "bottom" && <Cursor position="bottom" adjustmentX={adjustmentX} />}
<AnimatedComponent {...rest} onAccessibilityEscape={onDismiss} accessible={false} onPress={onDismiss} style={[styles.body, ...isAndroid() ? [styles.shadow, enterExitAnimatedStyles] : [], style]}>{r166}</AnimatedComponent>
{position === "top" && <Cursor position="top" adjustmentX={adjustmentX} />}
</View>;
};
Cursor = function Cursor(props) {
const { position, adjustmentX } = props;
const styles2 = useStyles();
const r1 = position === "top";
return <View style={[styles2.cursorContainer, r1 ? {
marginTop: -6
} : {
marginBottom: -6
}, {
flexDirection: r1 ? "column-reverse" : "column",
left: -adjustmentX
}]}>
<View style={styles2.cursorHead} />
<View style={styles2.cursorSpine} />
</View>;
};
_excluded = ["style"];
AnimatedComponent = ReanimatedRexport.createAnimatedComponent(Pressable);
useStyles = createStyles({
container: {
position: "absolute",
alignItems: "center"
},
shadow: {
...Module712.shadows.SHADOW_BUTTON_OVERLAY
},
body: {
width: Module712.modules.mobile.COACHMARK_BODY_WIDTH,
borderRadius: Module712.radii.lg,
overflow: "hidden",
zIndex: 1
},
textGap: {
gap: 4
},
textOnlyPadding: {
paddingHorizontal: Module712.space.PX_24
},
bodyBgColor: {
borderWidth: 1,
borderColor: Module712.colors.MOBILE_COACHMARK_BORDER_DEFAULT,
backgroundColor: Module712.colors.MOBILE_COACHMARK_BACKGROUND_DEFAULT,
borderRadius: Module712.radii.lg
},
gradient: {
borderRadius: Module712.radii.lg,
overflow: "hidden"
},
bodyContainer: {
padding: Module712.space.PX_16,
alignItems: "center",
justifyContent: "center"
},
center: {
alignItems: "center",
justifyContent: "center"
},
buttonSpacing: {
height: Module712.modules.mobile.COACHMARK_BUTTON_SPACING
},
text: {
maxWidth: 200,
textAlign: "center"
},
cursorContainer: {
alignItems: "center",
zIndex: 0
},
cursorHead: {
height: 8,
width: 8,
borderRadius: Module712.radii.xs,
borderWidth: 2,
backgroundColor: "transparent",
borderColor: Module712.colors.INTERACTIVE_TEXT_ACTIVE
},
cursorSpine: {
width: 2,
height: 16,
backgroundColor: Module712.colors.INTERACTIVE_TEXT_ACTIVE
},
image: {
height: 40,
width: 40
},
bottomMargin: {
marginBottom: Module712.modules.mobile.COACHMARK_BUTTON_SPACING
},
closeButton: {
position: "absolute",
top: Module712.modules.mobile.COACHMARK_BUTTON_SPACING,
right: Module712.modules.mobile.COACHMARK_BUTTON_SPACING
}
});
c5404_15 = {
"21/9": 90,
"16/9": 90,
"6/4": 60,
"2/1": 40,
"1/1": 40
};
export { Coachmark };
export function CoachmarkContainer(props) {
const theme = useThemeContext().theme;
return <ThemeContextProvider theme={props.experimental_withBlurBackground ? "dark" : theme}>
<Coachmark {...props} />
</ThemeContextProvider>;
}