diff --git a/src/components/StakeOverview.js b/src/components/StakeOverview.js new file mode 100644 index 0000000..4684b5d --- /dev/null +++ b/src/components/StakeOverview.js @@ -0,0 +1,203 @@ +import React, { useState, useEffect } from 'react' +import { useSelector, useDispatch } from 'react-redux'; +import { VictoryPie } from 'victory'; +import Address from '../components/OrchAddressViewer'; +import { + getOrchestratorScores +} from "../actions/livepeer"; + +const StakeOverview = (obj) => { + const livepeer = useSelector((state) => state.livepeerstate); + const dispatch = useDispatch(); + const [thisScores, setThisScores] = useState(null); + const [removeOnlyStakers, setRemoveOnlyStakers] = useState(false); + + useEffect(() => { + const now = new Date().getTime(); + let wasInCache = false; + // See if it is cached + for (const thisScore of livepeer.orchScores) { + if (thisScore.year === obj.year && thisScore.month === obj.month) { + // Check timeout + if (now - thisScore.timestamp < 360000) { + wasInCache = true; + } + if (!thisScores) { + setThisScores(thisScore); + } + } + } + if (!wasInCache) { + dispatch(getOrchestratorScores(obj.year, obj.month)); + } + }, [livepeer.orchScores]); + + const getName = (address) => { + let thisDomain = null; + // Lookup domain in cache + if (livepeer.ensDomainMapping) { + for (const thisAddr of livepeer.ensDomainMapping) { + if (thisAddr.address === address) { + thisDomain = thisAddr; + break; + } + } + } + // Lookup current info in cache only if this addr has a mapped ENS domain + if (thisDomain && thisDomain.domain) { + for (const thisAddr of livepeer.ensInfoMapping) { + if (thisAddr.domain === thisDomain.domain) { + return thisAddr.domain; + } + } + } + + if (livepeer.threeBoxInfo) { + for (const thisAddr of livepeer.threeBoxInfo) { + if (thisAddr.address === address) { + if (thisAddr.name) { + return thisAddr.name; + } else { + return (address.substring(0, 10) + ".."); + } + break; + } + } + } + + return (address.substring(0, 10) + ".."); + } + + let orchList = []; + let pieList = []; + let otherSum = 0; + let pieObj = null; + if (livepeer.orchInfo) { + let orchIdx = livepeer.orchInfo.length - 1; + // calc sum of stake + let totalStake = 0; + while (orchIdx >= 0) { + const thisOrch = livepeer.orchInfo[orchIdx]; + orchIdx -= 1; + if (removeOnlyStakers && !parseInt(thisOrch.totalVolumeUSD)) { + continue; + } + totalStake += parseInt(thisOrch.totalStake); + } + // create slices + orchIdx = livepeer.orchInfo.length - 1; + while (orchIdx >= 0) { + const thisOrch = livepeer.orchInfo[orchIdx]; + const thisStake = parseInt(thisOrch.totalStake); + orchIdx -= 1; + if (removeOnlyStakers && !parseInt(thisOrch.totalVolumeUSD)) { + continue; + } + // Add orch stat descending + let idx = orchList.length - 1; + while (idx >= 0) { + const sel = orchList[idx]; + idx--; + if (sel.sum < thisStake) { + continue; + } else { + break; + } + } + if (idx == orchList.length - 1) { + orchList.push({ + address: thisOrch.id, + sum: thisStake, + ratio: (thisStake / totalStake) * 100 + }); + } else { + orchList.splice(idx + 1, 0, { + address: thisOrch.id, + sum: thisStake, + ratio: (thisStake / totalStake) * 100 + }); + } + // Add slice + if ((thisStake / totalStake) < 0.04) { + otherSum += thisStake; + } else { + pieList.push({ + address: getName(thisOrch.id), + sum: thisStake + }); + } + } + pieList.push({ + address: "Other", + sum: otherSum + }); + pieObj =
+

Active Orchestrators by Stake

+
+

Only Transcoding?

+
setRemoveOnlyStakers(!removeOnlyStakers)}> +
+ {removeOnlyStakers ? "1" : "0"} +
+
+
+ +
+ } + + + return ( +
+ {pieObj} +
+ { + orchList.map(function (orch) { + return ( +
+
+
+
+
+
+

{orch.sum.toFixed(2)} LPT

+
+
+ ({orch.ratio.toFixed(2)} %) +
+
+
+ ) + }) + } +
+
+
+ ) +} + +export default StakeOverview; \ No newline at end of file diff --git a/src/components/eventButtonAddress.js b/src/components/eventButtonAddress.js index e906bc6..47ef310 100644 --- a/src/components/eventButtonAddress.js +++ b/src/components/eventButtonAddress.js @@ -8,16 +8,15 @@ const EventButtonAddress = (obj) => { const dispatch = useDispatch(); const livepeer = useSelector((state) => state.livepeerstate); const [hasRefreshed, setRefresh] = useState(false); - const [hasENS, setHasENS] = useState(false); - const [hasThreeBox, setHasThreeBox] = useState(false); const [hasThreeBoxRefreshed, setThreeBoxRefresh] = useState(false); - const [hasOrchInfo, setHasOrchInfo] = useState(false); const [orchInfo, setOrchInfo] = useState(null); const now = new Date().getTime(); useEffect(() => { let thisInfo = null; let thisDomain = null; + let hasENS = null; + let hasThreeBox = null // Lookup domain in cache if (livepeer.ensDomainMapping && !hasRefreshed) { for (const thisAddr of livepeer.ensDomainMapping) { @@ -29,6 +28,7 @@ const EventButtonAddress = (obj) => { } // Is outdated if (!hasRefreshed) { + console.log("Refresh due to old ENS domain"); getEnsInfo(obj.address); setRefresh(true); } @@ -37,6 +37,7 @@ const EventButtonAddress = (obj) => { } // If it was not cached at all if (thisDomain == null && !hasRefreshed) { + console.log("Refresh due to non-existing ENS domain"); setRefresh(true); getEnsInfo(obj.address); } @@ -46,13 +47,14 @@ const EventButtonAddress = (obj) => { for (const thisAddr of livepeer.ensInfoMapping) { if (thisAddr.domain === thisDomain.domain) { thisInfo = thisAddr; - setHasENS(true); + hasENS = true; // Check timeout if (now - thisAddr.timestamp < 86400000) { break; } // Is outdated if (!hasRefreshed) { + console.log("Refresh due to old ENS info"); getEnsInfo(obj.address); setRefresh(true); } @@ -61,6 +63,7 @@ const EventButtonAddress = (obj) => { } // If it was not cached at all if (thisInfo == null && !hasRefreshed) { + console.log("Refresh due to non-existing ENS info"); getEnsInfo(obj.address); setRefresh(true); } @@ -72,51 +75,41 @@ const EventButtonAddress = (obj) => { for (const thisAddr of livepeer.threeBoxInfo) { if (thisAddr.address === obj.address) { thisInfo = thisAddr; - setHasThreeBox(true); - // Check timeout - if (now - thisAddr.timestamp < 86400000) { - break; - } - // Is outdated - if (!hasThreeBoxRefreshed) { - getThreeBoxInfo(obj.address); - setThreeBoxRefresh(true); - } + hasThreeBox = true; break; } } // If it was not cached at all - if (thisDomain == null && !hasThreeBoxRefreshed) { + if (!hasThreeBox && !hasThreeBoxRefreshed) { + console.log("Refresh due to non-existing 3BOX info"); setThreeBoxRefresh(true); getThreeBoxInfo(obj.address); } } } if (thisInfo && thisInfo != orchInfo){ + console.log("Setting INFO obj"); setOrchInfo(thisInfo); } - }, [livepeer.ensDomainMapping, livepeer.threeBoxInfo, hasRefreshed, hasENS, hasThreeBoxRefreshed]); + }, [livepeer.ensDomainMapping, livepeer.threeBoxInfo]); useEffect(() => { // Check if cached as an orchestrator - if (livepeer.orchInfo && !hasOrchInfo) { + if (livepeer.orchInfo) { for (const thisOrch of livepeer.orchInfo) { if (thisOrch.id === obj.address) { - setHasOrchInfo(true); - break; + return; } } // Preload Orch info - if (!hasOrchInfo) { - dispatch(getOrchestratorInfoSilent(obj.address)); - setHasOrchInfo(true); - } + console.log("Refresh due to non-existing orch in global state"); + dispatch(getOrchestratorInfoSilent(obj.address)); } - }, [livepeer.orchInfo, hasOrchInfo]); + }, [livepeer.orchInfo]); let thisName; let thisIcon; - if (hasENS) { + if (orchInfo && orchInfo.domain) { thisName =

{orchInfo.domain}

; if (orchInfo.avatar) { thisIcon = @@ -124,7 +117,7 @@ const EventButtonAddress = (obj) => { } - } else if (hasThreeBox) { + } else if (orchInfo && (orchInfo.name || orchInfo.image)) { if (orchInfo.name) { thisName =

{orchInfo.name}

; } else { diff --git a/src/pages/tickets.js b/src/pages/tickets.js index b49f173..e336c2e 100644 --- a/src/pages/tickets.js +++ b/src/pages/tickets.js @@ -5,13 +5,13 @@ import { useSelector, useDispatch } from 'react-redux'; import { Accordion } from '@mantine/core'; import ScrollContainer from 'react-indiana-drag-scroll'; import WinnerMonth from '../components/WinnerMonth'; +import StakeOverview from '../components/StakeOverview'; import { VictoryPie } from 'victory'; const Tickets = (obj) => { const livepeer = useSelector((state) => state.livepeerstate); const [ticketsPerMonth, setTicketsPerMonth] = useState([]); const [redirectToHome, setRedirectToHome] = useState(false); - const [removeOnlyStakers, setRemoveOnlyStakers] = useState(false); console.log("Rendering Winning Ticket Viewer"); @@ -176,81 +176,6 @@ const Tickets = (obj) => { return (address.substring(0, 10) + ".."); } - let pieList = []; - let otherSum = 0; - let pieObj = null; - if (livepeer.orchInfo) { - let orchIdx = livepeer.orchInfo.length - 1; - // calc sum of stake - let totalStake = 0; - while (orchIdx >= 0) { - const thisOrch = livepeer.orchInfo[orchIdx]; - orchIdx -= 1; - if (removeOnlyStakers && !parseInt(thisOrch.totalVolumeUSD)) { - continue; - } - totalStake += parseInt(thisOrch.totalStake); - } - // create slices - orchIdx = livepeer.orchInfo.length - 1; - while (orchIdx >= 0) { - const thisOrch = livepeer.orchInfo[orchIdx]; - orchIdx -= 1; - if (removeOnlyStakers && !parseInt(thisOrch.totalVolumeUSD)) { - continue; - } - if ((thisOrch.totalStake / totalStake) < 0.04) { - otherSum += thisOrch.totalStake; - } else { - pieList.push({ - address: getName(thisOrch.id), - sum: thisOrch.totalStake - }); - } - } - pieList.push({ - address: "Other", - sum: otherSum - }); - pieObj =
-

Active Orchestrators by Stake

-
-

Show non-transcoding Orchestrators?

-
setRemoveOnlyStakers(!removeOnlyStakers)}> -
- {removeOnlyStakers ? "Show" : "Hide"} -
-
-
- -
- } - return (