diff --git a/src/typescript/frontend/src/components/charts/PrivateChart.tsx b/src/typescript/frontend/src/components/charts/PrivateChart.tsx index 461491f00..bd6d3a1ae 100644 --- a/src/typescript/frontend/src/components/charts/PrivateChart.tsx +++ b/src/typescript/frontend/src/components/charts/PrivateChart.tsx @@ -368,8 +368,8 @@ export const Chart = (props: ChartContainerProps) => { }); return ( -
-
+
+
{showErrorMessage ? ( <> diff --git a/src/typescript/frontend/src/components/pages/emojicoin/ClientEmojicoinPage.tsx b/src/typescript/frontend/src/components/pages/emojicoin/ClientEmojicoinPage.tsx index 3c35b5ca3..1d0a856b5 100644 --- a/src/typescript/frontend/src/components/pages/emojicoin/ClientEmojicoinPage.tsx +++ b/src/typescript/frontend/src/components/pages/emojicoin/ClientEmojicoinPage.tsx @@ -7,7 +7,6 @@ import DesktopGrid from "./components/desktop-grid"; import MobileGrid from "./components/mobile-grid"; import { type EmojicoinProps } from "./types"; import { useEventStore } from "context/event-store-context"; -import TextCarousel from "components/text-carousel/TextCarousel"; import MainInfo from "./components/main-info/MainInfo"; import { useReliableSubscribe } from "@hooks/use-reliable-subscribe"; import { type BrokerEvent } from "@/broker/types"; @@ -35,7 +34,6 @@ const ClientEmojicoinPage = (props: EmojicoinProps) => { return ( - {isTablet || isMobile ? : } diff --git a/src/typescript/frontend/src/components/pages/emojicoin/components/desktop-grid/index.tsx b/src/typescript/frontend/src/components/pages/emojicoin/components/desktop-grid/index.tsx index 175a3276a..b55ab0259 100644 --- a/src/typescript/frontend/src/components/pages/emojicoin/components/desktop-grid/index.tsx +++ b/src/typescript/frontend/src/components/pages/emojicoin/components/desktop-grid/index.tsx @@ -1,13 +1,8 @@ import React, { Suspense } from "react"; -import { Text } from "components"; - -import { translationFunction } from "context/language-context"; - import { StyledContentWrapper, StyledContentColumn, - StyledContentHeader, StyledBlockWrapper, StyledContentInner, StyledBlock, @@ -16,22 +11,16 @@ import { import ChatBox from "../chat/ChatBox"; import TradeHistory from "../trade-history"; import { type GridProps } from "../../types"; -import { LiquidityButton } from "../trade-emojicoin/LiquidityButton"; import ChartContainer from "components/charts/ChartContainer"; import SwapComponent from "../trade-emojicoin/SwapComponent"; import Loading from "components/loading"; const DesktopGrid = (props: GridProps) => { - const { t } = translationFunction(); - return ( - + }> { - - { - - - {t("Trade History")} - - - - - - {t("Chat")} - - - diff --git a/src/typescript/frontend/src/components/pages/emojicoin/components/desktop-grid/styled.tsx b/src/typescript/frontend/src/components/pages/emojicoin/components/desktop-grid/styled.tsx index 792b55e9f..9d04cc400 100644 --- a/src/typescript/frontend/src/components/pages/emojicoin/components/desktop-grid/styled.tsx +++ b/src/typescript/frontend/src/components/pages/emojicoin/components/desktop-grid/styled.tsx @@ -20,6 +20,19 @@ export const StyledContentColumn = styled(Flex)` border-left: 1px solid ${({ theme }) => theme.colors.darkGray}; border-right: 1px solid ${({ theme }) => theme.colors.darkGray}; + position: relative; + + &:after, + &:before { + content: ""; + display: block; + position: absolute; + width: 200vw; + background-color: ${({ theme }) => theme.colors.darkGray}; + height: 1px; + transform: translateX(-50%); + z-index: 10; + } `; export const StyledContentHeader = styled.div` diff --git a/src/typescript/frontend/src/components/pages/emojicoin/components/main-info/BondingProgress.tsx b/src/typescript/frontend/src/components/pages/emojicoin/components/main-info/BondingProgress.tsx new file mode 100644 index 000000000..6a065d836 --- /dev/null +++ b/src/typescript/frontend/src/components/pages/emojicoin/components/main-info/BondingProgress.tsx @@ -0,0 +1,87 @@ +import React, { useEffect, useState } from "react"; + +import { translationFunction } from "context/language-context"; +import { type MainInfoProps } from "../../types"; +import { useEventStore } from "context/event-store-context"; +import { useLabelScrambler } from "components/pages/home/components/table-card/animation-variants/event-variants"; +import { motion } from "framer-motion"; +import { getBondingCurveProgress } from "utils/bonding-curve"; +import Button from "components/button"; +import Link from "next/link"; +import { ROUTES } from "router/routes"; +import { useThemeContext } from "context"; + +const statsTextClasses = "uppercase ellipses font-forma text-[24px]"; + +const BondingProgress = ({ data }: MainInfoProps) => { + const { t } = translationFunction(); + const { theme } = useThemeContext(); + + const marketEmojis = data.symbolEmojis; + const stateEvents = useEventStore((s) => s.getMarket(marketEmojis)?.stateEvents ?? []); + + const [bondingProgress, setBondingProgress] = useState( + getBondingCurveProgress(data.state.state.clammVirtualReserves.quote) + ); + + useEffect(() => { + if (stateEvents.length === 0) return; + const event = stateEvents.at(0); + if (event) { + setBondingProgress(getBondingCurveProgress(event.state.clammVirtualReserves.quote)); + } + }, [stateEvents]); + + const { ref: bondingCurveRef } = useLabelScrambler(`${bondingProgress.toFixed(2)}%`, "%"); + + return ( +
+
+
+ {t("Bonding progress:")} +
+
+
+ {bondingProgress.toFixed(2)}% +
+
+
+ {bondingProgress >= 100 ? ( + e.emoji).join("") }, + }} + > + + + ) : ( +
+ +
+ )} +
+ ); +}; + +export default BondingProgress; diff --git a/src/typescript/frontend/src/components/pages/emojicoin/components/main-info/MainInfo.tsx b/src/typescript/frontend/src/components/pages/emojicoin/components/main-info/MainInfo.tsx index f39064d48..249820e20 100644 --- a/src/typescript/frontend/src/components/pages/emojicoin/components/main-info/MainInfo.tsx +++ b/src/typescript/frontend/src/components/pages/emojicoin/components/main-info/MainInfo.tsx @@ -4,21 +4,19 @@ import { translationFunction } from "context/language-context"; import { toCoinDecimalString } from "lib/utils/decimals"; import AptosIconBlack from "components/svg/icons/AptosBlack"; import { type MainInfoProps } from "../../types"; -import { emojisToName } from "lib/utils/emojis-to-name-or-symbol"; import { useEventStore } from "context/event-store-context"; import { useLabelScrambler } from "components/pages/home/components/table-card/animation-variants/event-variants"; import { isMarketStateModel } from "@sdk/indexer-v2/types"; +import BondingProgress from "./BondingProgress"; +import { useThemeContext } from "context"; +import { useMatchBreakpoints } from "@hooks/index"; import { Emoji } from "utils/emoji"; -const innerWrapper = `flex flex-col md:flex-row justify-around w-full max-w-[1362px] px-[30px] lg:px-[44px] py-[17px] -md:py-[37px] xl:py-[68px]`; -const headerWrapper = - "flex flex-row md:flex-col md:justify-between gap-[12px] md:gap-[4px] w-full md:w-[58%] xl:w-[65%] mb-[8px]"; -const statsWrapper = "flex flex-col w-full md:w-[42%] xl:w-[35%] mt-[-8px]"; -const statsTextClasses = "display-6 md:display-4 uppercase ellipses font-forma"; +const statsTextClasses = "uppercase ellipses font-forma text-[24px]"; const MainInfo = ({ data }: MainInfoProps) => { const { t } = translationFunction(); + const { theme } = useThemeContext(); const marketEmojis = data.symbolEmojis; const stateEvents = useEventStore((s) => s.getMarket(marketEmojis)?.stateEvents ?? []); @@ -41,27 +39,48 @@ const MainInfo = ({ data }: MainInfoProps) => { } }, [stateEvents]); - const { ref: marketCapRef } = useLabelScrambler(marketCap); - const { ref: dailyVolumeRef } = useLabelScrambler(dailyVolume); - const { ref: allTimeVolumeRef } = useLabelScrambler(allTimeVolume); + const { ref: marketCapRef } = useLabelScrambler(toCoinDecimalString(marketCap, 2)); + const { ref: dailyVolumeRef } = useLabelScrambler(toCoinDecimalString(dailyVolume, 2)); + const { ref: allTimeVolumeRef } = useLabelScrambler(toCoinDecimalString(allTimeVolume, 2)); - return ( -
-
-
-
- {emojisToName(data.emojis)} -
+ const { isMobile } = useMatchBreakpoints(); - -
+ return ( +
+
+ -
-
-
{t("Mkt. Cap:")}
+
+
+
{t("Market Cap:")}
{toCoinDecimalString(marketCap, 2)}
@@ -71,7 +90,7 @@ const MainInfo = ({ data }: MainInfoProps) => {
-
+
{t("24 hour vol:")}
@@ -82,7 +101,7 @@ const MainInfo = ({ data }: MainInfoProps) => {
-
+
{t("All-time vol:")}
@@ -92,6 +111,10 @@ const MainInfo = ({ data }: MainInfoProps) => {
+ +
+ +
diff --git a/src/typescript/frontend/src/components/pages/emojicoin/components/trade-emojicoin/SwapComponent.tsx b/src/typescript/frontend/src/components/pages/emojicoin/components/trade-emojicoin/SwapComponent.tsx index a05aa5ee9..70588e749 100644 --- a/src/typescript/frontend/src/components/pages/emojicoin/components/trade-emojicoin/SwapComponent.tsx +++ b/src/typescript/frontend/src/components/pages/emojicoin/components/trade-emojicoin/SwapComponent.tsx @@ -10,7 +10,7 @@ import { toActualCoinDecimals, toDisplayCoinDecimals } from "lib/utils/decimals" import { useScramble } from "use-scramble"; import { useSimulateSwap } from "lib/hooks/queries/use-simulate-swap"; import { useEventStore } from "context/event-store-context"; -import { useMatchBreakpoints, useTooltip } from "@hooks/index"; +import { useTooltip } from "@hooks/index"; import { useSearchParams } from "next/navigation"; import { translationFunction } from "context/language-context"; import { useAptos } from "context/wallet-context/AptosContextProvider"; @@ -69,7 +69,6 @@ export default function SwapComponent({ presetInputAmount !== null && presetInputAmount !== "" && !Number.isNaN(Number(presetInputAmount)); - const { isDesktop } = useMatchBreakpoints(); const [inputAmount, setInputAmount] = useState( toActualCoinDecimals({ num: presetInputAmountIsValid ? presetInputAmount! : "1" }) ); @@ -177,7 +176,7 @@ export default function SwapComponent({ const { theme } = useThemeContext(); - const { targetRef, tooltip } = useTooltip( + const { targetRef, tooltip: gearTooltip } = useTooltip( setMaxSlippage(getMaxSlippageSettings().maxSlippage)} />, @@ -185,141 +184,141 @@ export default function SwapComponent({ placement: "bottom", customStyles: getTooltipStyles(theme), trigger: "click", + tooltipOffset: [100, 10], } ); return ( - <> - - -
- {t("Trade Emojicoin")} -
- - {isSell ? ( - <> - { - setInputAmount(emojicoinBalance / 2n); - }} - /> - { - setInputAmount(emojicoinBalance); - }} - /> - - ) : ( - <> - { - setInputAmount(availableAptBalance / 4n); - }} - /> - { - setInputAmount(availableAptBalance / 2n); - }} - /> - { - setInputAmount(availableAptBalance); - }} - /> - - )} - -
- - - - -
- {isSell ? t("You sell") : t("You pay")} - {balanceLabel} -
- setInputAmount(v)} - onSubmit={() => (submit ? submit() : {})} - decimals={8} + + +
+ +
+ {gearTooltip} + + {isSell ? ( + <> + { + setInputAmount(emojicoinBalance / 2n); + }} + /> + { + setInputAmount(emojicoinBalance); + }} /> -
- {isSell ? : } -
+ + ) : ( + <> + { + setInputAmount(availableAptBalance / 4n); + }} + /> + { + setInputAmount(availableAptBalance / 2n); + }} + /> + { + setInputAmount(availableAptBalance); + }} + /> + + )} + + + + + + +
+ {isSell ? t("You sell") : t("You pay")} + {balanceLabel} +
+ setInputAmount(v)} + onSubmit={() => (submit ? submit() : {})} + decimals={8} + /> +
+ {isSell ? : } +
- { - setInputAmount(outputAmount); - // This is done as to not display an old value if the swap simulation fails. - setOutputAmount(0n); - setPrevious(0n); - setIsSell((v) => !v); - }} - /> + { + setInputAmount(outputAmount); + // This is done as to not display an old value if the swap simulation fails. + setOutputAmount(0n); + setPrevious(0n); + setIsSell((v) => !v); + }} + /> - - -
{t("You receive")}
-
-
setIsSell((v) => !v)} - className={inputAndOutputStyles + " mt-[8px] ml-[1px] cursor-pointer"} - style={{ opacity: isLoading ? 0.6 : 1 }} - > - {/* Scrambled swap result output below. */} -
-
+ + +
{t("You receive")}
+
+
setIsSell((v) => !v)} + className={inputAndOutputStyles + " mt-[8px] ml-[1px] cursor-pointer"} + style={{ opacity: isLoading ? 0.6 : 1 }} + > + {/* Scrambled swap result output below. */} +
- - {isSell ? : } - - -
-
- -
- {tooltip} -
- - {gasCost === null ? "~" : ""} - {toDisplayCoinDecimals({ - num: gasCost !== null ? gasCost.toString() : SWAP_GAS_COST.toString(), - decimals: 4, - })}{" "} - APT - {" "} - -
+
+ + {isSell ? : } + + +
+
+
+ + {gasCost === null ? "~" : ""} + {toDisplayCoinDecimals({ + num: gasCost !== null ? gasCost.toString() : SWAP_GAS_COST.toString(), + decimals: 4, + })}{" "} + APT + {" "} +
+
- - - - - + + + + ); } diff --git a/src/typescript/frontend/src/components/pages/home/components/main-card/MainCard.tsx b/src/typescript/frontend/src/components/pages/home/components/main-card/MainCard.tsx index 53b436073..f595f77a2 100644 --- a/src/typescript/frontend/src/components/pages/home/components/main-card/MainCard.tsx +++ b/src/typescript/frontend/src/components/pages/home/components/main-card/MainCard.tsx @@ -51,9 +51,9 @@ const MainCard = (props: MainCardProps) => { }, []); /* eslint-enable react-hooks/exhaustive-deps */ - const { ref: marketCapRef } = useLabelScrambler(marketCap); - const { ref: dailyVolumeRef } = useLabelScrambler(dailyVolume); - const { ref: allTimeVolumeRef } = useLabelScrambler(allTimeVolume); + const { ref: marketCapRef } = useLabelScrambler(toCoinDecimalString(marketCap, 2)); + const { ref: dailyVolumeRef } = useLabelScrambler(toCoinDecimalString(dailyVolume, 2)); + const { ref: allTimeVolumeRef } = useLabelScrambler(toCoinDecimalString(allTimeVolume, 2)); return ( diff --git a/src/typescript/frontend/src/components/pages/home/components/table-card/TableCard.tsx b/src/typescript/frontend/src/components/pages/home/components/table-card/TableCard.tsx index 133cece0a..9110d977d 100644 --- a/src/typescript/frontend/src/components/pages/home/components/table-card/TableCard.tsx +++ b/src/typescript/frontend/src/components/pages/home/components/table-card/TableCard.tsx @@ -103,8 +103,14 @@ const TableCard = ({ /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [animations, runAnimationSequence]); - const { ref: marketCapRef } = useLabelScrambler(marketCap, " APT"); - const { ref: dailyVolumeRef } = useLabelScrambler(dailyVolume, " APT"); + const { ref: marketCapRef } = useLabelScrambler( + toCoinDecimalString(marketCap.toString(), 2), + " APT" + ); + const { ref: dailyVolumeRef } = useLabelScrambler( + toCoinDecimalString(dailyVolume.toString(), 2), + " APT" + ); const { curr, prev, variant, displayIndex, layoutDelay } = useMemo(() => { const { curr, prev } = calculateGridData({ diff --git a/src/typescript/frontend/src/components/pages/home/components/table-card/animation-variants/event-variants.ts b/src/typescript/frontend/src/components/pages/home/components/table-card/animation-variants/event-variants.ts index 25cf953c2..e0871b6ec 100644 --- a/src/typescript/frontend/src/components/pages/home/components/table-card/animation-variants/event-variants.ts +++ b/src/typescript/frontend/src/components/pages/home/components/table-card/animation-variants/event-variants.ts @@ -1,4 +1,3 @@ -import { type AnyNumberString } from "@sdk-types"; import { Trigger } from "@sdk/const"; import { type ChatEventModel, @@ -12,8 +11,6 @@ import { type MarketRegistrationEventModel, type SwapEventModel, } from "@sdk/indexer-v2/types"; -import type Big from "big.js"; -import { toCoinDecimalString } from "lib/utils/decimals"; import { ECONIA_BLUE, GREEN, PINK, WHITE } from "theme/colors"; import { useScramble } from "use-scramble"; @@ -130,10 +127,10 @@ export const scrambleConfig = { overdrive: false, overflow: true, speed: 0.6, - playOnMount: false, + playOnMount: true, }; -export const useLabelScrambler = (value: AnyNumberString | Big, suffix: string = "") => { +export const useLabelScrambler = (value: string, suffix: string = "") => { // Ignore all characters in the suffix, as long as they are not numbers. const ignore = ["."]; const numberSet = new Set("0123456789"); @@ -145,7 +142,7 @@ export const useLabelScrambler = (value: AnyNumberString | Big, suffix: string = } const scrambler = useScramble({ - text: toCoinDecimalString(value.toString(), 2) + suffix, + text: value, ...scrambleConfig, ignore, }); diff --git a/src/typescript/frontend/src/components/selects/trade-options/index.tsx b/src/typescript/frontend/src/components/selects/trade-options/index.tsx index 71aaf2d97..436d6d497 100644 --- a/src/typescript/frontend/src/components/selects/trade-options/index.tsx +++ b/src/typescript/frontend/src/components/selects/trade-options/index.tsx @@ -65,7 +65,7 @@ export const TradeOptions = ({ onMaxSlippageUpdate }: TradeOptionsProps) => {
{ decimals={2} className="w-[4rem] bg-transparent text-right outline-none" /> - % + %
diff --git a/src/typescript/frontend/src/utils/bonding-curve.ts b/src/typescript/frontend/src/utils/bonding-curve.ts index 7396e0101..4f2389cbc 100644 --- a/src/typescript/frontend/src/utils/bonding-curve.ts +++ b/src/typescript/frontend/src/utils/bonding-curve.ts @@ -50,6 +50,7 @@ export const isInBondingCurve = ( * @returns the percentage of the bonding curve progress */ export const getBondingCurveProgress = (clammVirtualReservesQuote: number | bigint) => { + if (BigInt(clammVirtualReservesQuote) === 0n) return 100; return Big(clammVirtualReservesQuote.toString()) .sub(QUOTE_VIRTUAL_FLOOR.toString()) .div(QUOTE_REAL_CEILING.toString())