Bladeren bron

Merge branch 'iznik' into joy-proposals-upgrade

Leszek Wiesner 4 jaren geleden
bovenliggende
commit
1b649937b7

+ 3 - 11
pioneer/packages/joy-proposals/src/Proposal/ProposalDetails.tsx

@@ -5,14 +5,13 @@ import Body from './Body';
 import VotingSection from './VotingSection';
 import Votes from './Votes';
 import { MyAccountProps, withMyAccount } from '@polkadot/joy-utils/react/hocs/accounts';
-import { ParsedProposal, ProposalVotes } from '@polkadot/joy-utils/types/proposals';
+import { ParsedProposal } from '@polkadot/joy-utils/types/proposals';
 import { withCalls } from '@polkadot/react-api';
 import { withMulti } from '@polkadot/react-api/hoc';
 import { ProposalId, ProposalDecisionStatuses, ApprovedProposalStatuses, ExecutionFailedStatus } from '@joystream/types/proposals';
 import { BlockNumber } from '@polkadot/types/interfaces';
 import { MemberId } from '@joystream/types/members';
 import { Seat } from '@joystream/types/council';
-import PromiseComponent from '@polkadot/joy-utils/react/components/PromiseComponent';
 import ProposalDiscussion from './discussion/ProposalDiscussion';
 
 import styled from 'styled-components';
