Browse Source

show votes per council member

Joystream Stats 4 years ago
parent
commit
d09c82f54a
3 changed files with 93 additions and 8 deletions
  1. 60 2
      src/App.tsx
  2. 31 5
      src/components/Proposals/Row.tsx
  3. 2 1
      src/types.ts

+ 60 - 2
src/App.tsx

@@ -13,6 +13,7 @@ import { types } from "@joystream/types";
 import { Seat } from "@joystream/types/augment/all/types";
 import { ApiPromise, WsProvider } from "@polkadot/api";
 import { AccountId, Header } from "@polkadot/types/interfaces";
+import { MemberId, Membership } from "@joystream/types/members";
 
 interface IProps {}
 
@@ -122,6 +123,61 @@ class App extends React.Component<IProps, IState> {
     if (!proposal) return;
     proposals[id] = proposal;
     this.save("proposals", proposals);
+    this.fetchVotesPerProposal(api, id);
+  }
+
+  async fetchVotesPerProposal(api: Api, proposalId: number) {
+    const { proposals } = this.state;
+    const proposal = proposals.find((p) => p && p.id === proposalId);
+    if (!proposal) return;
+    const { id, createdAt, votes } = proposal;
+
+    //let totalVotes = 0;
+    //Object.keys(votes).map((key) => (totalVotes += votes[key]));
+
+    const council = this.getCouncilAtBlock(createdAt);
+
+    proposal.votesByMember = await Promise.all(
+      council.map(async (seat: Seat) => {
+        const memberId = await this.getMemberIdByAccount(api, seat.member);
+        const handle = await this.getHandleByAccount(api, seat.member);
+        const vote = await this.fetchVoteByProposalByVoter(api, id, memberId);
+        return { vote: String(vote), account: seat.member, handle };
+      })
+    );
+    proposals[id] = proposal;
+    this.save("proposals", proposals);
+  }
+
+  async fetchVoteByProposalByVoter(
+    api: Api,
+    proposalId: number,
+    memberId: MemberId
+  ) {
+    //const councilPerBlock
+    const vote = await api.query.proposalsEngine.voteExistsByProposalByVoter(
+      proposalId,
+      memberId
+    );
+    return vote.toHuman();
+  }
+
+  getCouncilAtBlock(block: number) {
+    // TODO
+    return this.state.council;
+  }
+
+  async getHandleByAccount(api: Api, accountId: AccountId): Promise<string> {
+    return await this.fetchHandle(api, accountId);
+  }
+  async getMemberIdByAccount(
+    api: Api,
+    accountId: AccountId
+  ): Promise<MemberId> {
+    const id: MemberId = await api.query.members.memberIdsByRootAccountId(
+      accountId
+    );
+    return id;
   }
 
   async fetchNominators(api: Api) {
@@ -141,13 +197,15 @@ class App extends React.Component<IProps, IState> {
     });
     this.save("validators", validators);
   }
-  async fetchHandle(api: Api, id: AccountId | string) {
+  async fetchHandle(api: Api, id: AccountId | string): Promise<string> {
     let { handles } = this.state;
-    if (handles[String(id)]) return;
+    const exists = handles[String(id)];
+    if (exists) return exists;
 
     const handle = await get.memberHandleByAccount(api, id);
     handles[String(id)] = handle;
     this.save("handles", handles);
+    return handle;
   }
   async fetchReports() {
     const domain = `https://raw.githubusercontent.com/Joystream/community-repo/master/council-reports`;

+ 31 - 5
src/components/Proposals/Row.tsx

@@ -62,11 +62,37 @@ const ProposalRow = (props: any) => {
         </OverlayTrigger>
       </td>
 
-      <td className={color}>
-        <b>{result}</b>
-        <br />
-        {votes.join(" / ")}
-      </td>
+      <OverlayTrigger
+        overlay={
+          <Tooltip id={id}>
+            <div>
+              {props.votesByMember ? (
+                <Table className="text-left text-light">
+                  <tbody>
+                    {props.votesByMember.map(
+                      (v: { handle: string; vote: string }) => (
+                        <tr key={`${id}-${v.handle}`}>
+                          <td>{v.handle}:</td>
+                          <td>{v.vote}</td>
+                        </tr>
+                      )
+                    )}
+                  </tbody>
+                </Table>
+              ) : (
+                `Fetching votes..`
+              )}
+            </div>
+          </Tooltip>
+        }
+      >
+        <td className={color}>
+          <b>{result}</b>
+          <br />
+          {votes.join(" / ")}
+        </td>
+      </OverlayTrigger>
+
       <td className="text-left  justify-content-center">
         <Bar
           id={id}

+ 2 - 1
src/types.ts

@@ -5,7 +5,7 @@ import {
   ProposalStatus,
   VotingResults,
 } from "@joystream/types/proposals";
-import { Nominations } from "@polkadot/types/interfaces";
+import { AccountId, Nominations } from "@polkadot/types/interfaces";
 import { Option } from "@polkadot/types/codec";
 import { StorageKey } from "@polkadot/types/primitive";
 
@@ -63,6 +63,7 @@ export interface ProposalDetail {
   description: any;
   votes: VotingResults;
   type: string;
+  votesByMember?: { vote: string; account: AccountId; handle: string }[];
 }
 
 export type ProposalArray = number[];