Skip to content

Commit

Permalink
feat: Add ConfettiAnimation component for visual effects
Browse files Browse the repository at this point in the history
  • Loading branch information
mohandast52 committed May 23, 2024
1 parent 7f8f4aa commit a307a5d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 21 deletions.
25 changes: 18 additions & 7 deletions frontend/components/Main/MainRewards.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Button, Col, Flex, Modal, Row, Skeleton, Tag, Typography } from 'antd';
import Image from 'next/image';
import { useEffect, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';
import { useTimeout } from 'usehooks-ts';

Expand All @@ -10,7 +10,7 @@ import { useBalance } from '@/hooks';
import { useElectronApi } from '@/hooks/useElectronApi';
import { useReward } from '@/hooks/useReward';

import { Confetti } from '../../common-util/Confetti';
import { ConfettiAnimation } from '../common/ConfettiAnimation';

const { Text, Title } = Typography;

Expand Down Expand Up @@ -84,6 +84,7 @@ const NotifyRewards = () => {

const [canShowNotification, setCanShowNotification] = useState(false);

// TODO: remove just to test the notification
useTimeout(() => setCanShowNotification(true), 1000);

useEffect(() => {
Expand All @@ -92,38 +93,48 @@ const NotifyRewards = () => {

if (!isEligibleForRewards) return;
if (hasAlreadyNotified) return;
if (!availableRewardsForEpochEther) return;

setCanShowNotification(!!availableRewardsForEpochEther);
setCanShowNotification(true);
}, [isEligibleForRewards, availableRewardsForEpochEther, showNotification]);

// hook to show app notification
useEffect(() => {
if (!canShowNotification) return;

showNotification?.(
'Your agent earned its first staking rewards!',
`Congratulations! Your agent just got the first reward for you! Your current balance: ${availableRewardsForEpochEther} OLAS`,
);
}, [canShowNotification, availableRewardsForEpochEther, showNotification]);

const closeNotificationModal = useCallback(() => {
setCanShowNotification(false);
// TODO: add setter for hasAlreadyNotified
}, [canShowNotification, availableRewardsForEpochEther, showNotification]);
}, []);

if (!canShowNotification) return null;

return (
<Modal
open={canShowNotification}
width={400}
onCancel={() => setCanShowNotification(false)}
onCancel={closeNotificationModal}
footer={[
<Button key="back" type="primary" block size="large" className="mt-8">
<Flex align="center" justify="center" gap={2}>
Share on
<Image src="/twitter.svg" width={24} height={24} alt="OLAS logo" />
<Image
src="/twitter.svg"
width={24}
height={24}
alt="Share on twitter"
/>
</Flex>
</Button>,
]}
>
<Confetti />
<ConfettiAnimation />

<Flex align="center" justify="center">
<Image
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useRef } from 'react';
import { useCallback, useRef } from 'react';
import ReactCanvasConfetti from 'react-canvas-confetti';
import { useInterval } from 'usehooks-ts';

Expand All @@ -11,30 +11,32 @@ const canvasStyles = {
left: 0,
};

export const Confetti = () => {
export const ConfettiAnimation = () => {
const animationInstance = useRef(null);

const makeShot = (particleRatio, opts) => {
animationInstance &&
animationInstance.current({
...opts,
origin: { y: 0.45 },
particleCount: Math.floor(200 * particleRatio),
});
};
const makeShot = useCallback((particleRatio, opts) => {
if (!animationInstance.current) return;

const fire = () => {
animationInstance.current({
...opts,
origin: { y: 0.45 },
particleCount: Math.floor(200 * particleRatio),
});
}, []);

const fire = useCallback(() => {
makeShot(0.25, { spread: 26, startVelocity: 55 });
makeShot(0.2, { spread: 60 });
makeShot(0.35, { spread: 80, decay: 0.91, scalar: 0.8 });
makeShot(0.1, { spread: 100, startVelocity: 25, decay: 0.92, scalar: 1.2 });
makeShot(0.1, { spread: 100, startVelocity: 45 });
};
}, [makeShot]);

const getInstance = (instance) => {
const getInstance = useCallback((instance) => {
animationInstance.current = instance;
};
}, []);

// Fire confetti every 2.5 seconds
useInterval(() => fire(), 2500);

return <ReactCanvasConfetti refConfetti={getInstance} style={canvasStyles} />;
Expand Down

0 comments on commit a307a5d

Please sign in to comment.