From b488b5f33fd0a74b5f0c4adb20a14d39cf170ac7 Mon Sep 17 00:00:00 2001 From: zho Date: Thu, 5 Dec 2024 16:56:43 +0100 Subject: [PATCH] chore: turn off live updates (#3020) --- .../Contest/components/StickyCards/index.tsx | 6 +- .../_pages/ListProposals/container.tsx | 16 +- .../hooks/useCastVotes/index.ts | 42 +++-- .../hooks/useContest/index.ts | 22 --- .../hooks/useContest/store.tsx | 4 - .../hooks/useContestEvents/index.ts | 150 ------------------ .../hooks/useProposal/store.tsx | 4 - .../layouts/LayoutViewContest/index.tsx | 13 -- 8 files changed, 32 insertions(+), 225 deletions(-) delete mode 100644 packages/react-app-revamp/hooks/useContestEvents/index.ts diff --git a/packages/react-app-revamp/components/_pages/Contest/components/StickyCards/index.tsx b/packages/react-app-revamp/components/_pages/Contest/components/StickyCards/index.tsx index e1c3a544f..11021eb19 100644 --- a/packages/react-app-revamp/components/_pages/Contest/components/StickyCards/index.tsx +++ b/packages/react-app-revamp/components/_pages/Contest/components/StickyCards/index.tsx @@ -1,4 +1,3 @@ -import useContestEvents from "@hooks/useContestEvents"; import { ContestStateEnum, useContestStateStore } from "@hooks/useContestState/store"; import { ContestStatus, useContestStatusStore } from "@hooks/useContestStatus/store"; import ContestCountdown from "./components/Countdown"; @@ -8,7 +7,6 @@ const ContestStickyCards = () => { const contestStatus = useContestStatusStore(state => state.contestStatus); const { contestState } = useContestStateStore(state => state); const isContestCanceled = contestState === ContestStateEnum.Canceled; - const { displayReloadBanner } = useContestEvents(); if (isContestCanceled || contestStatus === ContestStatus.VotingClosed) { return ( @@ -19,9 +17,7 @@ const ContestStickyCards = () => { } return ( -
+
diff --git a/packages/react-app-revamp/components/_pages/ListProposals/container.tsx b/packages/react-app-revamp/components/_pages/ListProposals/container.tsx index f7d183f2b..d45ef7dbc 100644 --- a/packages/react-app-revamp/components/_pages/ListProposals/container.tsx +++ b/packages/react-app-revamp/components/_pages/ListProposals/container.tsx @@ -17,8 +17,9 @@ const ListProposalsContainer = ({ enabledPreview, children }: ListProposalsConta case EntryPreview.IMAGE_AND_TITLE: case EntryPreview.TWEET: const childrenArray = React.Children.toArray(children); - const leftColumn = childrenArray.filter((_, index) => index % 2 === 0); - const rightColumn = childrenArray.filter((_, index) => index % 2 !== 0); + const firstColumn = childrenArray.filter((_, index) => index % 3 === 0); + const secondColumn = childrenArray.filter((_, index) => index % 3 === 1); + const thirdColumn = childrenArray.filter((_, index) => index % 3 === 2); if (isMobile) { return
{children}
; @@ -27,14 +28,21 @@ const ListProposalsContainer = ({ enabledPreview, children }: ListProposalsConta return (
- {leftColumn.map((child, index) => ( + {firstColumn.map((child, index) => (
{child}
))}
- {rightColumn.map((child, index) => ( + {secondColumn.map((child, index) => ( +
+ {child} +
+ ))} +
+
+ {thirdColumn.map((child, index) => (
{child}
diff --git a/packages/react-app-revamp/hooks/useCastVotes/index.ts b/packages/react-app-revamp/hooks/useCastVotes/index.ts index acc7fc46d..d10b5f491 100644 --- a/packages/react-app-revamp/hooks/useCastVotes/index.ts +++ b/packages/react-app-revamp/hooks/useCastVotes/index.ts @@ -48,7 +48,6 @@ interface CombinedAnalyticsParams extends UserAnalyticsParams, RewardsAnalyticsP export function useCastVotes() { const { - canUpdateVotesInRealTime, charge, contestAbi: abi, version, @@ -174,30 +173,27 @@ export function useCastVotes() { hash: receipt.transactionHash, }); - // We need this to update the votes either if there is more than 2 hours - if (!canUpdateVotesInRealTime) { - const voteResponse = (await readContract(config, { - address: contestAddress as `0x${string}`, - abi: DeployedContestContract.abi, - functionName: "proposalVotes", - args: [pickedProposal], - })) as bigint[]; + const voteResponse = (await readContract(config, { + address: contestAddress as `0x${string}`, + abi: DeployedContestContract.abi, + functionName: "proposalVotes", + args: [pickedProposal], + })) as bigint[]; - const forVotes = voteResponse[0] as bigint; - const againstVotes = voteResponse[1] as bigint; - const finalVotes = forVotes - againstVotes; - const votes = Number(formatEther(finalVotes)); - const existingProposal = listProposalsData.find(proposal => proposal.id === pickedProposal); + const forVotes = voteResponse[0] as bigint; + const againstVotes = voteResponse[1] as bigint; + const finalVotes = forVotes - againstVotes; + const votes = Number(formatEther(finalVotes)); + const existingProposal = listProposalsData.find(proposal => proposal.id === pickedProposal); - if (existingProposal) { - updateProposal( - { - ...existingProposal, - netVotes: votes, - }, - listProposalsData, - ); - } + if (existingProposal) { + updateProposal( + { + ...existingProposal, + netVotes: votes, + }, + listProposalsData, + ); } await updateCurrentUserVotes(abi, version, anyoneCanVote); diff --git a/packages/react-app-revamp/hooks/useContest/index.ts b/packages/react-app-revamp/hooks/useContest/index.ts index 56b325053..f7deb8ed1 100644 --- a/packages/react-app-revamp/hooks/useContest/index.ts +++ b/packages/react-app-revamp/hooks/useContest/index.ts @@ -64,7 +64,6 @@ export function useContest() { setVotesClose, setVotesOpen, setSubmissionsOpen, - setCanUpdateVotesInRealTime, setCharge, setVotingRequirements, setContestAbi, @@ -206,27 +205,6 @@ export function useContest() { setDownvotingAllowed(isDownvotingAllowed); setContestState(contestState); - // We want to track VoteCast event only 2H before the end of the contest, and only if alchemy support is enabled and if alchemy is configured - if (isBefore(new Date(), closingVoteDate) && alchemyRpc && isAlchemyConfigured) { - if (differenceInMinutes(closingVoteDate, new Date()) <= 120) { - setCanUpdateVotesInRealTime(true); - } else { - setCanUpdateVotesInRealTime(false); - - let delayBeforeVotesCanBeUpdated = - differenceInMilliseconds(closingVoteDate, new Date()) - minutesToMilliseconds(120); - - // Cap the delay at the maximum allowable value to prevent overflow - delayBeforeVotesCanBeUpdated = Math.min(delayBeforeVotesCanBeUpdated, MAX_MS_TIMEOUT); - - setTimeout(() => { - setCanUpdateVotesInRealTime(true); - }, delayBeforeVotesCanBeUpdated); - } - } else { - setCanUpdateVotesInRealTime(false); - } - setError(null); setIsSuccess(true); setIsLoading(false); diff --git a/packages/react-app-revamp/hooks/useContest/store.tsx b/packages/react-app-revamp/hooks/useContest/store.tsx index 20685d274..922258fd6 100644 --- a/packages/react-app-revamp/hooks/useContest/store.tsx +++ b/packages/react-app-revamp/hooks/useContest/store.tsx @@ -26,7 +26,6 @@ export interface ContestState { contestMaxProposalCount: number; downvotingAllowed: boolean; sortingEnabled: boolean; - canUpdateVotesInRealTime: boolean; supportsRewardsModule: boolean; submissionMerkleRoot: string; votingMerkleRoot: string; @@ -40,7 +39,6 @@ export interface ContestState { rewardsAbi: Abi | null; canEditTitleAndDescription: boolean; setSupportsRewardsModule: (value: boolean) => void; - setCanUpdateVotesInRealTime: (value: boolean) => void; setDownvotingAllowed: (isAllowed: boolean) => void; setSortingEnabled: (isAllowed: boolean) => void; setContestPrompt: (prompt: string) => void; @@ -87,7 +85,6 @@ export const createContestStore = () => contestMaxProposalCount: 0, downvotingAllowed: false, sortingEnabled: false, - canUpdateVotesInRealTime: false, votingRequirements: null, submissionRequirements: null, isV3: false, @@ -99,7 +96,6 @@ export const createContestStore = () => rewardsAbi: null, canEditTitleAndDescription: false, setSupportsRewardsModule: value => set({ supportsRewardsModule: value }), - setCanUpdateVotesInRealTime: value => set({ canUpdateVotesInRealTime: value }), setDownvotingAllowed: isAllowed => set({ downvotingAllowed: isAllowed }), setSortingEnabled: isAllowed => set({ sortingEnabled: isAllowed }), setContestPrompt: prompt => set({ contestPrompt: prompt }), diff --git a/packages/react-app-revamp/hooks/useContestEvents/index.ts b/packages/react-app-revamp/hooks/useContestEvents/index.ts deleted file mode 100644 index 54bcf7898..000000000 --- a/packages/react-app-revamp/hooks/useContestEvents/index.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { chains, config } from "@config/wagmi"; -import DeployedContestContract from "@contracts/bytecodeAndAbi/Contest.sol/Contest.json"; -import { getEthersProvider } from "@helpers/ethers"; -import { extractPathSegments } from "@helpers/extractPath"; -import isUrlToImage from "@helpers/isUrlToImage"; -import { useContestStore } from "@hooks/useContest/store"; -import { ContestStatus, useContestStatusStore } from "@hooks/useContestStatus/store"; -import useProposal from "@hooks/useProposal"; -import { useProposalStore } from "@hooks/useProposal/store"; -import useTotalVotesCastOnContest from "@hooks/useTotalVotesCastOnContest"; -import { readContract, watchContractEvent } from "@wagmi/core"; -import { usePathname } from "next/navigation"; -import { useEffect, useRef, useState } from "react"; -import { formatEther } from "viem"; - -export function useContestEvents() { - const asPath = usePathname(); - const { address: contestAddress, chainName } = extractPathSegments(asPath ?? ""); - const chainId = chains.filter( - (chain: { name: string }) => chain.name.toLowerCase().replace(" ", "") === chainName, - )?.[0]?.id; - const provider = getEthersProvider(config, { chainId }); - const { canUpdateVotesInRealTime } = useContestStore(state => state); - const { retry: refetchTotalVotesCastOnContest } = useTotalVotesCastOnContest(contestAddress, chainId); - const { contestStatus } = useContestStatusStore(state => state); - const { updateProposal } = useProposal(); - const { setProposalData, listProposalsData } = useProposalStore(state => state); - const [displayReloadBanner, setDisplayReloadBanner] = useState(false); - const contestStatusRef = useRef(contestStatus); - const listProposalsDataRef = useRef(listProposalsData); - - useEffect(() => { - listProposalsDataRef.current = listProposalsData; - }, [listProposalsData]); - - /** - * Callback function triggered on "VoteCast" event - * @param args - Array of the following values: from, to, value, event|event[] - */ - async function onVoteCast(args: Array) { - try { - const proposalId = args[0].args.proposalId.toString(); - - const votesRaw = (await readContract(config, { - address: contestAddress as `0x${string}`, - abi: DeployedContestContract.abi, - functionName: "proposalVotes", - args: [proposalId], - })) as bigint[]; - - const forVotesBigInt = votesRaw[0]; - const againstVotesBigInt = votesRaw[1]; - - const finalVotes = forVotesBigInt - againstVotesBigInt; - const votes = Number(formatEther(finalVotes)); - - const proposal = listProposalsDataRef.current.find(p => p.id === proposalId); - - if (proposal) { - updateProposal( - { - ...proposal, - netVotes: votes, - }, - listProposalsDataRef.current, - ); - } else { - const proposal = (await readContract(config, { - address: contestAddress as `0x${string}`, - abi: DeployedContestContract.abi, - functionName: "getProposal", - args: [proposalId], - })) as any; - - const proposalData: any = { - id: proposalId, - authorEthereumAddress: proposal.author, - content: proposal.description, - isContentImage: isUrlToImage(proposal.description) ? true : false, - exists: proposal.exists, - votes, - }; - - setProposalData(proposalData); - } - - refetchTotalVotesCastOnContest(); - } catch (e) { - console.error(e); - } - } - - useEffect(() => { - contestStatusRef.current = contestStatus; - }, [contestStatus]); - - useEffect(() => { - if (!canUpdateVotesInRealTime || ContestStatus.VotingOpen !== contestStatus) { - provider.removeAllListeners("VoteCast"); - setDisplayReloadBanner(false); - } else { - if (ContestStatus.VotingOpen === contestStatus && canUpdateVotesInRealTime) { - watchContractEvent(config, { - address: contestAddress as `0x${string}`, - abi: DeployedContestContract.abi, - eventName: "VoteCast", - onLogs: eventLogs => { - onVoteCast(eventLogs).catch(err => console.log(err)); - }, - }); - } - } - - return () => { - provider.removeAllListeners("VoteCast"); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [contestStatus, canUpdateVotesInRealTime]); - - function onVisibilityChangeHandler() { - if (document.visibilityState === "hidden") { - provider.removeAllListeners(); - - if (contestStatusRef.current === ContestStatus.VotingOpen && canUpdateVotesInRealTime) { - setDisplayReloadBanner(true); - } - return; - } else { - if (contestStatusRef.current === ContestStatus.VotingOpen && canUpdateVotesInRealTime) { - provider.addListener("VoteCast", (...args) => { - onVoteCast(args); - }); - } - } - } - - useEffect(() => { - document.addEventListener("visibilitychange", onVisibilityChangeHandler); - return () => { - document.removeEventListener("visibilitychange", onVisibilityChangeHandler); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [canUpdateVotesInRealTime]); - - return { - displayReloadBanner, - }; -} - -export default useContestEvents; diff --git a/packages/react-app-revamp/hooks/useProposal/store.tsx b/packages/react-app-revamp/hooks/useProposal/store.tsx index 473108c5f..f553da064 100644 --- a/packages/react-app-revamp/hooks/useProposal/store.tsx +++ b/packages/react-app-revamp/hooks/useProposal/store.tsx @@ -38,7 +38,6 @@ interface ProposalState { totalPagesPaginationProposals: number; currentPagePaginationProposals: number; hasPaginationProposalsNextPage: boolean; - canUpdateVotesInRealTime: boolean; submissionsCount: number; sortBy: SortOptions | null; addProposalId: (id: string) => void; @@ -56,7 +55,6 @@ interface ProposalState { setTotalPagesPaginationProposals: (value: number) => void; setCurrentPagePaginationProposals: (value: number) => void; setHasPaginationProposalsNextPage: (value: boolean) => void; - setCanUpdateVotesInRealTime: (value: boolean) => void; setSortBy: (sortBy: SortOptions | null) => void; } @@ -75,7 +73,6 @@ export const createProposalStore = () => totalPagesPaginationProposals: 0, currentPagePaginationProposals: 0, hasPaginationProposalsNextPage: false, - canUpdateVotesInRealTime: false, submissionsCount: 0, sortBy: null, setSubmissionsCount: value => set({ submissionsCount: value }), @@ -93,7 +90,6 @@ export const createProposalStore = () => setTotalPagesPaginationProposals: newTotal => set({ totalPagesPaginationProposals: newTotal }), setHasPaginationProposalsNextPage: hasNextPage => set({ hasPaginationProposalsNextPage: hasNextPage }), addProposalId: id => set(state => ({ listProposalsIds: [...state.listProposalsIds, id] })), - setCanUpdateVotesInRealTime: value => set({ canUpdateVotesInRealTime: value }), setIsListProposalsLoading: value => set({ isListProposalsLoading: value }), setIsListProposalsError: value => set({ isListProposalsError: value }), setIsListProposalsSuccess: value => set({ isListProposalsSuccess: value }), diff --git a/packages/react-app-revamp/layouts/LayoutViewContest/index.tsx b/packages/react-app-revamp/layouts/LayoutViewContest/index.tsx index 1ae702b0d..a5256afa0 100644 --- a/packages/react-app-revamp/layouts/LayoutViewContest/index.tsx +++ b/packages/react-app-revamp/layouts/LayoutViewContest/index.tsx @@ -24,7 +24,6 @@ import { ArrowPathIcon } from "@heroicons/react/24/outline"; import { useAccountChange } from "@hooks/useAccountChange"; import { ContractConfig, useContest } from "@hooks/useContest"; import { useContestStore } from "@hooks/useContest/store"; -import useContestEvents from "@hooks/useContestEvents"; import { ContestStatus, useContestStatusStore } from "@hooks/useContestStatus/store"; import useUser from "@hooks/useUser"; import moment from "moment"; @@ -59,7 +58,6 @@ const LayoutViewContest = ({ children }: { children: React.ReactNode }) => { const accountChanged = useAccountChange(); const { checkIfCurrentUserQualifyToVote, checkIfCurrentUserQualifyToSubmit } = useUser(); const { setContestStatus } = useContestStatusStore(state => state); - const { displayReloadBanner } = useContestEvents(); const [tab, setTab] = useState(Tab.Contest); const isMobile = useMediaQuery({ maxWidth: 768 }); const bugReportLink = populateBugReportLink(url?.href ?? "", accountAddress ?? "", error ?? ""); @@ -202,17 +200,6 @@ const LayoutViewContest = ({ children }: { children: React.ReactNode }) => { <> {isSuccess && !error && !isLoading && ( <> - {displayReloadBanner && ( -
-
- Let's refresh! -

Looks like live updates were frozen.

-
- window.location.reload()}> - Refresh - -
- )}