@@ -113,7 +112,6 @@ export function getExtendedStatus (proposal: ParsedProposal, bestNumber: BlockNu
 type ProposalDetailsProps = MyAccountProps & {
   proposal: ParsedProposal;
   proposalId: ProposalId;
-  votesListState: { data: ProposalVotes | null; error: any; loading: boolean };
   bestNumber?: BlockNumber;
   council?: Seat[];
 };
@@ -125,8 +123,7 @@ function ProposalDetails ({
   myMemberId,
   iAmMember,
   council,
-  bestNumber,
-  votesListState
+  bestNumber
 }: ProposalDetailsProps) {
   const iAmCouncilMember = Boolean(iAmMember && council && council.some(seat => seat.member.toString() === myAddress));
   const iAmProposer = Boolean(iAmMember && myMemberId !== undefined && proposal.proposerId === myMemberId.toNumber());
@@ -154,12 +151,7 @@ function ProposalDetails ({
               memberId={ myMemberId as MemberId }
               isVotingPeriod={ isVotingPeriod }/>
           ) }
-          <PromiseComponent
-            error={votesListState.error}
-            loading={votesListState.loading}
-            message="Fetching the votes...">
-            <Votes votes={votesListState.data as ProposalVotes} />
-          </PromiseComponent>
+          <Votes proposal={proposal}/>
         </ProposalDetailsVoting>
       </ProposalDetailsMain>
       <ProposalDetailsDiscussion>

+ 2 - 2
pioneer/packages/joy-proposals/src/Proposal/ProposalFromId.tsx

@@ -13,14 +13,14 @@ export default function ProposalFromId (props: RouteComponentProps<any>) {
   } = props;
   const { api } = useApi();
 
-  const { proposal: proposalState, votes: votesState } = useProposalSubscription(api.createType('ProposalId', id));
+  const proposalState = useProposalSubscription(api.createType('ProposalId', id));
 
   return (
     <PromiseComponent
       error={proposalState.error}
       loading={proposalState.loading}
       message={'Fetching proposal...'}>
-      <ProposalDetails proposal={ proposalState.data } proposalId={ id } votesListState={ votesState }/>
+      <ProposalDetails proposal={ proposalState.data } proposalId={ id }/>
     </PromiseComponent>
   );
 }

+ 53 - 36
pioneer/packages/joy-proposals/src/Proposal/Votes.tsx

@@ -1,50 +1,67 @@
 import React from 'react';
 import { Header, Divider, Table, Icon } from 'semantic-ui-react';
 import useVoteStyles from './useVoteStyles';
-import { ProposalVotes } from '@polkadot/joy-utils/types/proposals';
 import { VoteKind } from '@joystream/types/proposals';
 import { VoteKindStr } from './VotingSection';
 import ProfilePreview from '@polkadot/joy-utils/react/components/MemberProfilePreview';
+import { useTransport, usePromise } from '@polkadot/joy-utils/react/hooks';
+import { ParsedProposal, ProposalVotes } from '@polkadot/joy-utils/types/proposals';
+import PromiseComponent from '@polkadot/joy-utils/react/components/PromiseComponent';
 
 type VotesProps = {
-  votes: ProposalVotes;
+  proposal: ParsedProposal;
 };
 
-export default function Votes ({ votes }: VotesProps) {
-  if (!votes.votes.length) {
-    return <Header as="h4">No votes have been submitted!</Header>;
-  }
+export default function Votes ({ proposal: { id, votingResults } }: VotesProps) {
+  const transport = useTransport();
+  const [votes, error, loading] = usePromise<ProposalVotes | null>(
+    () => transport.proposals.votes(id),
+    null,
+    [votingResults]
+  );
 
   return (
-    <>
-      <Header as="h3">
-        All Votes: ({votes.votes.length}/{votes.councilMembersLength})
-      </Header>
-      <Divider />
-      <Table basic="very">
-        <Table.Body>
-          {votes.votes.map((proposalVote, idx) => {
-            const { vote, member } = proposalVote;
-            const voteStr = (vote as VoteKind).type.toString() as VoteKindStr;
-            const { icon, textColor } = useVoteStyles(voteStr);
-            return (
-              <Table.Row key={`${member.handle}-${idx}`}>
-                <Table.Cell className={textColor}>
-                  <Icon name={icon} />
-                  {voteStr}
-                </Table.Cell>
-                <Table.Cell>
-                  <ProfilePreview
-                    handle={member.handle}
-                    avatar_uri={member.avatar_uri}
-                    root_account={member.root_account}
-                  />
-                </Table.Cell>
-              </Table.Row>
-            );
-          })}
-        </Table.Body>
-      </Table>
-    </>
+    <PromiseComponent
+      error={error}
+      loading={loading}
+      message="Fetching the votes...">
+      { (votes && votes.votes.length > 0)
+        ? (
+          <>
+            <Header as="h3">
+              All Votes: ({votes.votes.length}/{votes.councilMembersLength})
+            </Header>
+            <Divider />
+            <Table basic="very">
+              <Table.Body>
+                {votes.votes.map((proposalVote, idx) => {
+                  const { vote, member } = proposalVote;
+                  const voteStr = (vote as VoteKind).type.toString() as VoteKindStr;
+                  const { icon, textColor } = useVoteStyles(voteStr);
+                  return (
+                    <Table.Row key={`${member.handle}-${idx}`}>
+                      <Table.Cell className={textColor}>
+                        <Icon name={icon} />
+                        {voteStr}
+                      </Table.Cell>
+                      <Table.Cell>
+                        <ProfilePreview
+                          handle={member.handle}
+                          avatar_uri={member.avatar_uri}
+                          root_account={member.root_account}
+                        />
+                      </Table.Cell>
+                    </Table.Row>
+                  );
+                })}
+              </Table.Body>
+            </Table>
+          </>
+        )
+        : (
+          <Header as="h4">No votes have been submitted!</Header>
+        )
+      }
+    </PromiseComponent>
   );
 }

+ 1 - 1
pioneer/packages/joy-roles/src/transport.substrate.ts

@@ -548,7 +548,7 @@ export class Transport extends TransportBase implements ITransport {
   }
 
   async blockHash (height: number): Promise<string> {
-    const blockHash = await this.cachedApi.query.system.blockHash(height);
+    const blockHash = await this.api.rpc.chain.getBlockHash(height);
     return blockHash.toString();
   }
 

+ 27 - 26
pioneer/packages/joy-utils/src/react/hooks/proposals/useProposalSubscription.tsx

@@ -1,39 +1,41 @@
 import { useState, useEffect } from 'react';
-import { ParsedProposal, ProposalVotes } from '../../../types/proposals';
-import { useTransport, usePromise } from '../';
+import { useTransport } from '../';
 import { ProposalId } from '@joystream/types/proposals';
+import { ParsedProposal } from '@polkadot/joy-utils/types/proposals';
 
 // Take advantage of polkadot api subscriptions to re-fetch proposal data and votes
 // each time there is some runtime change in the proposal
 const useProposalSubscription = (id: ProposalId) => {
   const transport = useTransport();
-  // State holding an "unsubscribe method"
-  const [unsubscribeProposal, setUnsubscribeProposal] = useState<(() => void) | null>(null);
-
-  const [proposal, proposalError, proposalLoading, refreshProposal] = usePromise<ParsedProposal>(
-    () => transport.proposals.proposalById(id),
-    {} as ParsedProposal
-  );
-
-  const [votes, votesError, votesLoading, refreshVotes] = usePromise<ProposalVotes | null>(
-    () => transport.proposals.votes(id),
-    null
-  );
-
-  // Function to re-fetch the data using transport
-  const refreshProposalData = () => {
-    refreshProposal();
-    refreshVotes();
-  };
+  // State holding current proposal data
+  const [data, setData] = useState<ParsedProposal | null>(null);
+  const [error, setError] = useState<any>(null);
+  const [loading, setLoading] = useState<boolean>(true);
 
   useEffect(() => {
     // onMount...
     let unmounted = false;
+    let unsubscribeProposal: (() => void) | undefined;
+    const refreshProposalData = () => {
+      transport.proposals.proposalById(id)
+        .then(newData => {
+          if (!unmounted) {
+            setData(newData);
+            setLoading(false);
+          }
+        })
+        .catch(error => {
+          if (!unmounted) {
+            setError(error);
+            setLoading(false);
+          }
+        });
+    };
     // Create the subscription
     transport.proposals.subscribeProposal(id, refreshProposalData)
       .then(unsubscribe => {
         if (!unmounted) {
-          setUnsubscribeProposal(() => unsubscribe);
+          unsubscribeProposal = unsubscribe;
         } else {
           unsubscribe(); // If already unmounted - unsubscribe immedietally!
         }
@@ -42,14 +44,13 @@ const useProposalSubscription = (id: ProposalId) => {
       // onUnmount...
       // Clean the subscription
       unmounted = true;
-      if (unsubscribeProposal !== null) unsubscribeProposal();
+      if (unsubscribeProposal) {
+        unsubscribeProposal();
+      }
     };
   }, []);
 
-  return {
-    proposal: { data: proposal, error: proposalError, loading: proposalLoading },
-    votes: { data: votes, error: votesError, loading: votesLoading }
-  };
+  return { data, error, loading };
 };
 
 export default useProposalSubscription;

+ 2 - 2
yarn.lock

@@ -11565,7 +11565,7 @@ find-babel-config@^1.2.0:
     json5 "^0.5.1"
     path-exists "^3.0.0"
 
-find-cache-dir@^2.0.0, find-cache-dir@^2.1.0:
+find-cache-dir@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7"
   integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==
@@ -19164,7 +19164,7 @@ pirates@^3.0.2:
   dependencies:
     node-modules-regexp "^1.0.0"
 
-pirates@^4.0.0, pirates@^4.0.1:
+pirates@^4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87"
   integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==