mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
fix: reduce premature skipping of donation animation (#54817)
Co-authored-by: Naomi <accounts+github@nhcarrigan.com>
This commit is contained in:
@@ -100,7 +100,6 @@
|
||||
"update-card": "Update your card",
|
||||
"donate-now": "Donate Now",
|
||||
"confirm-amount": "Confirm amount",
|
||||
"skip-advertisement": "Skip Advertisement",
|
||||
"play-scene": "Press Play"
|
||||
},
|
||||
"landing": {
|
||||
@@ -645,7 +644,8 @@
|
||||
"help-millions-learn": "Help millions of people learn",
|
||||
"reach-goals-faster": "Reach your goals faster",
|
||||
"remove-distractions": "Remove distractions",
|
||||
"animation-description": "This is a 20 second animated advertisement to encourage campers to become supporters of freeCodeCamp. The animation starts with a teddy bear who becomes a supporter. As a result, distracting pop-ups disappear and the bear gets to complete all of its goals. Then, it graduates and becomes an education super hero helping people around the world."
|
||||
"animation-description": "This is a 20 second animated advertisement to encourage campers to become supporters of freeCodeCamp. The animation starts with a teddy bear who becomes a supporter. As a result, distracting pop-ups disappear and the bear gets to complete all of its goals. Then, it graduates and becomes an education super hero helping people around the world.",
|
||||
"animation-countdown": "This animation will stop after {{secondsRemaining}} seconds."
|
||||
},
|
||||
"report": {
|
||||
"sign-in": "You need to be signed in to report a user",
|
||||
|
||||
@@ -124,16 +124,20 @@ const Benefits = ({ setShowForm }: { setShowForm: (arg: boolean) => void }) => {
|
||||
};
|
||||
|
||||
const AnimationContainer = ({
|
||||
setIsAnimationVisible
|
||||
secondsRemaining
|
||||
}: {
|
||||
setIsAnimationVisible: (arg: boolean) => void;
|
||||
secondsRemaining: number;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
<p style={{ opacity: 0, position: 'absolute' }}>
|
||||
{t('donate.animation-description')}{' '}
|
||||
</p>
|
||||
<div style={{ opacity: 0, position: 'absolute' }}>
|
||||
<p>{t('donate.animation-description')}</p>
|
||||
<span aria-live='polite'>
|
||||
{t('donate.animation-countdown', { secondsRemaining })}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className='donation-animation-container' aria-hidden='true'>
|
||||
<div className='donation-animation-bullet-points'>
|
||||
<p className='donation-animation-bullet-1'>
|
||||
@@ -150,19 +154,13 @@ const AnimationContainer = ({
|
||||
</p>
|
||||
</div>
|
||||
<img
|
||||
key={Date.now()}
|
||||
alt=''
|
||||
src={donationAnimation}
|
||||
id={'donation-animation'}
|
||||
data-playwright-test-label='not-found-image'
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
style={{ opacity: 0, position: 'absolute' }}
|
||||
className={'sr-only'}
|
||||
onClick={() => setIsAnimationVisible(false)}
|
||||
>
|
||||
{t('buttons.skip-advertisement')}
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -226,24 +224,33 @@ function DonationModalBody({
|
||||
const [showHeaderAndFooter, setShowHeaderAndFooter] = useState(true);
|
||||
const [isAnimationVisible, setIsAnimationVisible] = useState(true);
|
||||
const [showForm, setShowForm] = useState(false);
|
||||
const [secondsRemaining, setSecondsRemaining] = useState(20);
|
||||
|
||||
const handleProcessing = () => {
|
||||
setDonationAttempted(true);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
setIsAnimationVisible(false);
|
||||
}, 20000); // 20000 milliseconds = 20 seconds
|
||||
const interval = setInterval(() => {
|
||||
setSecondsRemaining(prevSeconds => {
|
||||
if (prevSeconds > 0) {
|
||||
return prevSeconds - 1;
|
||||
} else {
|
||||
setIsAnimationVisible(false);
|
||||
clearInterval(interval);
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
// Clear the timer if the component unmounts
|
||||
return () => clearTimeout(timer);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Modal.Body borderless alignment='start'>
|
||||
<div aria-live='polite' className='donation-modal'>
|
||||
{isAnimationVisible ? (
|
||||
<AnimationContainer setIsAnimationVisible={setIsAnimationVisible} />
|
||||
<AnimationContainer secondsRemaining={secondsRemaining} />
|
||||
) : (
|
||||
<BecomeASupporterConfirmation
|
||||
recentlyClaimedBlock={recentlyClaimedBlock}
|
||||
|
||||
@@ -43,10 +43,15 @@ const updateCardErrorMessage = i18next.t('donate.error-3');
|
||||
|
||||
function* showDonateModalSaga() {
|
||||
let shouldRequestDonation = yield select(shouldRequestDonationSelector);
|
||||
if (shouldRequestDonation) {
|
||||
const MODAL_SHOWN_KEY = 'modalShownTimestamp';
|
||||
const modalShownTimestamp = sessionStorage.getItem(MODAL_SHOWN_KEY);
|
||||
const isModalRecentlyShown = Date.now() - modalShownTimestamp < 20000;
|
||||
|
||||
if (shouldRequestDonation || isModalRecentlyShown) {
|
||||
yield delay(200);
|
||||
const recentlyClaimedBlock = yield select(recentlyClaimedBlockSelector);
|
||||
yield put(openDonationModal());
|
||||
sessionStorage.setItem(MODAL_SHOWN_KEY, Date.now());
|
||||
yield take(appTypes.closeDonationModal);
|
||||
if (recentlyClaimedBlock) {
|
||||
yield put(preventBlockDonationRequests());
|
||||
|
||||
Reference in New Issue
Block a user