diff --git a/src/api/democracy.ts b/src/api/democracy.ts index af3ef045c..bfe51b8d3 100644 --- a/src/api/democracy.ts +++ b/src/api/democracy.ts @@ -64,6 +64,30 @@ export const useReferendums = (type?: "ongoing" | "finished") => { ) } +export const useDeprecatedReferendumInfo = (referendumIndex: string) => { + return useQuery( + QUERY_KEYS.deprecatedReferendumInfo(referendumIndex), + async () => { + const res = await fetch( + `https://hydration.subsquare.io/api/democracy/referendums/${referendumIndex}.json`, + ) + if (!res.ok) return null + + const json: Referendum = await res.json() + + if ( + json === null || + json.referendumIndex === null || + json.motionIndex === null || + json.title === null + ) + return null + + return json + }, + ) +} + export const useReferendumInfo = (referendumIndex: string) => { return useQuery( QUERY_KEYS.referendumInfo(referendumIndex), diff --git a/src/components/ReferendumCard/ReferendaDeprecated.tsx b/src/components/ReferendumCard/ReferendaDeprecated.tsx new file mode 100644 index 000000000..c5c8def91 --- /dev/null +++ b/src/components/ReferendumCard/ReferendaDeprecated.tsx @@ -0,0 +1,156 @@ +import { PalletDemocracyReferendumInfo } from "@polkadot/types/lookup" +import { useDeprecatedReferendumInfo } from "api/democracy" +import IconArrow from "assets/icons/IconArrow.svg?react" +import GovernanceIcon from "assets/icons/GovernanceIcon.svg?react" +import { Separator } from "components/Separator/Separator" +import { Spacer } from "components/Spacer/Spacer" +import { Text } from "components/Typography/Text/Text" +import { useMemo } from "react" +import { useTranslation } from "react-i18next" +import { BN_0, BN_10, PARACHAIN_BLOCK_TIME } from "utils/constants" +import { SContainer, SHeader, SVotedBage } from "./ReferendumCard.styled" +import { Icon } from "components/Icon/Icon" +import BN from "bignumber.js" +import { useBestNumber } from "api/chain" +import { customFormatDuration } from "utils/formatting" +import { ReferendumCardProgress } from "./ReferendumCardProgress" +import { ReferendumCardSkeleton } from "./ReferendumCardSkeleton" + +const REFERENDUM_LINK = import.meta.env.VITE_REFERENDUM_LINK as string + +type Props = { + id: string + referendum: PalletDemocracyReferendumInfo + type: "toast" | "staking" + voted: boolean +} + +export const ReferendaDeprecated = ({ id, referendum, type, voted }: Props) => { + const { t } = useTranslation() + + const info = useDeprecatedReferendumInfo(id) + const bestNumber = useBestNumber() + + const votes = useMemo(() => { + if (!referendum.isOngoing) + return { ayes: BN_0, nays: BN_0, percAyes: BN_0, percNays: BN_0 } + + const ayes = referendum.asOngoing.tally.ayes + .toBigNumber() + .div(BN_10.pow(12)) + const nays = referendum.asOngoing.tally.nays + .toBigNumber() + .div(BN_10.pow(12)) + + const votesSum = ayes.plus(nays) + + let percAyes = BN_0 + let percNays = BN_0 + + if (!votesSum.isZero()) { + percAyes = ayes.div(votesSum).times(100) + percNays = nays.div(votesSum).times(100) + } + + return { ayes, nays, percAyes, percNays } + }, [referendum]) + + const diff = BN(info?.data?.onchainData.meta.end ?? 0) + .minus(bestNumber.data?.parachainBlockNumber.toBigNumber() ?? 0) + .times(PARACHAIN_BLOCK_TIME) + .toNumber() + const endDate = customFormatDuration({ end: diff * 1000 }) + + return info.isLoading || !info.data ? ( + + ) : ( + + +
+ + #{info.data.referendumIndex} + + + {"//"} + + + {endDate && + t(`duration.${endDate.isPositive ? "left" : "ago"}`, { + duration: endDate.duration, + })} + +
+ +
+ {voted && ( + + {t("toast.sidebar.referendums.voted")} + } + /> + + )} + } /> +
+
+ + + + + {info.data.title} + + + + + + + + +
+ + {t("toast.sidebar.referendums.aye")} + + + {t("toast.sidebar.referendums.nay")} + +
+ + + +
+ + {t("toast.sidebar.referendums.value", { + value: votes.ayes, + percent: votes.percAyes, + })} + + + {t("toast.sidebar.referendums.value", { + value: votes.nays, + percent: votes.percNays, + })} + +
+
+ ) +} diff --git a/src/components/ReferendumCard/ReferendumCard.styled.ts b/src/components/ReferendumCard/ReferendumCard.styled.ts index 0d6e20288..ced51150c 100644 --- a/src/components/ReferendumCard/ReferendumCard.styled.ts +++ b/src/components/ReferendumCard/ReferendumCard.styled.ts @@ -2,6 +2,56 @@ import { css } from "@emotion/react" import styled from "@emotion/styled" import { theme } from "theme" +export const SContainer = styled.a<{ type: "staking" | "toast" }>` + padding: 16px; + ${({ type }) => + type === "toast" + ? css` + border-radius: ${theme.borderRadius.default}px; + ` + : css` + border-radius: ${theme.borderRadius.medium}px; + + position: relative; + + :before { + content: ""; + position: absolute; + inset: 0; + + border-radius: ${theme.borderRadius.medium}px; + padding: 1px; // a width of the border + + background: linear-gradient( + 180deg, + rgba(152, 176, 214, 0.27) 0%, + rgba(163, 177, 199, 0.15) 66.67%, + rgba(158, 167, 180, 0.2) 100% + ); + -webkit-mask: + linear-gradient(#fff 0 0) content-box, + linear-gradient(#fff 0 0); + -webkit-mask-composite: xor; + mask-composite: exclude; + pointer-events: none; + } + `} + + background: ${theme.colors.darkBlue700}; + + transition: background ${theme.transitions.default}; + + cursor: pointer; + + &:hover { + background: ${theme.colors.darkBlue401}; + } + + &:active { + background: ${theme.colors.darkBlue400}; + } +` + export const SHeader = styled.div` display: flex; align-items: center; diff --git a/src/components/ReferendumCard/ReferendumCardProgress.tsx b/src/components/ReferendumCard/ReferendumCardProgress.tsx new file mode 100644 index 000000000..037c94967 --- /dev/null +++ b/src/components/ReferendumCard/ReferendumCardProgress.tsx @@ -0,0 +1,54 @@ +import { LinearProgress } from "components/Progress" +import BN from "bignumber.js" +import { theme } from "theme" + +export type ReferendumCardProgressProps = { + percAyes: BN + percNays: BN +} + +export const ReferendumCardProgress: React.FC = ({ + percAyes, + percNays, +}) => { + const isNoVotes = percAyes.eq(0) && percNays.eq(0) + return ( +
+ {isNoVotes ? ( + + ) : ( + <> + + + + )} +
+ ) +} diff --git a/src/components/ReferendumCard/ReferendumCardSkeleton.tsx b/src/components/ReferendumCard/ReferendumCardSkeleton.tsx new file mode 100644 index 000000000..c370d27b7 --- /dev/null +++ b/src/components/ReferendumCard/ReferendumCardSkeleton.tsx @@ -0,0 +1,59 @@ +import Skeleton from "react-loading-skeleton" +import IconArrow from "assets/icons/IconArrow.svg?react" +import { Separator } from "components/Separator/Separator" +import { SContainer, SHeader } from "./ReferendumCard.styled" +import { Spacer } from "components/Spacer/Spacer" +import { Text } from "components/Typography/Text/Text" +import { useTranslation } from "react-i18next" +import { Icon } from "components/Icon/Icon" + +export const ReferendumCardSkeleton = ({ + type, +}: { + type: "toast" | "staking" +}) => { + const { t } = useTranslation() + + const isToastCard = type === "toast" + + return ( + + + + } /> + + + + + + + + +
span": { width: "100%" } }} + > + + +
+ + + +
+ + {t("toast.sidebar.referendums.aye")} + + + {t("toast.sidebar.referendums.nay")} + +
+ + + +
+ + +
+
+ ) +} diff --git a/src/components/Toast/sidebar/referendums/ToastSidebarReferendums.tsx b/src/components/Toast/sidebar/referendums/ToastSidebarReferendums.tsx index 369f4aae5..e5ffdad4d 100644 --- a/src/components/Toast/sidebar/referendums/ToastSidebarReferendums.tsx +++ b/src/components/Toast/sidebar/referendums/ToastSidebarReferendums.tsx @@ -2,17 +2,21 @@ import { TReferenda, useOpenGovReferendas, useReferendaTracks, + useReferendums, } from "api/democracy" import { OpenGovReferenda } from "components/ReferendumCard/Referenda" import { useHDXSupplyFromSubscan } from "api/staking" import { ToastSidebarGroup } from "components/Toast/sidebar/group/ToastSidebarGroup" import { useTranslation } from "react-i18next" +import { ReferendaDeprecated } from "components/ReferendumCard/ReferendaDeprecated" export const ToastSidebarReferendums = () => { const { t } = useTranslation() const openGovQuery = useOpenGovReferendas() const tracks = useReferendaTracks() const { data: hdxSupply } = useHDXSupplyFromSubscan() + const { data: referendums = [] } = useReferendums("ongoing") + const referendum = referendums.find((referendum) => referendum.id === "203") return ( { ) }) : null} + + {referendum && ( + + )} ) diff --git a/src/i18n/locales/en/translations.json b/src/i18n/locales/en/translations.json index 211c43e8d..773a3530b 100644 --- a/src/i18n/locales/en/translations.json +++ b/src/i18n/locales/en/translations.json @@ -730,7 +730,6 @@ "farms.claimCard.button.label": "Claim all", "farms.claimCard.claim.asset": "{{num}}{{denom}} {{symbol}}", "farms.claimCard.claim.usd": "Total of ≈ <0/>", - "farms.claimCard.claim.diffRewards": "Locked rewards ≈ <0/>", "farms.claimCard.toast.onLoading": "<0>Claiming farm rewards for ", "farms.claimCard.toast.onSuccess": "<0>Farm rewards claimed for ", "farms.claimCard.toast.asset": "<1>{{num}}{{denom}} {{symbol}}.", diff --git a/src/sections/pools/farms/components/claimAllDropdown/ClaimAllContent.tsx b/src/sections/pools/farms/components/claimAllDropdown/ClaimAllContent.tsx index 726f82878..b2a99d700 100644 --- a/src/sections/pools/farms/components/claimAllDropdown/ClaimAllContent.tsx +++ b/src/sections/pools/farms/components/claimAllDropdown/ClaimAllContent.tsx @@ -36,7 +36,7 @@ export const ClaimAllContent = forwardRef( ) : [] - const { claimableTotal, claimableAssetValues, diffRewards } = + const { claimableTotal, claimableAssetValues } = useSummarizeClaimableValues(claimableValues) const claimableAssets = Object.keys(claimableAssetValues ?? {}).map( @@ -101,25 +101,12 @@ export const ClaimAllContent = forwardRef( ))} - + - - - - - - { const claimableAssets = [] @@ -145,19 +146,6 @@ export const ClaimRewardsCard = (props: { - - - - - -
)} [id, "referendumInfo"], + deprecatedReferendumInfo: (id: string) => [id, "deprecatedReferendumInfo"], stats: ( type: ChartType, timeframe?: StatsTimeframe,