Skip to content

Commit

Permalink
Show whether I have voted a proposal on the list page, #1075 (#1077)
Browse files Browse the repository at this point in the history
* Show whether I have voted a proposal on the list page, #1075

* Simplify, #1075

* fix, #1075

* Update error text, #1075
  • Loading branch information
hyifeng authored Dec 30, 2024
1 parent 6c299fb commit 4ba0755
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const Router = require("koa-router");
const { getProposalById } = require("./getProposalById");
const { getUserVotesOfProposals } = require("./getUserVotesOfProposals");

const router = new Router();
router.get("/proposal/:proposalId", getProposalById);
router.get("/votes", getUserVotesOfProposals);

module.exports = router;
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const { HttpError } = require("../../exc");
const { getVoteCollection } = require("../../mongo");

async function getUserVotesOfProposals(ctx) {
const { network, address, proposal_cid: proposalCid } = ctx.query;

if (!proposalCid) {
throw new HttpError(400, "Query parameter proposal cid is required");
}

if (!network) {
throw new HttpError(400, "Query parameter network is required");
}

if (!address) {
throw new HttpError(400, "Query parameter address is required");
}

const proposalCids = proposalCid.split(",");

const q = {
"data.proposalCid": { $in: proposalCids },
voter: address,
voterNetwork: network,
};

const voteCol = await getVoteCollection();
const votes = await voteCol.find(q).toArray();

ctx.body = votes;
}

module.exports = {
getUserVotesOfProposals,
};
47 changes: 43 additions & 4 deletions next/components/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { p_16_semibold } from "styles/textStyles";
import StatusTag from "./statusTag";
import PostTime from "./postTime";
import { p_24 } from "../styles/paddings";
import { useEffect, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { useWindowSize } from "../frontedUtils/hooks";
import PostResult from "./postResult";
import { findNetworkConfig } from "../services/util";
import { Flex, FlexBetween } from "@osn/common-ui";
import { Flex, FlexBetween, Tooltip } from "@osn/common-ui";
import { p_14_medium } from "../styles/componentCss";
import { getSpaceIconUrl } from "frontedUtils/space";

Expand Down Expand Up @@ -59,6 +59,10 @@ const LeftWrapper = styled(Flex)`
}
`;

const RightWrapper = styled(Flex)`
gap: 8px;
`;

const FromSpace = styled(Flex)`
.ml-4px {
margin-left: 8px;
Expand All @@ -80,9 +84,41 @@ const TitleWrapper = styled(FlexBetween)`
align-items: flex-start;
`;

export default function Post({ data, showSpace, space }) {
function MyVoteMark({ proposal, myVote }) {
if (!myVote || !proposal) {
return null;
}

const getVoteIndex = (choice) =>
proposal.choices.findIndex((item) => item === choice) + 1;

const content = (
<div>
<span>Vote:</span>
<ul>
{myVote.choices.map((choice, index) => (
<li key={index}>
#{getVoteIndex(choice)}: {choice}
</li>
))}
</ul>
</div>
);

return (
<Tooltip content={content}>
<img src="/imgs/icons/my-vote-mark.svg" alt="" />
</Tooltip>
);
}

export default function Post({ data, showSpace, space, myVotes }) {
const windowSize = useWindowSize();
const [showRichInfo, setShowRichInfo] = useState(true);
const myVote = useMemo(
() => myVotes.find((item) => item.data.proposalCid === data.cid),
[myVotes, data.cid],
);

useEffect(() => {
if (windowSize.width <= 900) {
Expand Down Expand Up @@ -139,7 +175,10 @@ export default function Post({ data, showSpace, space }) {
</FromSpace>
)}
</LeftWrapper>
<StatusTag>{data.status}</StatusTag>
<RightWrapper>
<MyVoteMark proposal={data} myVote={myVote} />
<StatusTag>{data.status}</StatusTag>
</RightWrapper>
</InfoWrapper>
</Wrapper>
);
Expand Down
32 changes: 32 additions & 0 deletions next/components/postList.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import Post from "./post";
import { p_20_semibold } from "../styles/textStyles";
import Pagination from "@/components/pagination";
import NoData from "@osn/common-ui/es/NoData";
import { useEffect, useState } from "react";
import nextApi from "services/nextApi";
import { loginAccountSelector } from "store/reducers/accountSlice";
import { useSelector } from "react-redux";

const Title = styled.div`
${p_20_semibold};
Expand All @@ -16,6 +20,31 @@ const PostsWrapper = styled.div`
}
`;

function useMyVotes(proposals) {
const [myVotes, setMyVotes] = useState([]);
const account = useSelector(loginAccountSelector);
const voter = account?.address;
const voterNetwork = account?.network;

useEffect(() => {
if (!proposals || proposals?.length === 0 || !voter || !voterNetwork) {
return;
}

nextApi
.fetch("votes", {
address: voter,
network: voterNetwork,
proposalCid: proposals.map((p) => p.cid).join(","),
})
.then(({ result }) => {
setMyVotes(result || []);
});
}, [proposals, voter, voterNetwork]);

return myVotes;
}

export default function PostList({
title,
posts,
Expand All @@ -24,6 +53,8 @@ export default function PostList({
showSpace = false,
}) {
const items = Array.isArray(posts) ? posts : posts?.items ?? [];
const myVotes = useMyVotes(items);

return (
<div>
{title && <Title>{title}</Title>}
Expand All @@ -35,6 +66,7 @@ export default function PostList({
showSpace={showSpace}
space={space}
spaces={spaces}
myVotes={myVotes}
/>
))}
{items.length === 0 && <NoData message="No current active proposals" />}
Expand Down
3 changes: 3 additions & 0 deletions next/public/imgs/icons/my-vote-mark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 4ba0755

Please sign in to comment.