import React from 'react';
import { View } from 'react-native';
import Animated, {
useAnimatedStyle,
interpolate,
withSpring,
runOnJS,
useAnimatedReaction,
useSharedValue
} from 'react-native-reanimated';
import { RectButton } from 'react-native-gesture-handler';
import * as Haptics from 'expo-haptics';
import { CustomIcon } from '../CustomIcon';
import { DisplayMode } from '../../lib/constants';
import styles, { ACTION_WIDTH, LONG_SWIPE, ROW_HEIGHT_CONDENSED } from './styles';
import { ILeftActionsProps, IRightActionsProps } from './interfaces';
import { useTheme } from '../../theme';
import I18n from '../../i18n';
const CONDENSED_ICON_SIZE = 24;
const EXPANDED_ICON_SIZE = 28;
export const LeftActions = React.memo(({ transX, isRead, width, onToggleReadPress, displayMode }: ILeftActionsProps) => {
const { colors } = useTheme();
const animatedStyles = useAnimatedStyle(() => ({
transform: [{ translateX: transX.value }]
}));
const isCondensed = displayMode === DisplayMode.Condensed;
const viewHeight = isCondensed ? { height: ROW_HEIGHT_CONDENSED } : null;
return (
);
});
export const RightActions = React.memo(({ transX, favorite, width, toggleFav, onHidePress, displayMode }: IRightActionsProps) => {
const { colors } = useTheme();
const animatedFavStyles = useAnimatedStyle(() => ({ transform: [{ translateX: transX.value }] }));
const translateXHide = useSharedValue(0);
const triggerHideAnimation = (toValue: number) => {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
translateXHide.value = withSpring(toValue, { overshootClamping: true, mass: 0.7 });
};
useAnimatedReaction(
() => transX.value,
(currentTransX, previousTransX) => {
// Triggers the animation and hapticFeedback if swipe reaches/unreaches the threshold.
if (I18n.isRTL) {
if (previousTransX && currentTransX > LONG_SWIPE && previousTransX <= LONG_SWIPE) {
runOnJS(triggerHideAnimation)(ACTION_WIDTH);
} else if (previousTransX && currentTransX <= LONG_SWIPE && previousTransX > LONG_SWIPE) {
runOnJS(triggerHideAnimation)(0);
}
} else if (previousTransX && currentTransX < -LONG_SWIPE && previousTransX >= -LONG_SWIPE) {
runOnJS(triggerHideAnimation)(-ACTION_WIDTH);
} else if (previousTransX && currentTransX >= -LONG_SWIPE && previousTransX < -LONG_SWIPE) {
runOnJS(triggerHideAnimation)(0);
}
}
);
const animatedHideStyles = useAnimatedStyle(() => {
if (I18n.isRTL) {
if (transX.value < LONG_SWIPE && transX.value >= 2 * ACTION_WIDTH) {
const parallaxSwipe = interpolate(
transX.value,
[2 * ACTION_WIDTH, LONG_SWIPE],
[ACTION_WIDTH, ACTION_WIDTH + 0.1 * transX.value]
);
return { transform: [{ translateX: parallaxSwipe + translateXHide.value }] };
}
return { transform: [{ translateX: transX.value - ACTION_WIDTH + translateXHide.value }] };
}
if (transX.value > -LONG_SWIPE && transX.value <= -2 * ACTION_WIDTH) {
const parallaxSwipe = interpolate(
transX.value,
[-2 * ACTION_WIDTH, -LONG_SWIPE],
[-ACTION_WIDTH, -ACTION_WIDTH + 0.1 * transX.value]
);
return { transform: [{ translateX: parallaxSwipe + translateXHide.value }] };
}
return { transform: [{ translateX: transX.value + ACTION_WIDTH + translateXHide.value }] };
});
const isCondensed = displayMode === DisplayMode.Condensed;
const viewHeight = isCondensed ? { height: ROW_HEIGHT_CONDENSED } : null;
return (
);
});