166 lines
4.9 KiB
TypeScript
166 lines
4.9 KiB
TypeScript
import React, { useEffect, useState } from "react";
|
|
|
|
import { StyledLottie } from "../styled-lottie/StyledLottie";
|
|
|
|
import {
|
|
NativeEventEmitter,
|
|
NativeModules,
|
|
Platform,
|
|
ViewStyle,
|
|
useWindowDimensions,
|
|
} from "react-native";
|
|
|
|
import {
|
|
PanGestureHandler,
|
|
State,
|
|
TapGestureHandler,
|
|
} from "react-native-gesture-handler";
|
|
|
|
import Animated, {
|
|
clamp,
|
|
useAnimatedGestureHandler,
|
|
useAnimatedStyle,
|
|
useSharedValue,
|
|
} from "react-native-reanimated";
|
|
import { GenericActionPayload } from "../../../App/common/actions/GenericAction";
|
|
import {
|
|
FAB_WIDTH_LARGE,
|
|
FAB_WIDTH_SMALL,
|
|
FabIconSize,
|
|
OsTypeConstants,
|
|
} from "../../../App/common/constants";
|
|
import { NativeEventNameConstants } from "../../../App/common/constants/EventNameConstants";
|
|
import { CtaData } from "../../../App/common/interface";
|
|
import { FabWidgetData } from "../../../App/common/interface/widgets/widgetData/FabWidgetData";
|
|
import { getTextWithHtmlSpace } from "../../../App/common/utilities/MiscUtils";
|
|
import { StyledImage } from "../../StyledImage";
|
|
import { createStyles } from "./FABStyle";
|
|
|
|
const FAB = ({
|
|
widgetData,
|
|
handleActions,
|
|
handleClick,
|
|
scrollStyle,
|
|
}: {
|
|
widgetData: FabWidgetData;
|
|
handleActions: (
|
|
value: any | undefined | null,
|
|
actionPayloadList: GenericActionPayload | undefined,
|
|
) => void;
|
|
handleClick?: (cta: CtaData) => void;
|
|
scrollStyle?: ViewStyle;
|
|
}) => {
|
|
const [enabled, setEnabled] = useState(true);
|
|
const { height } = useWindowDimensions();
|
|
useEffect(() => {
|
|
const nativeEventListener =
|
|
Platform.OS === OsTypeConstants.ANDROID
|
|
? new NativeEventEmitter()
|
|
: new NativeEventEmitter(NativeModules.DeviceEventEmitterModule);
|
|
let reloadPageEventListener = nativeEventListener.addListener(
|
|
NativeEventNameConstants.reloadPage,
|
|
event => {
|
|
if (event === true) {
|
|
setEnabled(false);
|
|
}
|
|
},
|
|
);
|
|
return () => {
|
|
nativeEventListener.removeAllListeners(
|
|
NativeEventNameConstants.reloadPage,
|
|
);
|
|
setEnabled(true);
|
|
};
|
|
}, [widgetData]);
|
|
|
|
const FAB_STARTING_POSITION = widgetData?.properties?.startingPosition ?? 145;
|
|
const getFabWidth = (fabIconSize?: string) =>
|
|
fabIconSize === FabIconSize.SMALL ? FAB_WIDTH_SMALL : FAB_WIDTH_LARGE;
|
|
const FAB_WIDTH = getFabWidth(widgetData?.properties?.fabIconSize);
|
|
const styles = createStyles(FAB_WIDTH);
|
|
const FAB_HEIGHT = FAB_WIDTH;
|
|
|
|
const fabPositionY = useSharedValue(-FAB_STARTING_POSITION);
|
|
|
|
const _onTapHandlerStateChange = ({ nativeEvent }: { nativeEvent: any }) => {
|
|
if (
|
|
handleClick &&
|
|
widgetData?.callbackCta &&
|
|
nativeEvent.state === State.ACTIVE
|
|
) {
|
|
handleClick(widgetData?.callbackCta);
|
|
}
|
|
};
|
|
|
|
const _onPanHandlerStateChange = useAnimatedGestureHandler({
|
|
onStart: (_, ctx) => {
|
|
ctx.startY = fabPositionY.value;
|
|
},
|
|
onActive: (event, ctx: any) => {
|
|
const newY = ctx.startY + event.translationY;
|
|
const minY = -height + 2 * FAB_HEIGHT;
|
|
const maxY = 0;
|
|
fabPositionY.value = clamp(newY, minY, maxY);
|
|
},
|
|
onEnd: _ => {},
|
|
});
|
|
|
|
const animatedRootStyles = useAnimatedStyle(() => {
|
|
return {
|
|
transform: [{ translateY: fabPositionY.value }],
|
|
};
|
|
});
|
|
|
|
const isDraggable = widgetData?.properties?.isDraggable ?? true;
|
|
const buttonText = getTextWithHtmlSpace(widgetData?.buttonTitle?.text);
|
|
|
|
const fabContent = (
|
|
<Animated.View style={[styles.rootStyles, animatedRootStyles]}>
|
|
<TapGestureHandler
|
|
enabled={enabled}
|
|
onHandlerStateChange={_onTapHandlerStateChange}
|
|
>
|
|
<Animated.View style={styles.fabButtonStyles}>
|
|
{widgetData.topLottieData && (
|
|
<Animated.View style={styles.topLottie}>
|
|
<StyledLottie lottieFieldData={widgetData?.topLottieData} />
|
|
</Animated.View>
|
|
)}
|
|
{widgetData?.imageData && (
|
|
<Animated.View style={styles.image}>
|
|
<StyledImage imageFieldData={widgetData?.imageData} />
|
|
</Animated.View>
|
|
)}
|
|
{widgetData?.buttonTitle?.text && (
|
|
<Animated.View style={[styles.buttonTitle, scrollStyle]}>
|
|
<Animated.Text style={widgetData?.buttonTitle?.textStyle}>
|
|
{buttonText}
|
|
</Animated.Text>
|
|
</Animated.View>
|
|
)}
|
|
{widgetData.lottieData &&
|
|
!!!widgetData.topLottieData &&
|
|
!!!widgetData.imageData &&
|
|
!!!widgetData.buttonTitle?.text && (
|
|
<Animated.View style={styles.lottie}>
|
|
<StyledLottie lottieFieldData={widgetData?.lottieData} />
|
|
</Animated.View>
|
|
)}
|
|
</Animated.View>
|
|
</TapGestureHandler>
|
|
</Animated.View>
|
|
);
|
|
|
|
/* remove backward compatibility code in next release */
|
|
|
|
return isDraggable ? (
|
|
<PanGestureHandler onHandlerStateChange={_onPanHandlerStateChange}>
|
|
{fabContent}
|
|
</PanGestureHandler>
|
|
) : (
|
|
fabContent
|
|
);
|
|
};
|
|
|
|
export default FAB;
|