Skip to content

Commit

Permalink
Feature/adopt optimization (#235)
Browse files Browse the repository at this point in the history
* feat: 🎸 optimize interaction with adopt and upgrade sdk

  • Loading branch information
leosley-m committed Jun 6, 2024
1 parent b7b4d6e commit 22c3c5d
Show file tree
Hide file tree
Showing 17 changed files with 471 additions and 109 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
"@portkey-v1/did-ui-react": "^1.5.4-alpha.22",
"@portkey/contracts": "2.2.0",
"@portkey/detect-provider": "^2.1.0",
"@portkey/did-ui-react": "2.6.5",
"@portkey/did-ui-react": "2.6.6",
"@portkey/onboarding": "^2.2.0",
"@portkey/provider-types": "^2.2.0",
"@portkey/provider-types": "^2.2.1",
"@portkey/request": "2.2.0",
"@portkey/services": "2.2.0",
"@portkey/types": "2.2.0",
Expand All @@ -36,7 +36,7 @@
"@types/lodash-es": "^4.17.9",
"aelf-design": "^0.1.73-alpha.0",
"aelf-sdk": "^3.2.40",
"aelf-web-login": "2.0.1-beta.12",
"aelf-web-login": "2.0.1-beta.15",
"ahooks": "^3.7.10",
"antd": "^5.x",
"antd-mobile": "^5.35.0",
Expand Down
1 change: 1 addition & 0 deletions src/assets/lottie/light.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/assets/lottie/scrap.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/components/AdoptNextModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Balance from 'components/Balance';
import CommonModal from 'components/CommonModal';
import TransactionFee from 'components/TransactionFee';
import NoticeBar from 'components/NoticeBar';
import SGRTokenInfo from 'components/SGRTokenInfo';
import SGRTokenInfo, { ISGRTokenInfoProps } from 'components/SGRTokenInfo';
import TraitsList from 'components/TraitsList';
import { ReactComponent as QuestionSVG } from 'assets/img/icons/question.svg';
import AIImageSelect from 'components/AIImageSelect';
Expand Down Expand Up @@ -37,7 +37,7 @@ function DescriptionItem({ title, tip, children }: IDescriptionItemProps) {
interface IAdoptNextModal {
isAcross?: boolean;
data: IAdoptNextData;
onConfirm?: (image: string) => void;
onConfirm?: (image: string, SGRToken?: ISGRTokenInfoProps) => void;
onClose?: () => void;
}

Expand All @@ -53,8 +53,8 @@ function AdoptNextModal({ isAcross, data, onConfirm, onClose }: IAdoptNextModal)

const onClick = useCallback(() => {
setLoading(true);
onConfirm?.(images[selectImage]);
}, [images, onConfirm, selectImage]);
onConfirm?.(images[selectImage], SGRToken);
}, [SGRToken, images, onConfirm, selectImage]);
const onCancel = useCallback(() => {
if (onClose) return onClose();
modal.hide();
Expand Down
29 changes: 29 additions & 0 deletions src/components/CardResultModal/index.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.button-wrapper {
:global(.aelfd-btn) {
> span {
@apply overflow-hidden w-full text-ellipsis;

word-break: break-all;
}
}
}

.card-result-modal-wrap {
@apply !z-[1004];
.card-result-modal {
@apply !overflow-visible;
:global {
.aelfd-modal-content {
@apply !overflow-visible;

.aelfd-modal-header {
@apply !rounded-tl-lg !rounded-tr-lg;
}

.aelfd-modal-body {
@apply !pt-0 lg:!pt-[16px];
}
}
}
}
}
258 changes: 258 additions & 0 deletions src/components/CardResultModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
import React, { ReactNode, useCallback, useMemo, useState } from 'react';
import CommonModal from 'components/CommonModal';
import NiceModal, { useModal } from '@ebay/nice-modal-react';
import { useResponsive } from 'hooks/useResponsive';
import { Button } from 'aelf-design';
import { ReactComponent as SuccessIcon } from 'assets/img/icons/success.svg';
import { ReactComponent as FailedIcon } from 'assets/img/icons/failed.svg';
import { ReactComponent as ExportOutlined } from 'assets/img/icons/exportOutlined.svg';
import { getAdoptErrorMessage } from 'hooks/Adopt/getErrorMessage';
import { singleMessage } from '@portkey/did-ui-react';
import { isMobile } from 'react-device-detect';
import styles from './index.module.css';
import clsx from 'clsx';
import SkeletonImage from 'components/SkeletonImage';
import { formatTokenPrice } from 'utils/format';
import { getDescriptionCom } from 'components/ResultModal';
import Lottie from 'lottie-react';
import light from 'assets/lottie/light.json';
import scrap from 'assets/lottie/scrap.json';
import { useCmsInfo } from 'redux/hooks';
import { useJumpToPage } from 'hooks/useJumpToPage';

export enum Status {
ERROR = 'error',
WARNING = 'warning',
SUCCESS = 'success',
INFO = 'info',
}

function CardList({ title, value }: { title: string; value: string }) {
return (
<div className="flex flex-row justify-between items-center mt-2 w-full overflow-hidden">
<div className="w-[110px] text-sm text-neutralSecondary">{title}</div>
<div className="flex-1 text-right text-sm text-neutralTitle font-medium truncate">{value}</div>
</div>
);
}

interface IProps {
modalTitle?: string;
title?: string;
description?: string | ReactNode | string[];
status?: Status;
amount?: number | string;
hideButton?: boolean;
buttonInfo?: {
btnText?: string;
openLoading?: boolean;
onConfirm?: () => void | Promise<any>;
};
image?: string;
info?: {
name?: string;
symbol?: string;
generation?: string | number;
rank?: string | number;
points?: string;
levelInfo?: ILevelInfo;
};
showScrap?: boolean;
showLight?: boolean;
link?: {
text?: string;
href?: string;
};
onCancel?: <T, R>(params?: T) => R | void;
}

function CardResultModal({
modalTitle,
description,
status = Status.INFO,
amount,
buttonInfo,
hideButton = false,
image,
info,
link,
showScrap = false,
showLight = false,
onCancel,
}: IProps) {
const modal = useModal();
const { isLG } = useResponsive();
const cmsInfo = useCmsInfo();
const { jumpToPage } = useJumpToPage();

const [loading, setLoading] = useState<boolean>(false);
const [animationEnds, setAnimationEnds] = useState<boolean>(false);
const [scrapComplete, setScrapComplete] = useState<boolean>(false);

const onClick = useCallback(async () => {
if (buttonInfo?.onConfirm) {
if (buttonInfo.openLoading) {
setLoading(true);
}
try {
await buttonInfo.onConfirm();
setLoading(false);
} catch (error) {
console.log(error, 'error==');
const _error = getAdoptErrorMessage(error);
console.log(_error, 'errorMessage');

singleMessage.error(_error);
} finally {
setLoading(false);
}

return;
}
modal.hide();
return;
}, [buttonInfo, modal]);

const Icon = useMemo(() => {
return {
[Status.ERROR]: <FailedIcon className="w-[32px] h-[32px]" />,
[Status.SUCCESS]: <SuccessIcon className="w-[32px] h-[32px]" />,
[Status.WARNING]: '',
[Status.INFO]: '',
}[status];
}, [status]);

const aProps = useMemo(() => (isMobile ? {} : { target: '_blank', rel: 'noreferrer' }), []);

const modalFooter = useMemo(() => {
return (
<div className="flex flex-1 lg:flex-none flex-col justify-center items-center">
{!hideButton ? (
<div className={clsx('w-full flex flex-col items-center', styles['button-wrapper'])}>
<Button
type="primary"
size="ultra"
loading={loading}
className={`${isLG ? 'w-full' : '!w-[256px]'}`}
onClick={onClick}>
{buttonInfo?.btnText || 'View'}
</Button>
</div>
) : null}

{link && (
<div className="flex items-center mt-[16px]">
<a href={link.href} {...aProps} className="flex items-center">
<span className="text-brandDefault font-medium text-base mr-[8px]">
{link.text || 'View on aelf Explorer'}
</span>
<span>
<ExportOutlined width={20} height={20} />
</span>
</a>
</div>
)}
</div>
);
}, [aProps, buttonInfo?.btnText, hideButton, isLG, link, loading, onClick]);

return (
<>
<CommonModal
title={
modalTitle ? (
<p className="flex flex-nowrap">
<span className="mr-[8px] lg:mr-[12px] lg:mb-0">{Icon}</span>
<span className="text-neutralTitle font-semibold text-xl lg:text-2xl">{modalTitle}</span>
</p>
) : null
}
wrapClassName={styles['card-result-modal-wrap']}
className={clsx('relative', styles['card-result-modal'])}
disableMobileLayout={true}
open={modal.visible}
onOk={modal.hide}
onCancel={onCancel || modal.hide}
afterClose={modal.remove}
afterOpenChange={(open) => {
setAnimationEnds(open);
}}
footer={modalFooter}>
<div className="w-full flex flex-col lg:flex-row items-center lg:items-start">
{image || amount ? (
<div className="flex flex-col items-center w-max">
{image ? (
<SkeletonImage
generation={info?.generation}
level={info?.levelInfo?.level}
rarity={info?.levelInfo?.describe}
img={image}
rank={info?.rank}
className="w-[128px] h-[128px] lg:w-[180px] lg:h-[180px]"
/>
) : null}
</div>
) : null}
{info ? (
<div className="flex flex-col w-full overflow-hidden flex-none lg:flex-1 mt-[16px] lg:mt-[0px] border border-solid border-neutralDivider rounded-lg lg:ml-[24px] p-[16px]">
{!isLG ? (
<div className="flex flex-row justify-between items-center">
<div className="text-neutralTitle font-medium text-base">Info</div>
</div>
) : null}

{!!info.name && <CardList title="Name" value={info.name} />}
{!!amount && <CardList title="Adopt amount" value={formatTokenPrice(amount)} />}
{!!info.points && <CardList title="Points" value={info.points} />}
{!!info.points && cmsInfo?.ecoEarn && (
<div className="w-full flex items-center justify-end">
<span
className="w-max flex items-center cursor-pointer"
onClick={() =>
jumpToPage({
link: cmsInfo.ecoEarn,
linkType: 'externalLink',
})
}>
<span className="text-xs font-medium text-brandDefault">
View the SGR reward from point staking
</span>
<ExportOutlined className="scale-[0.6]" />
</span>
</div>
)}
</div>
) : null}
</div>
{description ? (
<div className="mt-[16px] lg:mt-[24px] text-center text-sm font-medium text-neutralSecondary">
{getDescriptionCom(description)}
</div>
) : null}
</CommonModal>
{animationEnds && showLight && modal.visible ? (
<div className="fixed w-screen h-screen z-[1001] left-0 top-0 overflow-hidden">
<div className="relative w-[938px] h-[938px] lg:w-[1280px] lg:h-[1280px] top-[50%] left-[50%] -translate-y-1/2 -translate-x-1/2">
<Lottie animationData={light} autoPlay={true} loop={true} className="w-full" />
</div>
</div>
) : null}

{animationEnds && showScrap && !scrapComplete && modal.visible ? (
<div className="fixed w-screen h-screen z-[1005] left-0 top-0 overflow-hidden">
<div className="relative w-[160%] lg:w-[938px] lg:h-[938px] aspect-square lg:aspect-auto top-[50%] left-[50%] -translate-y-1/2 -translate-x-1/2">
<Lottie
animationData={scrap}
onComplete={() => setScrapComplete(true)}
autoPlay={true}
loop={false}
className="w-full"
/>
</div>
</div>
) : null}
</>
);
}

export default NiceModal.create(CardResultModal);
24 changes: 12 additions & 12 deletions src/components/ResultModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ import { isMobile } from 'react-device-detect';
import styles from './index.module.css';
import clsx from 'clsx';

export const getDescriptionCom = (description: string | ReactNode | string[]) => {
if (typeof description === 'string') {
return <p>{description}</p>;
} else if (description instanceof Array) {
return description.map((item, index) => {
return <p key={index}>{item}</p>;
});
} else {
return description;
}
};

export enum Status {
ERROR = 'error',
WARNING = 'warning',
Expand Down Expand Up @@ -125,18 +137,6 @@ function ResultModal({
);
}, [aProps, buttonInfo?.btnText, hideButton, isLG, link, loading, onClick]);

const getDescriptionCom = (description: string | ReactNode | string[]) => {
if (typeof description === 'string') {
return <p>{description}</p>;
} else if (description instanceof Array) {
return description.map((item, index) => {
return <p key={index}>{item}</p>;
});
} else {
return description;
}
};

return (
<CommonModal
title={
Expand Down
4 changes: 4 additions & 0 deletions src/constants/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ export const AELF_TOKEN_INFO: TBaseTokenInfo = {
export const DEFAULT_TOKEN_INFO = AELF_TOKEN_INFO;
export const DEFAULT_TOKEN_SYMBOL = DEFAULT_TOKEN_INFO.symbol;
export const DEFAULT_TOKEN_DECIMALS = DEFAULT_TOKEN_INFO.decimals;

export const POINTS_COEFFICIENT = {
'XPSGR-5': 1314,
};
2 changes: 1 addition & 1 deletion src/contract/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ interface IApproveParams {
spender: string;
symbol: string;
amount: number;
showBatchApproveToken: boolean;
batchApproveNFT: boolean;
}
1 change: 1 addition & 0 deletions src/hooks/Adopt/AdoptStep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface IAdoptNextInfo {
symbol: string;
tokenName: string;
outputAmount: string | number;
inputAmount: string | number;
adoptId: string;
}

Expand Down
Loading

0 comments on commit 22c3c5d

Please sign in to comment.