Procházet zdrojové kódy

fetch Councils ; TODO OPTIMIZE first load

Joystream Stats před 4 roky
rodič
revize
5c9e9798ff

+ 32 - 25
src/App.tsx

@@ -19,15 +19,6 @@ import { VoteKind } from "@joystream/types/proposals";
 
 interface IProps {}
 
-const councils = [
-  [129, 321, 439, 4, 2, 319],
-  [129, 318, 321, 4, 2, 319],
-  [495, 129, 321, 4, 2, 319],
-  [361, 129, 318, 321, 439, 319],
-  [361, 129, 321, 4, 2, 319],
-  [361, 129, 318, 321, 2, 319],
-];
-
 const version = 0.1;
 
 const initialState = {
@@ -40,8 +31,7 @@ const initialState = {
   validators: [],
   channels: [],
   posts: [],
-  council: [],
-  councils,
+  councils: [],
   categories: [],
   threads: [],
   proposals: [],
@@ -125,14 +115,10 @@ class App extends React.Component<IProps, IState> {
       }
     );
 
-    this.fetchCouncil(api);
+    this.fetchCouncils(api, round);
     this.fetchProposals(api);
     this.fetchValidators(api);
     this.fetchNominators(api);
-
-    councils.map((council) =>
-      council.map((seat) => this.fetchMember(api, seat))
-    );
   }
 
   async fetchTokenomics() {
@@ -142,11 +128,32 @@ class App extends React.Component<IProps, IState> {
     this.save("tokenomics", data);
   }
 
-  async fetchCouncil(api: Api) {
-    const council: any = await api.query.council.activeCouncil();
-    this.setState({ council });
-    this.save(`council`, council);
-    council.map((seat: Seat) => this.fetchMemberByAccount(api, seat.member));
+  async fetchCouncils(api: Api, currentRound: number) {
+    if (this.state.councils.length)
+      // TODO when to update
+      return this.state.councils.map((council) =>
+        council.map((seat) => this.fetchMember(api, seat))
+      );
+
+    let councils: number[][] = [];
+    const cycle = 201600; // TODO calculate cycle
+
+    for (let round = 0; round < currentRound; round++) {
+      let council: number[] = [];
+      const block = 57601 + round * cycle;
+      console.log(`fetching council at block ${block}`);
+
+      const blockHash = await api.rpc.chain.getBlockHash(block);
+      if (!blockHash) continue;
+      const seats: Seat[] = await api.query.council.activeCouncil.at(blockHash);
+
+      seats.forEach(async (seat) => {
+        const member = await this.fetchMemberByAccount(api, seat.member);
+        council = council.concat(Number(member.id));
+        councils[round] = council;
+        this.save("councils", councils);
+      });
+    }
   }
 
   // proposals
@@ -330,9 +337,9 @@ class App extends React.Component<IProps, IState> {
     this.updateHandles(members);
     this.setState({ members });
   }
-  loadCouncil() {
-    const council = this.load("council");
-    if (council) this.setState({ council });
+  loadCouncils() {
+    const councils = this.load("councils");
+    if (councils) this.setState({ councils });
   }
   loadProposals() {
     const proposals = this.load("proposals");
@@ -377,7 +384,7 @@ class App extends React.Component<IProps, IState> {
     if (lastVersion !== version) return this.clearData();
     console.log(`Loading data`);
     await this.loadMembers();
-    await this.loadCouncil();
+    await this.loadCouncils();
     await this.loadProposals();
     await this.loadThreads();
     await this.loadValidators();

+ 1 - 0
src/components/Council/ElectionStatus.tsx

@@ -5,6 +5,7 @@ const ElectionStage = (props: any) => {
   const { block, stage, termEndsAt } = props;
 
   if (!stage) {
+    if (!block) return <div />;
     const blocks = termEndsAt - block;
     const seconds = blocks * 6;
     const days = Math.floor(seconds / 86400);

+ 19 - 14
src/components/Council/index.tsx

@@ -2,37 +2,42 @@ import React from "react";
 import { Link } from "react-router-dom";
 import ElectionStatus from "./ElectionStatus";
 import User from "../User";
-import { Seat } from "../../types";
 import Loading from "../Loading";
 
+const Member = (props: { id: number; findHandle: (id: number) => string }) => {
+  const handle = props.findHandle(props.id);
+  return (
+    <div className="col">
+      <User id={handle} handle={handle} />
+    </div>
+  );
+};
+
 const Council = (props: {
-  council: Seat[];
-  handles: { [key: string]: string };
+  findHandle: (id: number) => string;
+  council: number[];
   councilElection?: any;
   block: number;
 }) => {
-  const { council, handles, block, councilElection } = props;
+  const { findHandle, council, block, councilElection } = props;
   const half = Math.floor(council.length / 2);
+  const show = council.length;
 
   return (
     <div className="box">
-      <ElectionStatus block={block} councilElection={councilElection} />
+      <ElectionStatus show={show} block={block} {...councilElection} />
       <h3>Council</h3>
 
-      {(council.length && (
+      {(show && (
         <div className="d-flex flex-column">
           <div className="d-flex flex-row">
-            {council.slice(0, half).map((seat: Seat) => (
-              <div key={String(seat.member)} className="col">
-                <User id={String(seat.member)} handle={handles[String(seat.member)]} />
-              </div>
+            {council.slice(0, half).map((id) => (
+              <Member key={String(id)} id={id} findHandle={findHandle} />
             ))}
           </div>
           <div className="d-flex flex-row">
-            {council.slice(half).map((seat: Seat) => (
-              <div key={String(seat.member)} className="col">
-                <User id={String(seat.member)} handle={handles[String(seat.member)]} />
-              </div>
+            {council.slice(half).map((id) => (
+              <Member key={String(id)} id={id} findHandle={findHandle} />
             ))}
           </div>
         </div>

+ 8 - 2
src/components/Dashboard/index.tsx

@@ -7,7 +7,13 @@ import Loading from "../Loading";
 import { IState } from "../../types";
 
 const Dashboard = (props: IState) => {
-  const { block, council, domain, handles, proposals } = props;
+  const { block, councils, domain, handles, members, proposals } = props;
+  const council = councils[councils.length - 1];
+
+  const findHandle = (id: number) => {
+    const member = members.find((m) => m.id === id);
+    return member ? member.handle : String(id);
+  };
 
   return (
     <div className="w-100 flex-grow-1 d-flex align-items-center justify-content-center d-flex flex-column">
@@ -28,8 +34,8 @@ const Dashboard = (props: IState) => {
       </div>
 
       <Council
+        findHandle={findHandle}
         council={council}
-        handles={handles}
         councilElection={props.councilElection}
         block={block}
       />

+ 2 - 9
src/components/Routes/index.tsx

@@ -1,12 +1,5 @@
 import { Switch, Route } from "react-router-dom";
-import {
-  Council,
-  Councils,
-  Dashboard,
-  Proposals,
-  Proposal,
-  Tokenomics,
-} from "..";
+import { Councils, Dashboard, Proposals, Proposal, Tokenomics } from "..";
 import { IState } from "../../types";
 
 const Routes = (props: IState) => {
@@ -23,7 +16,7 @@ const Routes = (props: IState) => {
       />
       <Route path="/proposals" render={() => <Proposals {...props} />} />
       <Route path="/councils" render={() => <Councils {...props} />} />
-      <Route path="/council" render={() => <Council {...props} />} />
+
       <Route path="/" render={() => <Dashboard {...props} />} />
     </Switch>
   );

+ 1 - 1
src/types.ts

@@ -11,6 +11,7 @@ import { StorageKey } from "@polkadot/types/primitive";
 
 export interface Api {
   query: any;
+  rpc: any;
 }
 
 export interface IState {
@@ -21,7 +22,6 @@ export interface IState {
   nominators: string[];
   validators: string[];
   loading: boolean;
-  council: Seat[];
   councils: number[][];
   councilElection?: { stage: any; round: number; termEndsAt: number };
   channels: number[];