import React, { useCallback, useContext, useRef, useState } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { I18nContext } from '../../../contexts/i18n'; import { AlignItems, Display, JustifyContent, } from '../../../helpers/constants/design-system'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { MetaMetricsEventCategory, MetaMetricsEventKeyType, MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; import { Button, Box } from '../../component-library'; const radius = 14; const strokeWidth = 2; const radiusWithStroke = radius - strokeWidth / 2; export default function HoldToRevealButton({ buttonText, onLongPressed }) { const t = useContext(I18nContext); const isLongPressing = useRef(false); const [isUnlocking, setIsUnlocking] = useState(false); const [hasTriggeredUnlock, setHasTriggeredUnlock] = useState(false); const trackEvent = useContext(MetaMetricsContext); /** * Prevent animation events from propogating up * * @param e - Native animation event - React.AnimationEvent */ const preventPropogation = (e) => { e.stopPropagation(); }; /** * Event for mouse click down */ const onMouseDown = () => { isLongPressing.current = true; trackEvent({ category: MetaMetricsEventCategory.Keys, event: MetaMetricsEventName.SrpHoldToRevealClickStarted, properties: { key_type: MetaMetricsEventKeyType.Srp, }, }); }; /** * Event for mouse click up */ const onMouseUp = () => { isLongPressing.current = false; }; /** * 1. Progress cirle completed. Begin next animation phase (Shrink halo and show unlocked padlock) */ const onProgressComplete = () => { isLongPressing.current && setIsUnlocking(true); }; /** * 2. Trigger onLongPressed callback. Begin next animation phase (Shrink unlocked padlock and fade in original content) * * @param e - Native animation event - React.AnimationEvent */ const triggerOnLongPressed = useCallback( (e) => { trackEvent({ category: MetaMetricsEventCategory.Keys, event: MetaMetricsEventName.SrpHoldToRevealCompleted, properties: { key_type: MetaMetricsEventKeyType.Srp, }, }); trackEvent({ category: MetaMetricsEventCategory.Keys, event: MetaMetricsEventName.SrpRevealViewed, properties: { key_type: MetaMetricsEventKeyType.Srp, }, }); onLongPressed(); setHasTriggeredUnlock(true); preventPropogation(e); }, [onLongPressed, trackEvent], ); /** * 3. Reset animation states */ const resetAnimationStates = () => { setIsUnlocking(false); setHasTriggeredUnlock(false); }; const renderPreCompleteContent = useCallback(() => { return ( {t('padlock')} ); }, [isUnlocking, hasTriggeredUnlock, t]); const renderPostCompleteContent = useCallback(() => { return isUnlocking ? (
{t('padlock')}
) : null; }, [isUnlocking, hasTriggeredUnlock, triggerOnLongPressed, t]); return ( ); } HoldToRevealButton.propTypes = { /** * Text to be displayed on the button */ buttonText: PropTypes.string.isRequired, /** * Function to be called after the animation is finished */ onLongPressed: PropTypes.func.isRequired, };