more consistent estimated time text (#884)

This commit is contained in:
kyzooghost
2025-04-22 17:51:08 +10:00
committed by GitHub
parent d1e20dfb53
commit 04db5c7204
5 changed files with 49 additions and 32 deletions

View File

@@ -2,27 +2,22 @@ import { useState } from "react";
import EstimatedTimeModal from "../../modal/estimated-time";
import ClockIcon from "@/assets/icons/clock.svg";
import styles from "./estimated-time.module.scss";
import { useChainStore } from "@/stores";
import { ChainLayer } from "@/types";
import { useChainStore, useFormStore } from "@/stores";
import { getEstimatedTimeText } from "@/utils";
export default function EstimatedTime() {
const fromChain = useChainStore.useFromChain();
const token = useFormStore((state) => state.token);
const [showEstimatedTimeModal, setShowEstimatedTimeModal] = useState<boolean>(false);
const estimatedTime = fromChain.layer === ChainLayer.L1 ? "~ 20 mins" : "~ 8-32 hours";
const estimatedTimeType = fromChain.layer === ChainLayer.L1 ? "deposit" : "withdraw";
const estimatedTimeText = `~${getEstimatedTimeText(fromChain, token, { withSpaceAroundHyphen: false, isAbbreviatedTimeUnit: true })}`;
return (
<>
<button type="button" className={styles.time} onClick={() => setShowEstimatedTimeModal(true)}>
<ClockIcon />
<span>{estimatedTime}</span>
<span>{estimatedTimeText}</span>
</button>
<EstimatedTimeModal
type={estimatedTimeType}
isModalOpen={showEstimatedTimeModal}
onCloseModal={() => setShowEstimatedTimeModal(false)}
/>
<EstimatedTimeModal isModalOpen={showEstimatedTimeModal} onCloseModal={() => setShowEstimatedTimeModal(false)} />
</>
);
}

View File

@@ -1,22 +1,29 @@
import Modal from "@/components/modal";
import styles from "./estimated-time.module.scss";
import Button from "@/components/ui/button";
import { useChainStore, useFormStore } from "@/stores";
import { getEstimatedTimeText } from "@/utils";
import { ChainLayer } from "@/types";
type Props = {
type: "deposit" | "withdraw";
isModalOpen: boolean;
onCloseModal: () => void;
};
export default function EstimatedTime({ type, isModalOpen, onCloseModal }: Props) {
const estimatedTime = type === "deposit" ? "20 minutes" : "8 to 32 hours";
const estimatedTimeType = type === "deposit" ? "deposits" : "withdrawals";
export default function EstimatedTimeModal({ isModalOpen, onCloseModal }: Props) {
const fromChain = useChainStore.useFromChain();
const token = useFormStore((state) => state.token);
const estimatedTimeText = getEstimatedTimeText(fromChain, token, {
withSpaceAroundHyphen: true,
isAbbreviatedTimeUnit: false,
});
const estimatedTimeType = fromChain.layer === ChainLayer.L1 ? "deposit" : "withdraw";
return (
<Modal title="Estimated time" isOpen={isModalOpen} onClose={onCloseModal}>
<div className={styles["modal-inner"]}>
<p className={styles["text"]}>
Linea has an approximate {estimatedTime} delay on {estimatedTimeType} as a security measure.
Linea has an approximate {estimatedTimeText} delay on {estimatedTimeType} as a security measure.
</p>
<Button fullWidth onClick={onCloseModal}>
OK

View File

@@ -4,23 +4,13 @@ import styles from "./item.module.scss";
import CheckIcon from "@/assets/icons/check.svg";
import ClockIcon from "@/assets/icons/clock.svg";
import BridgeTwoLogo from "@/components/bridge/bridge-two-logo";
import { getChainLogoPath, formatHex, formatTimestamp, isCctp } from "@/utils";
import { BridgeTransaction, Chain, ChainLayer, Token, TransactionStatus } from "@/types";
import { getChainLogoPath, formatHex, formatTimestamp, getEstimatedTimeText } from "@/utils";
import { BridgeTransaction, TransactionStatus } from "@/types";
type Props = BridgeTransaction & {
onClick: (code: string) => void;
};
const getEstimatedTime = (fromChain: Chain, token: Token) => {
if (isCctp(token)) {
return "22 secs - 19 mins";
}
if (fromChain.layer === ChainLayer.L1) {
return "20 mins";
}
return "8 - 32 hours";
};
export default function Transaction({
bridgingTx,
status,
@@ -32,7 +22,10 @@ export default function Transaction({
onClick,
}: Props) {
const formatedTxHash = formatHex(bridgingTx);
const estimatedTime = getEstimatedTime(fromChain, token);
const estimatedTimeText = getEstimatedTimeText(fromChain, token, {
withSpaceAroundHyphen: true,
isAbbreviatedTimeUnit: true,
});
const renderStatus = () => {
switch (status) {
@@ -54,7 +47,7 @@ export default function Transaction({
return (
<>
<ClockIcon />
<span>{estimatedTime}</span>
<span>{estimatedTimeText}</span>
</>
);

View File

@@ -3,7 +3,7 @@ export { generateChain, generateChains, getChainLogoPath, getChainNetworkLayer }
export { estimateEthGasFee, estimateERC20GasFee } from "./fees";
export { formatAddress, formatBalance, formatHex, formatTimestamp, safeGetAddress } from "./format";
export { fetchTransactionsHistory } from "./history";
export { computeMessageHash, computeMessageStorageSlot, isCctpV2BridgeMessage, isNativeBridgeMessage } from "./message";
export * from "./message";
export { isEth, isCctp } from "./tokens";
export {
isEmptyObject,

View File

@@ -1,6 +1,7 @@
import { keccak256, encodeAbiParameters, Address } from "viem";
import { CctpV2BridgeMessage, NativeBridgeMessage } from "@/types";
import { CctpV2BridgeMessage, Chain, ChainLayer, NativeBridgeMessage, Token } from "@/types";
import { INBOX_L1L2_MESSAGE_STATUS_MAPPING_SLOT } from "@/constants";
import { isCctp } from "./tokens";
export function computeMessageHash(
from: Address,
@@ -55,3 +56,24 @@ export function isCctpV2BridgeMessage(msg: NativeBridgeMessage | CctpV2BridgeMes
typeof (msg as CctpV2BridgeMessage).attestation === "string"
);
}
export type GetEstimatedTimeTextOptions = {
withSpaceAroundHyphen: boolean;
isAbbreviatedTimeUnit?: boolean;
};
export const getEstimatedTimeText = (fromChain: Chain, token: Token, opts: GetEstimatedTimeTextOptions) => {
const { withSpaceAroundHyphen, isAbbreviatedTimeUnit } = opts;
const spaceChar = withSpaceAroundHyphen ? " " : "";
const hourUnit = isAbbreviatedTimeUnit ? "hrs" : "hour";
const minuteUnit = isAbbreviatedTimeUnit ? "mins" : "minute";
const secondUnit = isAbbreviatedTimeUnit ? "secs" : "second";
if (isCctp(token)) {
return `22 ${secondUnit}${spaceChar}-${spaceChar}19 ${minuteUnit}`;
}
if (fromChain.layer === ChainLayer.L1) {
return `20 ${minuteUnit}`;
}
return `8${spaceChar}-${spaceChar}32 ${hourUnit}`;
};