Skip to content
This repository has been archived by the owner on Sep 22, 2021. It is now read-only.

Using council members from chain db rather than onchain. #814

Merged
merged 91 commits into from
Jun 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
38f11e1
Added vote tables
niklabh May 15, 2020
e0183a1
Added permissions
niklabh May 15, 2020
f31ad97
Added votes post relationship
niklabh May 15, 2020
5d11d81
Added UI
niklabh May 17, 2020
b41d60a
Added Offchain Poll
niklabh May 17, 2020
89c0489
Everything works
niklabh May 17, 2020
f3c68c0
onchain only
niklabh May 17, 2020
80b24ab
removed console
niklabh May 17, 2020
92b9d11
Merge branch 'master' into niklabh-feature-vote
Tbaut May 18, 2020
5a38601
using default address field
niklabh May 18, 2020
ccabda6
removed span
niklabh May 18, 2020
3de33f8
Merge branch 'master' into niklabh-feature-vote
niklabh May 25, 2020
d8f156f
Split useEffect
niklabh May 25, 2020
6b77498
Using encoded address
niklabh May 25, 2020
febe898
&& instead of ?
niklabh May 25, 2020
c8d3ee1
Using use callback
niklabh May 25, 2020
0d8c981
Box shadow
niklabh May 25, 2020
004af73
conditional component dispaly
niklabh May 25, 2020
5419860
comment
niklabh May 25, 2020
dc3c4d9
Using enum
niklabh May 25, 2020
f646b36
Added own vote
niklabh May 25, 2020
064e898
Added check of has_poll on create post itself
niklabh May 25, 2020
3780868
Added check of has_poll on create post itself
niklabh May 25, 2020
716c309
Merge branch 'master' into niklabh-feature-vote
niklabh May 25, 2020
a56e8d0
box-shadow fix
erler May 25, 2020
33f5039
Update front-end/src/ui-components/CouncilSignalBar.tsx
niklabh May 26, 2020
02dbf54
Update front-end/src/components/Post/Poll/CouncilSignals.tsx
niklabh May 26, 2020
a8b226d
Update front-end/src/ui-components/OffChainSignalBar.tsx
niklabh May 26, 2020
4eb17fa
Merge branch 'master' into niklabh-feature-vote
niklabh May 26, 2020
a7e0b29
Merge branch 'master' into niklabh-feature-vote
Tbaut May 26, 2020
d2d018c
Merge branch 'master' into niklabh-feature-vote
niklabh May 27, 2020
98406bd
Adding address of council if it exist
niklabh May 27, 2020
d5c1ccf
checking defaultAddress not empty string
niklabh May 27, 2020
4aa5518
renamed OffChainSignals -> GeneralSignals
niklabh May 27, 2020
836563a
Commented poll
niklabh May 27, 2020
6649cda
lint
niklabh May 27, 2020
73fc7e3
Update front-end/src/ui-components/CouncilSignalBar.tsx
niklabh May 27, 2020
32d7932
fix table setup
Tbaut May 27, 2020
21c7947
Merge branch 'niklabh-feature-vote' of github.com:paritytech/polkasse…
Tbaut May 27, 2020
1368467
Using council members from chain db rather than onchain. Showing old …
niklabh May 27, 2020
0ec411d
Merge master
niklabh May 27, 2020
d6a89a8
< 2 check
niklabh May 27, 2020
e59b226
Signal percentage
erler May 27, 2020
d3e801f
Merge branch 'niklabh-feature-vote' of https://github.com/paritytech/…
erler May 27, 2020
90cfa49
Helpertooltip next to title
erler May 27, 2020
6f2066d
Update front-end/src/components/Post/Poll/CouncilSignals.tsx
niklabh May 27, 2020
cc79db7
Update front-end/src/components/Post/Poll/GeneralSignals.tsx
niklabh May 27, 2020
bb0c2e7
Merge branch 'master' into niklabh-feature-vote
niklabh May 27, 2020
f64da0a
Added checkbox
niklabh May 27, 2020
3205b90
fix
niklabh May 27, 2020
2c22100
Merge branch 'master' into niklabh-feature-vote
Tbaut May 28, 2020
ed71102
Fix ayes nays
niklabh May 29, 2020
36848ac
Cancel poll vote interaction (#815)
erler May 30, 2020
215b01e
Merge branch 'master' into niklabh-feature-vote
Tbaut Jun 2, 2020
e04d769
use type guard and avoid over fetching
Tbaut Jun 2, 2020
a5f1c2c
comment out Poll
Tbaut Jun 2, 2020
b21bf8a
lint
Tbaut Jun 2, 2020
5b8695a
Merge poll feature branch
niklabh Jun 2, 2020
6c4beab
merge master
niklabh Jun 2, 2020
9a093d7
Merge branch 'master' into block-number-check
niklabh Jun 2, 2020
36b1237
Merge branch 'master' into block-number-check
niklabh Jun 3, 2020
a03b6a7
Merge branch 'master' into block-number-check
Tbaut Jun 5, 2020
670fe67
Merge branch 'master' into block-number-check
niklabh Jun 6, 2020
678f788
changed block_number to poll_block_number_end
niklabh Jun 8, 2020
696f700
extracted reused code in function
niklabh Jun 8, 2020
ef206d8
Uncommented poll
niklabh Jun 8, 2020
76c5496
removed twoWeekBlocks
niklabh Jun 8, 2020
5e03e88
Calculating end block
niklabh Jun 8, 2020
ddda164
fix
niklabh Jun 8, 2020
21b5fc9
Merge branch 'master' into block-number-check
Tbaut Jun 8, 2020
e2ecdbf
Merge master
niklabh Jun 8, 2020
ef4e9b1
Merge branch 'master' into block-number-check
Tbaut Jun 8, 2020
6bce7d4
Added blocktime context
niklabh Jun 8, 2020
03bc0b2
using hook instead of context for getting block time
niklabh Jun 8, 2020
0eed4bf
Merge branch 'master' into block-number-check
niklabh Jun 8, 2020
d49b482
not using default 0
niklabh Jun 8, 2020
20c6df9
showing error on no block number
niklabh Jun 8, 2020
89d1df5
Merge branch 'master' into block-number-check
niklabh Jun 8, 2020
a86943b
Merge branch 'master' into block-number-check
niklabh Jun 9, 2020
472d1e1
Merge branch 'master' into block-number-check
niklabh Jun 9, 2020
9ed3947
Moved poll table
niklabh Jun 9, 2020
2d82fa1
Merge branch 'master' into block-number-check
niklabh Jun 9, 2020
f2f9547
Merge branch 'master' into block-number-check
Tbaut Jun 10, 2020
063bc5f
timestamps and permissions
niklabh Jun 10, 2020
3102623
added relationship
niklabh Jun 10, 2020
d71907b
added @ardatan/graphql-tools
niklabh Jun 10, 2020
47c2890
Merge branch 'master' into block-number-check
niklabh Jun 10, 2020
7ee6a99
added permission
niklabh Jun 10, 2020
b71cfac
removed unused relationship
niklabh Jun 10, 2020
0d8240a
prevent poll vote when finished (#878)
Tbaut Jun 10, 2020
2a013e8
Merge branch 'master' into block-number-check
Tbaut Jun 10, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions front-end/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"Thibaut Sardan"
],
"dependencies": {
"@ardatan/graphql-tools": "^4.1.0",
"@polkadot/api": "^1.18.1",
"@polkadot/extension-dapp": "^0.30.1",
"@polkadot/extension-inject": "^0.30.1",
Expand Down
34 changes: 6 additions & 28 deletions front-end/src/components/BlockCountdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.

import { ApiPromiseContext } from '@substrate/context';
import styled from '@xstyled/styled-components';
import BN from 'bn.js';
import React, { useContext, useEffect, useState } from 'react';
import React from 'react';
import { Popup } from 'semantic-ui-react';
import { chainProperties } from 'src/global/networkConstants';
import { useBlockTime } from 'src/hooks';
import useCurrentBlock from 'src/hooks/useCurrentBlock';
import blockToTime from 'src/util/blockToTime';
import getNetwork from 'src/util/getNetwork';

interface Props {
className?: string
Expand All @@ -22,31 +21,10 @@ const DivContent = styled.div`
`;

const BlockCountdown = ({ className, endBlock }:Props ) => {
const network = getNetwork();
const ZERO = new BN(0);
const { api, isApiReady } = useContext(ApiPromiseContext);
const [currentBlock, setCurrentBlock] = useState(ZERO);
const currentBlock = useCurrentBlock() || ZERO;
const blocksRemaining = endBlock - currentBlock.toNumber();
const DEFAULT_TIME = chainProperties?.[network]?.blockTime;
const [blocktime, setBlocktime] = useState(DEFAULT_TIME);

useEffect(() => {
if (!isApiReady) {
return;
}

let unsubscribe: () => void;

setBlocktime(api.consts.babe?.expectedBlockTime.toNumber());

api.derive.chain.bestNumber((number) => {
setCurrentBlock(number);
})
.then(unsub => {unsubscribe = unsub;})
.catch(e => console.error(e));

return () => unsubscribe && unsubscribe();
}, [api, isApiReady]);
const { blocktime } = useBlockTime();

return (
<Popup
Expand All @@ -59,4 +37,4 @@ const BlockCountdown = ({ className, endBlock }:Props ) => {
);
};

export default BlockCountdown;
export default BlockCountdown;
26 changes: 6 additions & 20 deletions front-end/src/components/BlocksToTime.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
// Copyright 2019-2020 @paritytech/polkassembly authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiPromiseContext } from '@substrate/context';

import styled from '@xstyled/styled-components';
import BN from 'bn.js';
import React, { useContext, useState } from 'react';
import { useEffect } from 'react';
import React from 'react';
import { Popup } from 'semantic-ui-react';
import { chainProperties } from 'src/global/networkConstants';
import { useBlockTime } from 'src/hooks';
import blockToTime from 'src/util/blockToTime';
import getNetwork from 'src/util/getNetwork';

interface Props {
blocks: number | BN;
Expand All @@ -22,29 +20,17 @@ const DivContent = styled.div`
`;

const BlocksToTime = ({ blocks, className }:Props ) => {
const network = getNetwork();
const { api, isApiReady } = useContext(ApiPromiseContext);
const DEFAULT_TIME = chainProperties?.[network]?.blockTime;
const [blocktime, setBlocktime] = useState(DEFAULT_TIME);

useEffect(() => {

if (!isApiReady) {
return;
}

setBlocktime(api.consts.babe?.expectedBlockTime.toNumber());
}, [ api, isApiReady]);
const { blocktime } = useBlockTime();

return (
<Popup
className={className}
trigger={<div>{blockToTime(blocks , blocktime)}</div>}
trigger={<div>{blockToTime(blocks, blocktime)}</div>}
content={<DivContent>{`${blocks} blocks`}</DivContent>}
hoverable={true}
position='top left'
/>
);
};

export default BlocksToTime;
export default BlocksToTime;
59 changes: 31 additions & 28 deletions front-end/src/components/Post/Poll/CouncilSignals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.

import { DeriveElectionsInfo } from '@polkadot/api-derive/types';
import { ApiPromiseContext } from '@substrate/context';
import { QueryResult } from '@apollo/react-common';
import styled from '@xstyled/styled-components';
import React, { useContext, useEffect, useState } from 'react';
import React, { useEffect, useState } from 'react';
import { Grid, Icon } from 'semantic-ui-react';
import useCurrentBlock from 'src/hooks/useCurrentBlock';
import HelperTooltip from 'src/ui-components/HelperTooltip';

import { PostVotesQuery } from '../../../generated/graphql';
import { CouncilAtBlockNumberQuery, CouncilAtBlockNumberQueryVariables, PollVotesQuery, useCouncilAtBlockNumberQuery } from '../../../generated/graphql';
import { OffchainVote, Vote } from '../../../types';
import Address from '../../../ui-components/Address';
import Card from '../../../ui-components/Card';
Expand All @@ -19,48 +19,51 @@ import getEncodedAddress from '../../../util/getEncodedAddress';

interface Props {
className?: string
data?: PostVotesQuery | undefined
data?: PollVotesQuery | undefined
endBlock: number
}

const CouncilSignals = ({ className, data }: Props) => {
const CouncilSignals = ({ className, endBlock, data }: Props) => {
const [ayes, setAyes] = useState(0);
const [nays, setNays] = useState(0);
const [memberSet, setMemberSet] = useState<Set<string>>(new Set<string>());
const [councilVotes, setCouncilVotes] = useState<OffchainVote[]>([]);
const { api, isApiReady } = useContext(ApiPromiseContext);
const currentBlockNumber = useCurrentBlock()?.toNumber() || endBlock;

useEffect(() => {
if (!isApiReady){
return;
}

let unsubscribe: () => void;
const councilAtPollEndBlockNumber = useCouncilAtBlockNumberQuery({ variables: { blockNumber: endBlock } });
const councilAtCurrentBlockNumber = useCouncilAtBlockNumberQuery({ variables: { blockNumber: currentBlockNumber } });

api.derive.elections.info((info: DeriveElectionsInfo) => {
const memberSet = new Set<string>();
const getCouncilMembers = (councilAtBlockNumber: QueryResult<CouncilAtBlockNumberQuery, CouncilAtBlockNumberQueryVariables>): Set<string> => {
const memberSet = new Set<string>();
councilAtBlockNumber?.data?.councils?.[0]?.members?.forEach((member) => {
const address = getEncodedAddress(member.address);
if (address) {
memberSet.add(address);
}
});
return memberSet;
};

info?.members.map(([accountId]) => {
const address = getEncodedAddress(accountId.toString());
if (address) {
memberSet.add(address);
}
});
useEffect(() => {
const pollClosingBlockNumber = endBlock;
let memberSet = new Set<string>();

setMemberSet(memberSet);
})
.then(unsub => { unsubscribe = unsub; })
.catch(e => console.error(e));
if (pollClosingBlockNumber > currentBlockNumber) {
memberSet = getCouncilMembers(councilAtCurrentBlockNumber);
} else {
memberSet = getCouncilMembers(councilAtPollEndBlockNumber);
}

return () => unsubscribe && unsubscribe();
}, [api, isApiReady]);
setMemberSet(memberSet);
}, [endBlock, currentBlockNumber, councilAtPollEndBlockNumber, councilAtCurrentBlockNumber]);

useEffect(() => {
let ayes = 0;
let nays = 0;
const defaultAddressField = getDefaultAddressField();
const councilVotes: OffchainVote[] = [];

data?.post_votes?.forEach(({ vote, voter }) => {
data?.poll_votes?.forEach(({ vote, voter }) => {
const defaultAddress = voter?.[defaultAddressField];

if (defaultAddress && memberSet.has(defaultAddress)) {
Expand Down
33 changes: 19 additions & 14 deletions front-end/src/components/Post/Poll/GeneralSignals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
import styled from '@xstyled/styled-components';
import { ApolloQueryResult } from 'apollo-client';
import React, { useCallback, useContext, useState } from 'react';
import useCurrentBlock from 'src/hooks/useCurrentBlock';
import ButtonLink from 'src/ui-components/ButtonLink';
import HelperTooltip from 'src/ui-components/HelperTooltip';

import { UserDetailsContext } from '../../../context/UserDetailsContext';
import { PostVotesQuery, PostVotesQueryVariables, useAddPostVoteMutation, useDeleteVoteMutation } from '../../../generated/graphql';
import { PollVotesQuery, PollVotesQueryVariables, useAddPollVoteMutation, useDeleteVoteMutation } from '../../../generated/graphql';
import { Vote } from '../../../types';
import AyeNayButtons from '../../../ui-components/AyeNayButtons';
import Card from '../../../ui-components/Card';
Expand All @@ -20,17 +21,20 @@ import GeneralChainSignalBar from '../../../ui-components/GeneralChainSignalBar'
interface Props {
ayes: number,
className?: string,
ownVote?: Vote | null,
endBlock: number
nays: number,
postId: number
refetch: (variables?: PostVotesQueryVariables | undefined) => Promise<ApolloQueryResult<PostVotesQuery>>
ownVote?: Vote | null,
pollId: number
refetch: (variables?: PollVotesQueryVariables | undefined) => Promise<ApolloQueryResult<PollVotesQuery>>
}

const CouncilSignals = ({ className, ayes, ownVote, nays, postId, refetch }: Props) => {
const CouncilSignals = ({ ayes, className, endBlock, nays, ownVote, pollId, refetch }: Props) => {
const { id } = useContext(UserDetailsContext);
const [error, setErr] = useState<Error | null>(null);
const [addPostVoteMutation] = useAddPostVoteMutation();
const [addPollVoteMutation] = useAddPollVoteMutation();
const [deleteVoteMutation] = useDeleteVoteMutation();
const currentBlockNumber = useCurrentBlock()?.toNumber() || 0;
const canVote = endBlock > currentBlockNumber;

const cancelVote = useCallback(async () => {
if (!id) {
Expand All @@ -40,7 +44,7 @@ const CouncilSignals = ({ className, ayes, ownVote, nays, postId, refetch }: Pro
try {
await deleteVoteMutation({
variables: {
postId,
pollId,
userId: id
}
});
Expand All @@ -49,17 +53,17 @@ const CouncilSignals = ({ className, ayes, ownVote, nays, postId, refetch }: Pro
} catch (error) {
setErr(error);
}
}, [id, deleteVoteMutation, postId, refetch]);
}, [id, deleteVoteMutation, pollId, refetch]);

const castVote = useCallback(async (vote: Vote) => {
if (!id) {
return;
}

try {
await addPostVoteMutation({
await addPollVoteMutation({
variables: {
postId,
pollId,
userId: id,
vote
}
Expand All @@ -69,7 +73,7 @@ const CouncilSignals = ({ className, ayes, ownVote, nays, postId, refetch }: Pro
} catch (error) {
setErr(error);
}
}, [id, addPostVoteMutation, postId, refetch]);
}, [id, addPollVoteMutation, pollId, refetch]);

return (
<Card className={className}>
Expand All @@ -84,11 +88,12 @@ const CouncilSignals = ({ className, ayes, ownVote, nays, postId, refetch }: Pro
<Form standalone={false}>
<AyeNayButtons
className={`signal-btns ${ownVote}`}
disabled={!id || !!ownVote}
disabled={!id || !!ownVote || !canVote}
onClickAye={() => castVote(Vote.AYE)}
onClickNay={() => castVote(Vote.NAY)}
/>
{ownVote &&
{!canVote && <span>Poll finished</span>}
{ownVote && canVote &&
<ButtonLink className='info text-muted' onClick={cancelVote}>Cancel {ownVote.toLowerCase()} vote</ButtonLink>
}
</Form>
Expand Down Expand Up @@ -122,4 +127,4 @@ export default styled(CouncilSignals)`
opacity: 1 !important;
}
}
`;
`;
56 changes: 56 additions & 0 deletions front-end/src/components/Post/Poll/Poll.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2019-2020 @paritytech/polkassembly authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.

import React, { useContext } from 'react';

import { UserDetailsContext } from '../../../context/UserDetailsContext';
import { usePollVotesQuery } from '../../../generated/graphql';
import { Vote } from '../../../types';
import Card from '../../../ui-components/Card';
import FilteredError from '../../../ui-components/FilteredError';
import CouncilSignals from './CouncilSignals';
import GeneralSignals from './GeneralSignals';

interface Props {
pollId: number
endBlock: number
}

const Poll = ({ pollId, endBlock }: Props) => {
const { id } = useContext(UserDetailsContext);
const { data, error, refetch } = usePollVotesQuery({ variables: { pollId } });
let ayes = 0;
let nays = 0;
let ownVote: Vote | null = null;

data?.poll_votes?.forEach(({ vote, voter }) => {
if (voter?.id === id) {
ownVote = vote;
}
if (vote === Vote.AYE) {
ayes++;
}
if (vote === Vote.NAY) {
nays++;
}
});

if (error?.message) return <Card><FilteredError text={error.message}/></Card>;

return (
<>
<GeneralSignals
ayes={ayes}
endBlock={endBlock}
nays={nays}
ownVote={ownVote}
pollId={pollId}
refetch={refetch}
/>
<CouncilSignals data={data} endBlock={endBlock} />
</>
);
};

export default Poll;