From a55d422dedfa629f7ccd1bc7bee7f3c3accdbd7f Mon Sep 17 00:00:00 2001 From: Marco van Dijk Date: Fri, 4 Mar 2022 13:40:09 +0100 Subject: [PATCH] Added share function to orch profiles Rewrote some class components to functional components Batch multiple redux events on load and in the livepeer explorer component added inset when button is active --- public/clipboard.svg | 187 ++++++++++++++++++++++ src/App.js | 1 - src/eventButton.js | 41 ++--- src/eventViewer.js | 38 +++-- src/grafana.js | 167 +++++++++----------- src/livepeer.js | 320 ++++++++++++++++++-------------------- src/loadingScreen.js | 18 ++- src/orchestratorViewer.js | 34 +++- src/style.css | 3 + 9 files changed, 489 insertions(+), 320 deletions(-) create mode 100644 public/clipboard.svg diff --git a/public/clipboard.svg b/public/clipboard.svg new file mode 100644 index 0000000..3b5b58d --- /dev/null +++ b/public/clipboard.svg @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/App.js b/src/App.js index d71ce26..f0650ba 100644 --- a/src/App.js +++ b/src/App.js @@ -11,7 +11,6 @@ import { } from "react-router-dom"; - export default function App() { return ( diff --git a/src/eventButton.js b/src/eventButton.js index 5c03084..4b26a9a 100644 --- a/src/eventButton.js +++ b/src/eventButton.js @@ -1,4 +1,8 @@ import React from "react"; +import { + getOrchestratorInfo +} from "./actions/livepeer"; +import { useDispatch } from 'react-redux' const activationColour = "rgba(23, 60, 122, 0.3)"; const rewardColour = "rgba(20, 99, 29, 0.3)"; @@ -7,6 +11,7 @@ const withdrawStakeColour = "rgba(102, 3, 10, 0.3)"; const stakeColour = "rgba(71, 23, 122, 0.3)"; const EventButton = (obj) => { + const dispatch = useDispatch(); // Data shared among all events in this transaction const thisURL = obj.transactionUrl; //const thisTransaction = obj.transactionHash; @@ -81,8 +86,8 @@ const EventButton = (obj) => { } // Check name filter on transactionCaller, transactionFrom, transactionTo - if (obj.searchTerm){ - if (obj.searchTerm !== ""){ + if (obj.searchTerm) { + if (obj.searchTerm !== "") { let isFiltered = true; if (transactionCaller.toLowerCase().includes(obj.searchTerm.toLowerCase())) isFiltered = false; if (transactionFrom.toLowerCase().includes(obj.searchTerm.toLowerCase())) isFiltered = false; @@ -93,40 +98,40 @@ const EventButton = (obj) => { let isFiltered = true; // Check boolean filters on transactionName let count = 0; - if(obj.filterActivated){ - if (transactionName === "Activated"){ + if (obj.filterActivated) { + if (transactionName === "Activated") { isFiltered = false; } count++; } - if(obj.rewardActivated){ - if (transactionName === "Reward"){ + if (obj.rewardActivated) { + if (transactionName === "Reward") { isFiltered = false; } count++; } - if(obj.updateActivated){ - if (transactionName === "Update"){ + if (obj.updateActivated) { + if (transactionName === "Update") { isFiltered = false; } count++; } - if(obj.withdrawActivated){ - if (transactionName === "Withdraw"){ + if (obj.withdrawActivated) { + if (transactionName === "Withdraw") { isFiltered = false; } count++; } - if(obj.stakeActivated){ - if (transactionName === "Stake"){ + if (obj.stakeActivated) { + if (transactionName === "Stake") { isFiltered = false; } count++; } - if (isFiltered && count){ + if (isFiltered && count) { return null; } - + let eventSpecificInfo; if (transactionName === "Reward") { if (transactionAmount - 69 < 1 && transactionAmount - 69 > 0) { @@ -150,15 +155,15 @@ const EventButton = (obj) => { eventSpecificInfo =

staked {(transactionAmount / 1000000000000000000).toFixed(2)} LPT to

- +
} else { eventSpecificInfo =

moved {(transactionAmount / 1000000000000000000).toFixed(2)} LPT stake:

- +

to

- +
} } else if (transactionName === "Withdraw") { @@ -196,7 +201,7 @@ const EventButton = (obj) => {
- +
{eventSpecificInfo} diff --git a/src/eventViewer.js b/src/eventViewer.js index 1c32d8c..faf930d 100644 --- a/src/eventViewer.js +++ b/src/eventViewer.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useState } from "react"; import EventButton from "./eventButton"; import ScrollContainer from 'react-indiana-drag-scroll'; @@ -9,7 +9,7 @@ const withdrawStakeColour = "rgba(102, 3, 10, 0.3)"; const stakeColour = "rgba(71, 23, 122, 0.3)"; const EventViewer = (obj) => { - const [searchTerm, setSearchTerm] = useState(""); + const [searchTerm, setSearchTerm] = useState(obj.prefill || ""); const [filterActivated, setFilterActivated] = useState(false); const [rewardActivated, setRewardActivated] = useState(false); const [updateActivated, setUpdateActivated] = useState(false); @@ -28,23 +28,22 @@ const EventViewer = (obj) => { let finalIdx = 0; return (
-
-
- setSearchTerm(evt.target.value)} - placeholder='Filter by Orchestrator address' - type="text" - /> -
+
+ setSearchTerm(evt.target.value)} + placeholder='Filter by Orchestrator address' + type="text" + />
-
+
-
+
{obj.events.slice(0).reverse().map((eventObj, idx) => { // Filter if (eventObj.name === "WithdrawFees" || eventObj.name === "TransferBond" || eventObj.name === "Rebond" || eventObj.name === "Unbond" || eventObj.name === "EarningsClaimed") { + console.log("Skipping event" + eventObj); return; } // New transaction found @@ -73,7 +72,6 @@ const EventViewer = (obj) => { transactionHash={finalHash} events={eventBundle} idx={finalIdx} - setOrchFunction={obj.setOrchFunction} searchTerm={searchTerm} filterActivated={filterActivated} rewardActivated={rewardActivated} @@ -85,28 +83,28 @@ const EventViewer = (obj) => { })}
-
- - - - - +
-
- -
-
-
-
-
+
+
+
+
-
- -

${lptPrice}

-

({lptPriceChange24h}%)

-
- -
- -

${ethPrice}

-

({ethPriceChange24h}%)

-
+ +

${lptPrice}

+

({lptPriceChange24h}%)

-
-
- -
-
- -
-
- -
-
- -
-
- -
- + +
+ +

${ethPrice}

+

({ethPriceChange24h}%)

+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
- ); - } +
+ ); } -export default connect( - mapStateToProps, - mapDispatchToProps -)(Grafana); +export default Grafana; diff --git a/src/livepeer.js b/src/livepeer.js index 5c17d2a..a33b24e 100644 --- a/src/livepeer.js +++ b/src/livepeer.js @@ -1,9 +1,9 @@ -import * as React from "react"; +import React, { useState, useEffect } from 'react' import './style.css'; import { - Navigate + Navigate, useSearchParams } from "react-router-dom"; -import { connect } from "react-redux"; +import { useSelector, useDispatch, batch } from 'react-redux' import { getQuotes, getBlockchainData, getEvents, getCurrentOrchestratorInfo, getOrchestratorInfo } from "./actions/livepeer"; @@ -11,190 +11,166 @@ import EventViewer from "./eventViewer"; import Orchestrator from "./orchestratorViewer"; import Stat from "./statViewer"; -const mapStateToProps = (state) => { - return { - session: state.session, - userstate: state.userstate, - errors: state.errors, - livepeer: state.livepeerstate - } -}; +// Refresh every 30 seconds +const refreshInterval = 30000; -const mapDispatchToProps = dispatch => ({ - getQuotes: () => dispatch(getQuotes()), - getBlockchainData: () => dispatch(getBlockchainData()), - getEvents: () => dispatch(getEvents()), - getCurrentOrchestratorInfo: () => dispatch(getCurrentOrchestratorInfo()), - getOrchestratorInfo: (addr) => dispatch(getOrchestratorInfo(addr)) -}); +const Livepeer = (obj) => { + const [prefill, setPrefill] = useSearchParams(); + const dispatch = useDispatch(); + const livepeer = useSelector((state) => state.livepeerstate); + const [redirectToHome, setRedirectToHome] = useState(false); -class Livepeer extends React.Component { - state = { - redirectToHome: false, - }; - - constructor(props) { - super(props); + const refreshAllZeData = () => { + batch(() => { + dispatch(getQuotes()) + dispatch(getEvents()) + dispatch(getBlockchainData()) + dispatch(getCurrentOrchestratorInfo()) + }); } - componentDidMount() { - this.props.getQuotes(); - this.props.getBlockchainData(); - this.props.getEvents(); - this.props.getCurrentOrchestratorInfo(); + useEffect(() => { + if (prefill.get('orchAddr') != ""){ + dispatch(getOrchestratorInfo(prefill.get('orchAddr'))); + } + if (refreshInterval) { + const interval = setInterval(refreshAllZeData, refreshInterval); + return () => clearInterval(interval); + } + }, [refreshInterval]); + + if (redirectToHome) { + return ; } - render() { - if (this.state.redirectToHome) { - return ; + let ethPrice = 0; + if (livepeer.quotes) { + if (livepeer.quotes.ETH) { + ethPrice = livepeer.quotes.ETH.price.toFixed(2); } + } - let lptPrice = 0; - let ethPrice = 0; - let lptPriceChange24h = 0; - let ethPriceChange24h = 0; - if (this.props.livepeer.quotes) { - if (this.props.livepeer.quotes.LPT) { - lptPrice = this.props.livepeer.quotes.LPT.price.toFixed(2); - lptPriceChange24h = this.props.livepeer.quotes.LPT.percent_change_24h.toFixed(2); - } - if (this.props.livepeer.quotes.ETH) { - ethPrice = this.props.livepeer.quotes.ETH.price.toFixed(2); - ethPriceChange24h = this.props.livepeer.quotes.ETH.percent_change_24h.toFixed(2); - } - } + let l1GasFeeInGwei = 0; + let l2GasFeeInGwei = 0; + let redeemRewardCostL1 = 0; + let redeemRewardCostL2 = 0; + let claimTicketCostL1 = 0; + let claimTicketCostL2 = 0; + let withdrawFeeCostL1 = 0; + let withdrawFeeCostL2 = 0; + let stakeFeeCostL1 = 0; + let stakeFeeCostL2 = 0; + let commissionFeeCostL1 = 0; + let commissionFeeCostL2 = 0; + let serviceUriFeeCostL1 = 0; + let serviceUriFeeCostL2 = 0; + if (livepeer.blockchains) { + l1GasFeeInGwei = livepeer.blockchains.l1GasFeeInGwei; + l2GasFeeInGwei = livepeer.blockchains.l2GasFeeInGwei; + redeemRewardCostL1 = livepeer.blockchains.redeemRewardCostL1; + redeemRewardCostL2 = livepeer.blockchains.redeemRewardCostL2; + claimTicketCostL1 = livepeer.blockchains.claimTicketCostL1; + claimTicketCostL2 = livepeer.blockchains.claimTicketCostL2; + withdrawFeeCostL1 = livepeer.blockchains.withdrawFeeCostL1; + withdrawFeeCostL2 = livepeer.blockchains.withdrawFeeCostL2; + stakeFeeCostL1 = livepeer.blockchains.stakeFeeCostL1; + stakeFeeCostL2 = livepeer.blockchains.stakeFeeCostL2; + commissionFeeCostL1 = livepeer.blockchains.commissionFeeCostL1; + commissionFeeCostL2 = livepeer.blockchains.commissionFeeCostL2; + serviceUriFeeCostL1 = livepeer.blockchains.serviceUriFeeCostL1; + serviceUriFeeCostL2 = livepeer.blockchains.serviceUriFeeCostL2; + } - let blockchainTime = 0; - let l1Block = 0; - let l2Block = 0; - let l1GasFeeInGwei = 0; - let l2GasFeeInGwei = 0; - let redeemRewardCostL1 = 0; - let redeemRewardCostL2 = 0; - let claimTicketCostL1 = 0; - let claimTicketCostL2 = 0; - let withdrawFeeCostL1 = 0; - let withdrawFeeCostL2 = 0; - let stakeFeeCostL1 = 0; - let stakeFeeCostL2 = 0; - let commissionFeeCostL1 = 0; - let commissionFeeCostL2 = 0; - let serviceUriFeeCostL1 = 0; - let serviceUriFeeCostL2 = 0; - if (this.props.livepeer.blockchains) { - blockchainTime = this.props.livepeer.blockchains.timestamp; - l1GasFeeInGwei = this.props.livepeer.blockchains.l1GasFeeInGwei; - l2GasFeeInGwei = this.props.livepeer.blockchains.l2GasFeeInGwei; - redeemRewardCostL1 = this.props.livepeer.blockchains.redeemRewardCostL1; - redeemRewardCostL2 = this.props.livepeer.blockchains.redeemRewardCostL2; - claimTicketCostL1 = this.props.livepeer.blockchains.claimTicketCostL1; - claimTicketCostL2 = this.props.livepeer.blockchains.claimTicketCostL2; - withdrawFeeCostL1 = this.props.livepeer.blockchains.withdrawFeeCostL1; - withdrawFeeCostL2 = this.props.livepeer.blockchains.withdrawFeeCostL2; - l1Block = this.props.livepeer.blockchains.l1block; - l2Block = this.props.livepeer.blockchains.l2block; - stakeFeeCostL1 = this.props.livepeer.blockchains.stakeFeeCostL1; - stakeFeeCostL2 = this.props.livepeer.blockchains.stakeFeeCostL2; - commissionFeeCostL1 = this.props.livepeer.blockchains.commissionFeeCostL1; - commissionFeeCostL2 = this.props.livepeer.blockchains.commissionFeeCostL2; - serviceUriFeeCostL1 = this.props.livepeer.blockchains.serviceUriFeeCostL1; - serviceUriFeeCostL2 = this.props.livepeer.blockchains.serviceUriFeeCostL2; + let redeemRewardCostL1USD = 0; + let redeemRewardCostL2USD = 0; + let claimTicketCostL1USD = 0; + let claimTicketCostL2USD = 0; + let withdrawFeeCostL1USD = 0; + let withdrawFeeCostL2USD = 0; + let stakeFeeCostL1USD = 0; + let stakeFeeCostL2USD = 0; + let commissionFeeCostL1USD = 0; + let commissionFeeCostL2USD = 0; + let serviceUriFeeCostL1USD = 0; + let serviceUriFeeCostL2USD = 0; + if (l1GasFeeInGwei && ethPrice) { + if (redeemRewardCostL1) { + redeemRewardCostL1USD = (redeemRewardCostL1 * ethPrice).toFixed(2); } + if (claimTicketCostL1) { + claimTicketCostL1USD = (claimTicketCostL1 * ethPrice).toFixed(2); + } + if (withdrawFeeCostL1) { + withdrawFeeCostL1USD = (withdrawFeeCostL1 * ethPrice).toFixed(2); + } + if (stakeFeeCostL1) { + stakeFeeCostL1USD = (stakeFeeCostL1 * ethPrice).toFixed(2); + } + if (commissionFeeCostL1) { + commissionFeeCostL1USD = (commissionFeeCostL1 * ethPrice).toFixed(2); + } + if (serviceUriFeeCostL1) { + serviceUriFeeCostL1USD = (serviceUriFeeCostL1 * ethPrice).toFixed(2); + } + } + if (l2GasFeeInGwei && ethPrice) { + if (redeemRewardCostL2) { + redeemRewardCostL2USD = (redeemRewardCostL2 * ethPrice).toFixed(2); + } + if (claimTicketCostL2) { + claimTicketCostL2USD = (claimTicketCostL2 * ethPrice).toFixed(2); + } + if (withdrawFeeCostL2) { + withdrawFeeCostL2USD = (withdrawFeeCostL2 * ethPrice).toFixed(2); + } + if (stakeFeeCostL2) { + stakeFeeCostL2USD = (stakeFeeCostL2 * ethPrice).toFixed(2); + } + if (commissionFeeCostL2) { + commissionFeeCostL2USD = (commissionFeeCostL2 * ethPrice).toFixed(2); + } + if (serviceUriFeeCostL2) { + serviceUriFeeCostL2USD = (serviceUriFeeCostL2 * ethPrice).toFixed(2); + } + } - let redeemRewardCostL1USD = 0; - let redeemRewardCostL2USD = 0; - let claimTicketCostL1USD = 0; - let claimTicketCostL2USD = 0; - let withdrawFeeCostL1USD = 0; - let withdrawFeeCostL2USD = 0; - let stakeFeeCostL1USD = 0; - let stakeFeeCostL2USD = 0; - let commissionFeeCostL1USD = 0; - let commissionFeeCostL2USD = 0; - let serviceUriFeeCostL1USD = 0; - let serviceUriFeeCostL2USD = 0; - if (l1GasFeeInGwei && ethPrice) { - if (redeemRewardCostL1) { - redeemRewardCostL1USD = (redeemRewardCostL1 * ethPrice).toFixed(2); - } - if (claimTicketCostL1) { - claimTicketCostL1USD = (claimTicketCostL1 * ethPrice).toFixed(2); - } - if (withdrawFeeCostL1) { - withdrawFeeCostL1USD = (withdrawFeeCostL1 * ethPrice).toFixed(2); - } - if (stakeFeeCostL1) { - stakeFeeCostL1USD = (stakeFeeCostL1 * ethPrice).toFixed(2); - } - if (commissionFeeCostL1) { - commissionFeeCostL1USD = (commissionFeeCostL1 * ethPrice).toFixed(2); - } - if (serviceUriFeeCostL1) { - serviceUriFeeCostL1USD = (serviceUriFeeCostL1 * ethPrice).toFixed(2); - } - } - if (l2GasFeeInGwei && ethPrice) { - if (redeemRewardCostL2) { - redeemRewardCostL2USD = (redeemRewardCostL2 * ethPrice).toFixed(2); - } - if (claimTicketCostL2) { - claimTicketCostL2USD = (claimTicketCostL2 * ethPrice).toFixed(2); - } - if (withdrawFeeCostL2) { - withdrawFeeCostL2USD = (withdrawFeeCostL2 * ethPrice).toFixed(2); - } - if (stakeFeeCostL2) { - stakeFeeCostL2USD = (stakeFeeCostL2 * ethPrice).toFixed(2); - } - if (commissionFeeCostL2) { - commissionFeeCostL2USD = (commissionFeeCostL2 * ethPrice).toFixed(2); - } - if (serviceUriFeeCostL2) { - serviceUriFeeCostL2USD = (serviceUriFeeCostL2 * ethPrice).toFixed(2); - } - } + let eventsList = []; + if (livepeer.events) { + eventsList = livepeer.events; + } - let eventsList = []; - if (this.props.livepeer.events) { - eventsList = this.props.livepeer.events; - } + let thisOrchObj; + if (livepeer.selectedOrchestrator) { + thisOrchObj = livepeer.selectedOrchestrator; + } - let thisOrchObj; - if (this.props.livepeer.selectedOrchestrator) { - thisOrchObj = this.props.livepeer.selectedOrchestrator; - } - - return ( -
-
- -
- + return ( +
+
+ +
+ +
+
+
+

Smart contract prices

-
-
-

Smart contract prices

-
-
- - - - - -
+
+ + + + +
-
- +
- ); - } + +
+ ); } -export default connect( - mapStateToProps, - mapDispatchToProps -)(Livepeer); +export default Livepeer; \ No newline at end of file diff --git a/src/loadingScreen.js b/src/loadingScreen.js index 74da480..251f2bf 100644 --- a/src/loadingScreen.js +++ b/src/loadingScreen.js @@ -1,5 +1,5 @@ import * as React from "react"; -import { connect } from "react-redux"; +import { connect, batch } from "react-redux"; import { getVisitorStats } from "./actions/user"; @@ -20,20 +20,22 @@ const mapDispatchToProps = dispatch => ({ getVisitorStats: () => dispatch(getVisitorStats()), login: () => dispatch(login()), getQuotes: () => dispatch(getQuotes()), - getBlockchainData: () => dispatch(getBlockchainData()), getEvents: () => dispatch(getEvents()), + getBlockchainData: () => dispatch(getBlockchainData()), getCurrentOrchestratorInfo: () => dispatch(getCurrentOrchestratorInfo()) }); class Startup extends React.Component { componentDidMount() { - this.props.login(); - this.props.getVisitorStats(); - this.props.getQuotes(); - this.props.getBlockchainData(); - this.props.getEvents(); - this.props.getCurrentOrchestratorInfo(); + batch(() => { + this.props.login(); + this.props.getVisitorStats(); + this.props.getQuotes(); + this.props.getBlockchainData(); + this.props.getEvents(); + this.props.getCurrentOrchestratorInfo(); + }); } render() { return this.props.children; diff --git a/src/orchestratorViewer.js b/src/orchestratorViewer.js index 3c8bd61..85fc13a 100644 --- a/src/orchestratorViewer.js +++ b/src/orchestratorViewer.js @@ -2,6 +2,27 @@ import React from "react"; import ScrollContainer from "react-indiana-drag-scroll"; import Stat from "./statViewer"; +function updateClipboard(newClip) { + navigator.clipboard.writeText(newClip).then( + () => { + console.log("Copied!"); + }, + () => { + console.log("Copy failed!"); + } + ); +} + +function copyLink(addr) { + navigator.permissions + .query({ name: "clipboard-write" }) + .then((result) => { + if (result.state === "granted" || result.state === "prompt") { + updateClipboard(addr); + } + }); +} + const Orchestrator = (obj) => { let rewardCut = 0; let feeCut = 0; @@ -41,7 +62,7 @@ const Orchestrator = (obj) => { return (