diff --git a/src/components/ChainIDBadge.re b/src/components/ChainIDBadge.re index c2283500..5c224fe4 100644 --- a/src/components/ChainIDBadge.re +++ b/src/components/ChainIDBadge.re @@ -5,11 +5,11 @@ module Styles = { style([ display(`flex), borderRadius(`px(8)), - border(`px(1), `solid, isDarkMode ? theme.neutral_100 : theme.neutral_600), + // border(`px(1), `solid, isDarkMode ? theme.neutral_100 : theme.neutral_600), backgroundColor(theme.neutral_000), - padding2(~v=`px(8), ~h=`px(10)), + padding2(~v=`px(8), ~h=`px(16)), minWidth(`px(153)), - justifyContent(`spaceBetween), + // justifyContent(`spaceBetween), alignItems(`center), position(`relative), cursor(`pointer), @@ -43,8 +43,40 @@ module Styles = { padding2(~v=`px(5), ~h=`px(10)), hover([backgroundColor(theme.neutral_100)]), ]); + let buttonContainer = style([Media.mobile([width(`percent(100.))])]); + let baseBtn = + style([ + textAlign(`center), + Media.mobile([flexGrow(0.), flexShrink(0.), flexBasis(`percent(50.))]), + ]); + + let leftBtn = (state, theme: Theme.t, isDarkMode) => { + style([ + borderTopRightRadius(`zero), + borderBottomRightRadius(`zero), + backgroundColor(state ? theme.neutral_900 : theme.neutral_000), + color(state ? theme.neutral_100 : theme.neutral_900), + hover([ + backgroundColor(state ? theme.neutral_900 : theme.neutral_100), + color(state ? theme.neutral_100 : theme.neutral_900), + ]), + ]); + }; + let rightBtn = (state, theme: Theme.t, isDarkMode) => { + style([ + borderTopLeftRadius(`zero), + borderBottomLeftRadius(`zero), + color(state ? theme.neutral_900 : theme.neutral_100), + backgroundColor(state ? theme.neutral_000 : theme.neutral_900), + hover([ + backgroundColor(state ? theme.neutral_100 : theme.neutral_900), + color(state ? theme.neutral_900 : theme.neutral_100), + ]), + ]); + }; }; + type chainID = | WenchangTestnet | WenchangMainnet @@ -109,7 +141,7 @@ let getName = | Unknown => "unknown"; [@react.component] -let make = () => +let make = (~dropdown=false) => { let (show, setShow) = React.useState(_ => false); let trackingSub = TrackingSub.use(); @@ -118,7 +150,18 @@ let make = () => let%Sub tracking = trackingSub; let currentChainID = tracking.chainID->parseChainID; -
Belt.Array.map(chainID => chainID->getName); + + let isMainnet = (currentChainID->getName) == "laozi-mainnet" + let handleToggle = (value) => { + Js.log(value) + Js.log(currentChainID->getName) + if(!value && isMainnet){ + ReasonReactRouter.push(LaoziMainnet |> getLink) + } + }; + + {dropdown ?
{ setShow(oldVal => !oldVal); @@ -130,22 +173,43 @@ let make = () => nowrap=true weight=Text.Semibold /> - - {show - ? - : } +
+ {show + ? + : } +
{[|LaoziMainnet, LaoziTestnet|] ->Belt.Array.keep(chainID => chainID != currentChainID) ->Belt.Array.map(chainID => { let name = chainID->getName; - + ; }) ->React.array}
-
+
:
+ + + + + + +
} + |> Sub.resolve; } |> Sub.default( diff --git a/src/components/ChainInfoHighlights.re b/src/components/ChainInfoHighlights.re index 0aa8a70d..185f09e6 100644 --- a/src/components/ChainInfoHighlights.re +++ b/src/components/ChainInfoHighlights.re @@ -1,7 +1,7 @@ module Styles = { open Css; - let card = (theme: Theme.t) => + let card = style([ position(`relative), Media.smallMobile([margin2(~v=`zero, ~h=`px(-5))]), @@ -11,7 +11,7 @@ module Styles = { style([ position(`relative), zIndex(2), - minHeight(`px(177)), + minHeight(`px(152)), padding2(~v=`px(24), ~h=`px(32)), Media.mobile([padding2(~v=`px(10), ~h=`px(12)), minHeight(`px(146))]), ]); @@ -30,7 +30,37 @@ module Styles = { let bandToken = style([position(`absolute), width(`percent(60.)), top(`percent(-40.)), right(`zero)]); -}; + + let longCard = + style([ + width(`percent(100.)), + marginTop(`px(24)), + padding2(~v=`px(4), ~h=`px(24)), + ]); + + let innerLongCard = + style([ + minHeight(`px(106)), + padding2(~v=`px(24), ~h=`px(12)), + Media.mobile([padding2(~v=`px(10), ~h=`px(12)), minHeight(`px(50))]), + ]); + + let halfWidth = + style([ + width(`calc((`sub, `percent(50.), `px(17)))), + Media.mobile([width(`percent(100.))]), + ]); + + let mr2 = + style([ + marginRight(`px(16)), + ]); + + let pb = + style([ + Media.mobile([paddingBottom(`px(4))]), + ]); + }; module HighlightCard = { [@react.component] @@ -39,7 +69,7 @@ module HighlightCard = { let (ThemeContext.{theme,isDarkMode}, _) = React.useContext(ThemeContext.context); let isMobile = Media.isMobile(); -
+
{special && !isMobile ? Band Token : React.null}
{switch (valueAndExtraComponentSub) { | Data((valueComponent, extraComponent)) => - <> valueComponent extraComponent + <> valueComponent extraComponent | _ => <> @@ -63,116 +93,374 @@ module HighlightCard = { }; }; +let getPrevDay = _ => { + MomentRe.momentNow() + |> MomentRe.Moment.defaultUtc + |> MomentRe.Moment.subtract(~duration=MomentRe.duration(1., `days)) + |> MomentRe.Moment.format(Config.timestampUseFormat); +}; + +let getUnixTime = _ => { + MomentRe.momentNow() + |> MomentRe.Moment.defaultUtc + |> MomentRe.Moment.subtract(~duration=MomentRe.duration(1., `days)) + |> MomentRe.Moment.toUnix; +}; + [@react.component] let make = (~latestBlockSub: Sub.t(BlockSub.t)) => { + let isMobile = Media.isMobile(); + let currentTime = + React.useContext(TimeContext.context) |> MomentRe.Moment.format(Config.timestampUseFormat); + let (prevDayTime, setPrevDayTime) = React.useState(getPrevDay); + let (prevUnixTime, setPrevUnixTime) = React.useState(getUnixTime); + let infoSub = React.useContext(GlobalContext.context); - let (ThemeContext.{theme}, _) = React.useContext(ThemeContext.context); + let (ThemeContext.{theme, isDarkMode}, _) = React.useContext(ThemeContext.context); + let activeValidatorCountSub = ValidatorSub.countByActive(true); let bondedTokenCountSub = ValidatorSub.getTotalBondedAmount(); - - let validatorInfoSub = Sub.all2(activeValidatorCountSub, bondedTokenCountSub); + let latestTxsSub = TxSub.getList(~pageSize=1, ~page=1, ()); + let last24txsCountSub = TxQuery.countOffset(prevDayTime); + let latestRequestSub = RequestSub.getList(~pageSize=1, ~page=1, ()); + let last24RequestCountSub = RequestQuery.countOffset(prevUnixTime); + let latestBlock = BlockSub.getLatest(); + let avgBlockTimeSub = BlockSub.getAvgBlockTime(prevDayTime, currentTime); + let avgCommissionSub = ValidatorSub.avgCommission(~isActive=true, ()); + + let validatorInfoSub = Sub.all3(activeValidatorCountSub, bondedTokenCountSub, avgBlockTimeSub); let allSub = Sub.all3(latestBlockSub, infoSub, validatorInfoSub); - - - Format.fPretty(~digits=2)); - ; - }, - { - let bandPriceInBTC = financial.btcPrice; + React.useEffect0(() => { + let timeOutID = Js.Global.setInterval(() => { + setPrevDayTime(getPrevDay) + setPrevUnixTime(getUnixTime) + }, 600_000); + Some(() => {Js.Global.clearInterval(timeOutID)}); + }); + + <> + + + Format.fPretty(~digits=2)); +
+
+ +
+ 0. ? "+" : "") + ++ (financial.usd24HrChange |> Format.fPretty(~digits=2)) + ++ "%" + } + size=Text.Md + weight=Text.Regular + color=(financial.usd24HrChange > 0. ? theme.successColor : theme.failColor) + /> +
+ }, + { + let bandPriceInBTC = financial.btcPrice; +
+ Format.fPretty ++ " BTC"} /> +
; + }, + ) + |> Sub.resolve; + } + /> + + + Format.fCurrency)} + size=Text.Xxxl + color={theme.neutral_900} + weight=Text.Semibold + />; + }, + { + let marketcap = financial.btcMarketCap; + Format.fPretty) ++ " BTC"} />; + }, + ) + |> Sub.resolve; + } + /> + + + , + , + ) + |> Sub.resolve; + } + /> + + + Format.iPretty; + ; + }, + Format.fPretty(~digits=2)) ++ " secs"} + size=Text.Lg + weight=Text.Regular + />, + ) + |> Sub.resolve; + } + /> + +
+
+
+ +
- Format.fPretty ++ " BTC"} /> -
; - }, - ) - |> Sub.resolve; - } - /> - - - Format.fCurrency)} - size=Text.Xxxl - color={theme.neutral_900} - weight=Text.Semibold - />; - }, - { - let marketcap = financial.btcMarketCap; - Format.fPretty) ++ " BTC"} />; - }, - ) - |> Sub.resolve; - } - /> - - - , - , - ) - |> Sub.resolve; - } - /> - - - Format.iPretty ++ " Nodes"; - ; - }, - Coin.getBandAmountFromCoin |> Format.fPretty) - ++ " BAND Bonded" - } - />, - ) - |> Sub.resolve; - } - /> - -
; +
+ +
+
+ {switch (latestTxsSub) { + | Data((latestTx)) => +
+ Belt.Array.get(0) + ->Belt.Option.mapWithDefault(0, ({id}) => id ) + ->float_of_int + ->Format.fCurrency + } + size=Text.Xxl + weight=Text.Bold + height={Text.Px(20)} + color=theme.neutral_900 + /> +
+ | _ => + + }} + {switch (last24txsCountSub) { + | Data((last24Tx)) => +
+ float_of_int |> Format.fCurrency ) ++ " last 24 hr)"} + size=Text.Md + weight=Text.Regular + color=theme.neutral_900 + /> +
+ | _ => + + }} +
+
+ + +
+
+ +
+
+ {switch (latestRequestSub) { + | Data((latestRequest)) => +
+ Belt.Array.get(0) + ->Belt.Option.mapWithDefault(0, ({id}) => id |> ID.Request.toInt) + ->float_of_int + ->Format.fCurrency + } + size=Text.Xxl + weight=Text.Bold + height={Text.Px(20)} + color=theme.neutral_900 + /> +
+ | _ => + + }} + {switch (last24RequestCountSub) { + | Data((last24Request)) => +
+ float_of_int |> Format.fCurrency ) ++ " last 24 hr)"} + size=Text.Md + weight=Text.Regular + color=theme.neutral_900 + /> +
+ | _ => + + }} +
+
+ + +
+ {isMobile ? React.null : } +
+ + +
+ {switch (latestBlock) { + | Data({inflation}) => + <> +
+ +
+ Format.fPretty(~digits=2)) ++ "%"} + size=Text.Xxl + weight=Text.Bold + height={Text.Px(20)} + color=theme.neutral_900 + /> + + | _ => + <> + + + + }} +
+ + +
+ {switch (avgCommissionSub) { + | Data(avgCommission) => + <> +
+ +
+ Format.fPretty(~digits=2)) ++ "%"} + size=Text.Xxl + weight=Text.Bold + height={Text.Px(20)} + color=theme.neutral_900 + /> + + | _ => + <> + + + + }} +
+ + +
+ {switch (allSub) { + | Data((_, {financial}, (_, bondedTokenCount, _))) => + <> +
+ +
+
+
+ Coin.getBandAmountFromCoin) /. financial.circulatingSupply *. 100.) + |> Format.fPretty(~digits=2) + ) + ++ "%" + } + size=Text.Xxl + weight=Text.Bold + color=theme.neutral_900 + /> +
+ Coin.getBandAmountFromCoin |> Format.fCurrency) + ++ "/" ++ (financial.circulatingSupply |> Format.fCurrency) + ++ " BAND" + } + size=Text.Md + weight=Text.Regular + height={Text.Px(20)} + color=theme.neutral_900 + /> +
+ + | _ => + <> + + + + }} +
+ +
+
+
+ }; diff --git a/src/components/Footer.re b/src/components/Footer.re index 517c054d..fe0d7c13 100644 --- a/src/components/Footer.re +++ b/src/components/Footer.re @@ -28,7 +28,7 @@ let make = () => { let ({ThemeContext.theme}, _) = React.useContext(ThemeContext.context); let isMobile = Media.isMobile(); -
+
diff --git a/src/components/Header.re b/src/components/Header.re index 223b7242..785b088c 100644 --- a/src/components/Header.re +++ b/src/components/Header.re @@ -75,7 +75,9 @@ module DesktopRender = {
-
+
+ +
@@ -144,11 +146,19 @@ module MobileRender = {
- +
+ + + + + + + + ; }; }; diff --git a/src/components/HistoricalBondedGraph.re b/src/components/HistoricalBondedGraph.re index 500bfd9d..89472467 100644 --- a/src/components/HistoricalBondedGraph.re +++ b/src/components/HistoricalBondedGraph.re @@ -135,7 +135,7 @@ function(data, isDarkMode) { [@react.component] let make = (~operatorAddress) => { let dataQuery = HistoricalBondedQuery.get(operatorAddress); - let (ThemeContext.{isDarkMode}, _) = React.useContext(ThemeContext.context); + let ({ThemeContext.theme, isDarkMode}, _) = React.useContext(ThemeContext.context); React.useEffect2( () => { @@ -156,7 +156,7 @@ let make = (~operatorAddress) => {
- + - style([ - backgroundColor(theme.primary_600), - borderRadius(`px(8)), - width(`px(32)), - height(`px(32)), - hover([backgroundColor(theme.darkBlue)]), - ]); + let textMRight = style([marginRight(`px(6))]); + let headingContainer = style([marginTop(`px(40)), marginBottom(`px(16))]); }; module RenderBody = { [@react.component] let make = (~requestSub: ApolloHooks.Subscription.variant(RequestSub.t)) => { - + {switch (requestSub) { @@ -38,9 +31,7 @@ module RenderBody = { {switch (requestSub) { | Data({oracleScript: {oracleScriptID, name}}) =>
- - - +
| _ => }} @@ -83,7 +74,7 @@ module RenderBodyMobile = { values=InfoMobileCard.[ ("Request ID", RequestID(id)), ("Oracle Script", OracleScript(oracleScriptID, name)), - ("Report Status", Text({j|$reportedCount of $requestedCount|j})), + ("Report Status", RequestStatus(resolveStatus, {j|$reportedCount of $requestedCount|j})), ] key={id |> ID.Request.toString} idx={id |> ID.Request.toString} @@ -108,110 +99,110 @@ let make = (~latest5RequestSub: Sub.t(array(RequestSub.t))) => { let isMobile = Media.isMobile(); let (ThemeContext.{theme, isDarkMode}, _) = React.useContext(ThemeContext.context); - - - - {isMobile - ? <> - - - {switch (latest5RequestSub) { - | ApolloHooks.Subscription.Data(requests) => - Belt.Array.get(0) - ->Belt.Option.mapWithDefault(0, ({id}) => id |> ID.Request.toInt) - ->Format.iPretty - } - size=Text.Lg - weight=Text.Medium + <> + {isMobile ?
+ +
+ +
+ +
+ + +
+
: React.null } +
+ {isMobile + ? React.null + : + + + + +
+ +
+ - | _ => - }} - - : } - -
-
- {isMobile ? React.null : } - - -
- +
+ +
- - - - - {isMobile - ? React.null - : - - - - - - - - - - - - } - {switch (latest5RequestSub) { - | Data(requests) when requests->Belt.Array.length === 0 => - - No Request - - - | Data(requests) => - requests - ->Belt_Array.mapWithIndex((i, e) => - isMobile - ? ID.Request.toString} - reserveIndex=i - requestSub={Sub.resolve(e)} - /> - : ID.Request.toString} requestSub={Sub.resolve(e)} /> - ) - ->React.array - | _ => - Belt_Array.make(5, ApolloHooks.Subscription.NoData) - ->Belt_Array.mapWithIndex((i, noData) => - isMobile - ? string_of_int} reserveIndex=i requestSub=noData /> - : string_of_int} requestSub=noData /> - ) - ->React.array - }} -
; + +
} + {isMobile + ? React.null + : + + + + + + + + + + + + } + {switch (latest5RequestSub) { + | Data(requests) when requests->Belt.Array.length === 0 => + + No Request + + + | Data(requests) => + requests + ->Belt_Array.mapWithIndex((i, e) => + isMobile + ? ID.Request.toString} + reserveIndex=i + requestSub={Sub.resolve(e)} + /> + : ID.Request.toString} requestSub={Sub.resolve(e)} /> + ) + ->React.array + | _ => + Belt_Array.make(5, ApolloHooks.Subscription.NoData) + ->Belt_Array.mapWithIndex((i, noData) => + isMobile + ? string_of_int} reserveIndex=i requestSub=noData /> + : string_of_int} requestSub=noData /> + ) + ->React.array + }} + + ; }; diff --git a/src/components/LatestTxTable.re b/src/components/LatestTxTable.re index f5814343..c735e37c 100644 --- a/src/components/LatestTxTable.re +++ b/src/components/LatestTxTable.re @@ -2,34 +2,35 @@ module Styles = { open Css; let statusImg = style([width(`px(20)), marginTop(`px(-3))]); - let allTxLink = (theme: Theme.t) => - style([ - backgroundColor(theme.primary_600), - borderRadius(`px(8)), - width(`px(32)), - height(`px(32)), - hover([backgroundColor(theme.darkBlue)]), - ]); + let textMRight = style([marginRight(`px(6))]); + let headingContainer = style([marginBottom(`px(16))]); }; module RenderBody = { [@react.component] let make = (~txSub: ApolloHooks.Subscription.variant(TxSub.t)) => { - - - + + + {switch (txSub) { - | Data({txHash}) => + | Data({txHash}) => | _ => }} - + {switch (txSub) { | Data({blockHeight}) => | _ => }} - + + {switch (txSub) { + | Data({messages, txHash, success, errMsg}) => + + | _ => + }} + +
{switch (txSub) { | Data({success}) => @@ -42,13 +43,6 @@ module RenderBody = { }}
- - {switch (txSub) { - | Data({messages, txHash, success, errMsg}) => - - | _ => - }} -
; }; @@ -65,7 +59,8 @@ module RenderBodyMobile = { values=InfoMobileCard.[ ("Tx Hash", TxHash(txHash, isSmallMobile ? 170 : 200)), ("Block", Height(blockHeight)), - ("Actions", Messages(txHash, messages, success, errMsg)), + ("Actions", MsgBadgeGroup(txHash, messages)), + ("Status", Status(success)), ] key={txHash |> Hash.toHex} idx={txHash |> Hash.toHex} @@ -84,6 +79,7 @@ module RenderBodyMobile = { }, ), ), + ("Status", Loading(70)), ] key={reserveIndex |> string_of_int} idx={reserveIndex |> string_of_int} @@ -95,93 +91,92 @@ module RenderBodyMobile = { [@react.component] let make = () => { let isMobile = Media.isMobile(); - let txCount = 5; + let txCount = 10; let txsSub = TxSub.getList(~page=1, ~pageSize=txCount, ()); let (ThemeContext.{theme}, _) = React.useContext(ThemeContext.context); - - - - - - {switch (txsSub) { - | ApolloHooks.Subscription.Data(txs) => - Belt.Array.get(0) - ->Belt.Option.mapWithDefault(0, ({id}) => id) - ->Format.iPretty - } - size=Text.Lg - weight=Text.Medium - /> - | _ => - }} - - -
- {isMobile ? React.null : } - - -
- + <> + {isMobile ?
+ +
+ +
+ +
+ + +
+
: React.null } +
+ {isMobile + ? React.null + : + + + + +
+ +
+ +
+ +
- - - - - {isMobile - ? React.null - : - - -
- -
- - -
- -
- - -
- -
- - -
- -
- - - } - {switch (txsSub) { - | Data(txs) => - txs - ->Belt_Array.mapWithIndex((i, e) => - isMobile - ? Hash.toHex} - reserveIndex=i - txSub={Sub.resolve(e)} - /> - : Hash.toHex} txSub={Sub.resolve(e)} /> - ) - ->React.array - | _ => - Belt_Array.make(txCount, ApolloHooks.Subscription.NoData) - ->Belt_Array.mapWithIndex((i, noData) => - isMobile - ? - : - ) - ->React.array - }} -
; + +
} + {isMobile + ? React.null + : + + + + + + + + + + + + + + + } + {switch (txsSub) { + | Data(txs) => + txs + ->Belt_Array.mapWithIndex((i, e) => + isMobile + ? Hash.toHex} + reserveIndex=i + txSub={Sub.resolve(e)} + /> + : Hash.toHex} txSub={Sub.resolve(e)} /> + ) + ->React.array + | _ => + Belt_Array.make(txCount, ApolloHooks.Subscription.NoData) + ->Belt_Array.mapWithIndex((i, noData) => + isMobile + ? + : + ) + ->React.array + }} + + ; }; diff --git a/src/components/MsgBadgeGroup.re b/src/components/MsgBadgeGroup.re new file mode 100644 index 00000000..bf1b6355 --- /dev/null +++ b/src/components/MsgBadgeGroup.re @@ -0,0 +1,16 @@ +[@react.component] + let make = (~txHash, ~messages) => { + let theme = List.nth(messages, 0) |> MsgDecoder.getBadgeTheme; + let length = List.length(messages); + +
+ + { + length > 1 ? string_of_int)} + size=Text.Md + transform=Text.Uppercase /> : React.null + } +
; + + } diff --git a/src/components/NavBar.re b/src/components/NavBar.re index 33b08a7f..782acf13 100644 --- a/src/components/NavBar.re +++ b/src/components/NavBar.re @@ -7,6 +7,7 @@ module RenderDesktop = { padding3(~top=`px(16), ~h=`zero, ~bottom=`px(12)), cursor(`pointer), fontSize(`px(12)), + fontWeight(`num(600)), hover([color(theme.neutral_900)]), active([color(theme.neutral_900)]), transition(~duration=400, "all"), @@ -24,11 +25,14 @@ module RenderDesktop = {