From 92819639d040a9e99f1b5771da994bbab723ecb9 Mon Sep 17 00:00:00 2001 From: Uncle Fatso Date: Tue, 16 Dec 2025 17:35:46 +0300 Subject: [PATCH] apply another corrections from @neptune and @ghost_7 Signed-off-by: Uncle Fatso --- package.json | 2 +- src/containers/Bridge/Bridge.jsx | 13 +- src/containers/Bridge/BridgeCard.jsx | 19 ++- src/containers/Bridge/BridgeHeader.jsx | 18 +-- src/containers/Bridge/BridgeModal.jsx | 181 ++++++++++++++--------- src/containers/Bridge/ValidatorTable.jsx | 89 ++++++++++- src/helpers/index.js | 8 +- 7 files changed, 225 insertions(+), 105 deletions(-) diff --git a/package.json b/package.json index 813a000..5337a8a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ghost-dao-interface", "private": true, - "version": "0.4.1", + "version": "0.4.2", "type": "module", "scripts": { "dev": "vite", diff --git a/src/containers/Bridge/Bridge.jsx b/src/containers/Bridge/Bridge.jsx index d5c138a..d159b5f 100644 --- a/src/containers/Bridge/Bridge.jsx +++ b/src/containers/Bridge/Bridge.jsx @@ -171,9 +171,7 @@ const Bridge = ({ chainId, address, config, connect }) => { const applaused = transactionApplaused?.finalized ?? false; const clappedAmount = transactionApplaused?.clapped_amount ?? 0n; const clappedPercentage = clappedAmount * 100n / (totalStakedAmount ?? 1n); - const step = finalization > 0 - ? 0 - : applaused ? 2 : 1; + const clapsPercentage = (numberOfClaps ?? 0) * 100 / (authorities?.length ?? 1); return { ...watchTransaction, @@ -182,14 +180,15 @@ const Bridge = ({ chainId, address, config, connect }) => { numberOfClaps, clappedAmount, clappedPercentage, - step, + clapsPercentage, } }, [ transactionApplaused, finalityDelay, watchTransaction, blockNumber, - totalStakedAmount + totalStakedAmount, + authorities ]); const filteredStoredTransactions = useMemo(() => { @@ -287,7 +286,7 @@ const Bridge = ({ chainId, address, config, connect }) => { const newStoredTransactions = [transaction, ...storedTransactions]; setStoredTransactions(newStoredTransactions); localStorage.setItem(STORAGE_PREFIX, JSON.stringify(newStoredTransactions)); - setActiveTxIndex(newStoredTransactions.length - 1) + setActiveTxIndex(0) } return ( @@ -322,7 +321,7 @@ const Bridge = ({ chainId, address, config, connect }) => { diff --git a/src/containers/Bridge/BridgeCard.jsx b/src/containers/Bridge/BridgeCard.jsx index 1f3b2b9..458b154 100644 --- a/src/containers/Bridge/BridgeCard.jsx +++ b/src/containers/Bridge/BridgeCard.jsx @@ -30,6 +30,7 @@ import { useBalance } from "../../hooks/tokens"; import CheckIcon from '@mui/icons-material/Check'; import HourglassBottomIcon from '@mui/icons-material/HourglassBottom'; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import { DecimalBigNumber } from "../../helpers/DecimalBigNumber"; import { formatNumber, formatCurrency, timeConverter } from "../../helpers"; @@ -165,10 +166,14 @@ export const BridgeCardAction = ({ UpperSwapCard={ setReceiver(event.currentTarget.value)} + value={convertedReceiver ? sliceString(receiver, 15, -10) : receiver} + onChange={event => setReceiver(convertedReceiver ? "" : event.currentTarget.value)} inputProps={{ "data-testid": "fromInput" }} placeholder="GHOST address (sf prefixed)" + endString={convertedReceiver + ? + : undefined + } type="text" maxWidth="100%" />} @@ -190,18 +195,18 @@ export const BridgeCardAction = ({ gap="10px" justifyContent="space-between" > - + {gatekeeperAddressEmpty && ( - - + + - There is no connected gatekeeper on {chainName} network. Propose gatekeeper on this network to make authorities listen to it. + There is no connected gatekeeper on {chainName} network yet. )} {!gatekeeperAddressEmpty && ( - + {!isVerySmallScreen && Gatekeeper:} @@ -97,7 +97,7 @@ export const BridgeHeader = ({ tooltip="Maximum estimated time for finalizing bridge transactions based on the latest update." /> - + Bridge Stability {bridgeStability ? `${formatNumber(bridgeStability, 0)}% ${progressBarPostfix}` - : "Unknown" + : "N/A" } - 0% - 50%: Bridge Stability ❌ Do NOT Bridge - 50% - 70%: Bridge Stability ⚠️ Critical Risk - 70% - 80%: Bridge Stability ⚠️ High Risk - 80% - 90%: Bridge Stability ✅ Moderate Risk - 90% - 100%: Bridge Stability ✅ Safe + + 0% - 50%: ❌ Do NOT Bridge + 50% - 70%: ⚠️ Critical Risk + 70% - 80%: ⚠️ High Risk + 80% - 90%: ✅ Moderate Risk + 90% - 100%: ✅ Safe } /> diff --git a/src/containers/Bridge/BridgeModal.jsx b/src/containers/Bridge/BridgeModal.jsx index b7a0254..60b449e 100644 --- a/src/containers/Bridge/BridgeModal.jsx +++ b/src/containers/Bridge/BridgeModal.jsx @@ -8,6 +8,7 @@ import ThumbDownAltIcon from '@mui/icons-material/ThumbDownAlt'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import CheckIcon from '@mui/icons-material/Check'; import AssuredWorkloadIcon from '@mui/icons-material/AssuredWorkload'; +import AccountBalanceIcon from '@mui/icons-material/AccountBalance'; import HourglassBottomIcon from '@mui/icons-material/HourglassBottom'; import ArrowRightIcon from '@mui/icons-material/ArrowRight'; @@ -88,11 +89,57 @@ export const BridgeModal = ({ > + {currentRecord?.finalization > 0 && ( + <> + 0 && "scale(1.2)", + color: currentRecord?.finalization === 0 && theme.colors.primary[300] + }} + width="120px" + display="flex" + flexDirection="column" + justifyContent="start" + alignItems="center" + > + 0 && 'rotateHourGlass 2s ease-in-out infinite', + '@keyframes rotateHourGlass': { + '0%': { transform: 'rotate(0deg)' }, + '15%': { transform: 'rotate(0deg)' }, + '85%': { transform: 'rotate(180deg)' }, + '100%': { transform: 'rotate(180deg)' }, + }, + }} + viewBox="0 0 25 25" + component={HourglassBottomIcon} + /> + Finalization + + {(currentRecord?.finalization ?? 0).toString()} blocks left + + + + 0 && "0.2" + }} + component={ArrowRightIcon} + /> + + )} + 0 && theme.colors.primary[300] + transition: "all 0.3s ease", + opacity: currentRecord?.finalization > 0 && "0.2", + transform: currentRecord?.finalization === 0 && currentRecord?.clappedPercentage < 50n && "scale(1.2)", + color: currentRecord?.clappedPercentage > 50n && theme.colors.primary[300] }} width="120px" display="flex" @@ -100,38 +147,42 @@ export const BridgeModal = ({ justifyContent="start" alignItems="center" > - - Finalization - - {(currentRecord?.finalization ?? 0).toString()} blocks left - + + {currentRecord?.clappedPercentage < 50n + ? + : + } + Capital Backed + + {(currentRecord?.clappedAmount ?? 0n) / 10n**18n} {ghstSymbol} ({currentRecord?.clappedPercentage ?? 0}%) + + 1 && theme.colors.primary[300] + opacity: currentRecord?.finalization > 0 && "0.2", + transform: currentRecord?.finalization === 0 && currentRecord?.clapsPercentage < 50 && "scale(1.2)", + color: currentRecord?.clapsPercentage > 50 && theme.colors.primary[300] }} width="120px" display="flex" @@ -140,14 +191,14 @@ export const BridgeModal = ({ alignItems="center" > - {currentRecord?.step <= 1 + {currentRecord?.clapsPercentage < 50 ? ( <> - + {currentRecord?.finalization === 0 && ( + <> + - - {currentRecord?.applaused - ? <> - - Applaused - Check Receiver - - : <> - - Capital Backed - - {(currentRecord?.clappedAmount ?? 0n) / 10n**18n} {ghstSymbol} ({currentRecord?.clappedPercentage ?? 0}%) - - - } - + + + Applaused + Check Receiver + + + )} diff --git a/src/containers/Bridge/ValidatorTable.jsx b/src/containers/Bridge/ValidatorTable.jsx index a90fb81..4542853 100644 --- a/src/containers/Bridge/ValidatorTable.jsx +++ b/src/containers/Bridge/ValidatorTable.jsx @@ -15,6 +15,8 @@ import { } from "@mui/material"; import { useTheme } from "@mui/material/styles"; +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; +import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; import WarningIcon from '@mui/icons-material/Warning'; import CancelIcon from '@mui/icons-material/Cancel'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; @@ -32,6 +34,7 @@ export const ValidatorTable = ({ providerDetail, }) => { const theme = useTheme(); + const [sortedBy, setsortedBy] = useState(undefined); const stabilityColor = useMemo(() => { const red = Math.round(255 * (1 - bridgeStability / 100)); @@ -39,6 +42,65 @@ export const ValidatorTable = ({ return `rgb(${red}, ${green}, 0)`; }, [bridgeStability]); + const sortedCommits = useMemo(() => { + return latestCommits?.sort((a, b) => { + let one = 0; + let two = 0; + switch (sortedBy) { + case -1: + one = Number(b.lastUpdated ?? 0n); + two = Number(a.lastUpdated ?? 0n); + break; + case 1: + one = Number(a.lastUpdated ?? 0n); + two = Number(b.lastUpdated ?? 0n); + break; + case -2: + one = Number(b.lastStoredBlock ?? 0n); + two = Number(a.lastStoredBlock ?? 0n); + break; + case 2: + one = Number(a.lastStoredBlock ?? 0n); + two = Number(b.lastStoredBlock ?? 0n); + break; + case -3: + one = Number(b.lastStoredBlock ?? 0n); + two = Number(a.lastStoredBlock ?? 0n); + break; + case 3: + one = Number(a.lastStoredBlock ?? 0n); + two = Number(b.lastStoredBlock ?? 0n); + break; + case -4: + one = b.disabled ? 1 : 0; + two = a.disabled ? 1 : 0; + break; + case 4: + one = a.disabled ? 1 : 0; + two = b.disabled ? 1 : 0; + break; + default: + break; + } + return one - two; + }) ?? []; + }, [latestCommits, sortedBy]); + + const changeSort = (prevValue, newValue) => { + if (prevValue === undefined) { + return newValue; + } + + const prevValueAbs = Math.abs(prevValue); + const newValueAbs = Math.abs(newValue); + + if (prevValueAbs === newValueAbs) { + return prevValue * -1; + } else { + return newValue; + } + } + return ( {!providerDetail && @@ -64,11 +126,11 @@ export const ValidatorTable = ({ - - - - - + setsortedBy(undefined)} value="Validator" background={theme.colors.paper.cardHover} borderTopLeftRadius="3px" /> + setsortedBy(prev => changeSort(prev, 1))} value="Last Acitve" background={theme.colors.paper.cardHover} tooltip="GHOST Validators must submit block commitments every 10 minutes to remain active." /> + setsortedBy(prev => changeSort(prev, 2))} value="Block Height" background={theme.colors.paper.cardHover} tooltip="The latest EVM block height reported by the Validator." /> + setsortedBy(prev => changeSort(prev, 3))} value="Block Delayed" background={theme.colors.paper.cardHover} tooltip="Block delays under 4 hours are safe. Block delays over 4 hours risk bridge transaction failure." /> + setsortedBy(prev => changeSort(prev, 4))} value="Status" background={theme.colors.paper.cardHover} borderTopRightRadius="3px" tooltip="Active and disabled validators fore the current GHOST Epoch." /> @@ -105,6 +167,9 @@ export const ValidatorTable = ({ } const BridgeHeaderTableCell = ({ + index=0, + sortedBy=undefined, + changeSort, align="center", borderTopRightRadius="0px", borderTopLeftRadius="0px", @@ -127,11 +192,21 @@ const BridgeHeaderTableCell = ({ background, fontSize, padding, + cursor: "pointer", }} > - + {value} - {tooltip && } + {tooltip + ? Math.abs(sortedBy) !== index + ? + : 0 ? KeyboardArrowDownIcon : KeyboardArrowUpIcon} + /> + : <> + } ) diff --git a/src/helpers/index.js b/src/helpers/index.js index a6d4410..d5531e7 100644 --- a/src/helpers/index.js +++ b/src/helpers/index.js @@ -42,9 +42,13 @@ export const sortBondsByDiscount = (bonds) => { return Array.from(bonds).filter((bond) => !bond.isSoldOut).sort((a, b) => (a.discount.gt(b.discount) ? -1 : 1)); }; -export const timeConverter = (time) => { +export const timeConverter = (time, max = 7200, maxText = "long ago") => { const seconds = Number(time); const mins = Math.floor(seconds / 60); const secs = seconds % 60; - return `${mins}m ${secs < 10 ? '0' : ''}${secs}s`; + if (mins > max) { + return maxText; + } else { + return `${mins}m ${secs < 10 ? '0' : ''}${secs}s`; + } }