Skip to content

Commit

Permalink
Support cleanup poll for fellowship referenda, #5540 (#5549)
Browse files Browse the repository at this point in the history
* init FellowshipReferendumCleanupPoll component, #5540

* add context for CleanupPollButton, #5540

* add tx func, #5540

* chore: optimize fellowship core members list style, #5540

* optimize null guard, #5540

* optimize context & components, #5540

* rename, #5540

* add onInblock toast, #5540

* rename, #5540

* add sign popup, #5540

* use SignerWithBalance, #5540

* Improve feedback text, #5540

---------

Co-authored-by: Yongfeng LI <wliyongfeng@gmail.com>
  • Loading branch information
leocs2417 and wliyongfeng authored Feb 28, 2025
1 parent 8d70098 commit 26e8614
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export function AvatarAndAddressInListView({ address, isActive }) {
<AddressUser
add={address}
fontSize={14}
className="[&_.identity]:!font-semibold"
link={`/${section}`}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import Button from "next-common/lib/button";
import { useState, useMemo } from "react";
import Tooltip from "next-common/components/tooltip";
import ReferendumVotingProvider, {
useReferendumVoting,
} from "next-common/context/fellowship/referendumVoting";
import useRealAddress from "next-common/utils/hooks/useRealAddress";
import { useReferendumVotingFinishIndexer } from "next-common/context/post/referenda/useReferendumVotingFinishHeight";
import { isNil } from "lodash-es";
import { useOnchainData } from "next-common/context/post";
import dynamicPopup from "next-common/lib/dynamic/popup";

const CleanupPopup = dynamicPopup(() => import("./popup"));

function CleanupPollButton() {
const { votes, isLoading } = useReferendumVoting();
const address = useRealAddress();
const [showPopup, setShowPopup] = useState(false);

const showCleanup = useMemo(() => {
return votes?.length > 0 && !isLoading && address;
}, [votes, isLoading, address]);

if (!showCleanup) {
return null;
}

return (
<>
<Tooltip content="Clean up votes from storage, no gas">
<Button
className="w-full h-[40px] rounded-lg bg-neutral100 border border-neutral400"
onClick={() => setShowPopup(true)}
>
Cleanup Poll
</Button>
</Tooltip>
{showPopup && <CleanupPopup onClose={() => setShowPopup(false)} />}
</>
);
}

function MakesureReferendumFinishedGuard({ children }) {
const finishedIndexer = useReferendumVotingFinishIndexer();
const { referendumIndex } = useOnchainData();

if (isNil(finishedIndexer) || isNil(referendumIndex)) {
return null;
}

return children;
}

export default function FellowshipReferendumCleanupPoll() {
return (
<MakesureReferendumFinishedGuard>
<ReferendumVotingProvider>
<CleanupPollButton />
</ReferendumVotingProvider>
</MakesureReferendumFinishedGuard>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import TxSubmissionButton from "next-common/components/common/tx/txSubmissionButton";
import PopupWithSigner from "next-common/components/popupWithSigner";
import { usePopupParams } from "next-common/components/popupWithSigner/context";
import { useContextApi } from "next-common/context/api";
import { useRankedCollectivePallet } from "next-common/context/collectives/collectives";
import { useCallback, useState } from "react";
import { useReferendumVoting } from "next-common/context/fellowship/referendumVoting";
import { useOnchainData } from "next-common/context/post";
import { useDispatch } from "react-redux";
import { newSuccessToast } from "next-common/store/reducers/toastSlice";
import { fetchFellowshipReferendumVotes2Times } from "next-common/context/fellowship/referendumVoting";
import SignerWithBalance from "next-common/components/signerPopup/signerWithBalance";

const successToastContent =
"Votes in storage have been cleaned up successfully.";

function Content() {
const { onClose } = usePopupParams();
const api = useContextApi();
const pallet = useRankedCollectivePallet();
const { votes, fetch } = useReferendumVoting();
const { referendumIndex: pollIndex } = useOnchainData();
const dispatch = useDispatch();
const [isDisabled, setIsDisabled] = useState(false);

const getTxFunc = useCallback(() => {
if (!api || !pallet) {
return;
}

setIsDisabled(true);
return api?.tx?.[pallet]?.cleanupPoll(pollIndex, votes.length);
}, [api, pallet, pollIndex, votes]);

const onInBlock = useCallback(async () => {
dispatch(newSuccessToast(successToastContent));
await fetchFellowshipReferendumVotes2Times(fetch);
}, [dispatch, fetch]);

return (
<>
<SignerWithBalance />
<TxSubmissionButton
title="Confirm"
getTxFunc={getTxFunc}
onInBlock={onInBlock}
onSubmitted={onClose}
disabled={isDisabled}
/>
</>
);
}

export default function CleanupPopup({ onClose }) {
return (
<PopupWithSigner title="Cleanup Poll" onClose={onClose}>
<Content />
</PopupWithSigner>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ const rankColumn = {

const memberColumn = {
name: "Member",
width: 140,
className: "min-w-[140px]",
};

const salaryColumn = {
name: "Salary",
className: "text-right",
minWidth: 120,
width: 120,
};

const demotionPeriodColumn = {
Expand Down
75 changes: 75 additions & 0 deletions packages/next-common/context/fellowship/referendumVoting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import {
createContext,
useContext,
useCallback,
useEffect,
useState,
} from "react";
import { isNil } from "lodash-es";
import { useOnchainData } from "next-common/context/post";
import { useContextApi } from "next-common/context/api";
import { defaultBlockTime } from "next-common/utils/constants";
import { sleep } from "next-common/utils";
import { useRankedCollectivePallet } from "next-common/context/collectives/collectives";
import getChainSettings from "next-common/utils/consts/settings";

const ReferendumVotingContext = createContext();

function useFellowshipReferendumVotes() {
const api = useContextApi();
const [fellowshipVotes, setFellowshipVotes] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const pallet = useRankedCollectivePallet();
const { referendumIndex: pollIndex } = useOnchainData();

const fetch = useCallback(async () => {
if (!api || isNil(pollIndex) || !pallet) {
return;
}

try {
const votes = await api?.query?.[pallet]?.voting?.entries(pollIndex);
setFellowshipVotes(votes);
} catch (error) {
console.error("Failed to fetch fellowship votes:", error);
setFellowshipVotes([]);
} finally {
setIsLoading(false);
}
}, [api, pollIndex, pallet]);

useEffect(() => {
fetch();
}, [fetch]);

return {
votes: fellowshipVotes,
isLoading,
fetch,
};
}

export async function fetchFellowshipReferendumVotes2Times(fetch) {
const blockTime =
getChainSettings(process.env.NEXT_PUBLIC_CHAIN).blockTime ||
defaultBlockTime;

for (let i = 0; i < 2; i++) {
await fetch();
await sleep(blockTime);
}
}

export default function ReferendumVotingProvider({ children }) {
const { votes, isLoading, fetch } = useFellowshipReferendumVotes();

return (
<ReferendumVotingContext.Provider value={{ votes, isLoading, fetch }}>
{children}
</ReferendumVotingContext.Provider>
);
}

export function useReferendumVoting() {
return useContext(ReferendumVotingContext);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Tooltip from "next-common/components/tooltip";
import dynamic from "next/dynamic";
import AllSpendsRequest from "./request/allSpendsRequest";
import useRankedCollectiveMinRank from "next-common/hooks/collectives/useRankedCollectiveMinRank";
import FellowshipReferendumCleanupPoll from "next-common/components/fellowship/referenda/cleanupPoll";

const MyCollectiveVote = dynamic(
() => import("next-common/components/collectives/referenda/myCollectiveVote"),
Expand Down Expand Up @@ -85,6 +86,7 @@ export default function FellowshipReferendumSideBar() {
/>
)}
</VoteSuccessfulProvider>
<FellowshipReferendumCleanupPoll />
<InlineWrapper>
<HowOpenGovWorks anchor="polkadot-fellowship" />
</InlineWrapper>
Expand Down

0 comments on commit 26e8614

Please sign in to comment.