Skip to content

Commit

Permalink
Adding polling comments & Removing votes from ballot (#272)
Browse files Browse the repository at this point in the history
* Adding polling comments

* Multistep sign comments

* Working on removing ballot

* Prettier

* Link to the commenter page

* Refactor comments into it's own module, bring address data from the comments API call, include correct address balance , fix executive contract deposit refresh UI

* fix build

* Refactor vote modal

* Default view fixes

* small fixes

* prettier

* fix tests

* Document poll tally api

* updated swaggers

* Add transaction hash to comment

* prettier

* Reuse same comment box with limit at 250 characters and limit to 1 comment per address. Show polling comment option

* comment count on  executives

* comments on polls

* fix build
  • Loading branch information
rafinskipg authored Dec 15, 2021
1 parent 095b31e commit c5e911a
Show file tree
Hide file tree
Showing 61 changed files with 2,296 additions and 1,044 deletions.
1 change: 0 additions & 1 deletion __tests__/pages/executive.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ describe('Executive page', () => {
click(submitButton);

// wait for transaction to progress
await screen.findByText('Confirm Transaction');
await screen.findByText('Transaction Sent');
await screen.findByText('Close');
});
Expand Down
2 changes: 1 addition & 1 deletion lib/maker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function isTestnet(): boolean {
return getNetwork() === SupportedNetworks.TESTNET || !!config.TESTNET;
}

async function personalSign(message) {
async function personalSign(message: string): Promise<any> {
const maker = await getMaker();
const provider = maker.service('web3')._web3.currentProvider;
const from = maker.currentAddress();
Expand Down
48 changes: 48 additions & 0 deletions modules/address/api/getAddressInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { SupportedNetworks } from 'lib/constants';
import getMaker from 'lib/maker';
import { fetchDelegate } from 'modules/delegates/api/fetchDelegates';
import { AddressApiResponse } from '../types/addressApiResponse';
import voteProxyFactoryAbi from 'lib/abis/voteProxyAbi.json';

export async function getAddressInfo(
address: string,
network: SupportedNetworks
): Promise<AddressApiResponse> {
const maker = await getMaker(network);
const voteProxyContract = maker
.service('smartContract')
.getContractByAddressAndAbi(address, voteProxyFactoryAbi);

// TODO: should we check cold for history?
let hot;
let cold;
let voteProxyAddress;
try {
hot = await voteProxyContract.hot();
cold = await voteProxyContract.cold();
voteProxyAddress = address;
} catch (err) {
// console.log(err);
}

const voteProxyInfo =
hot && cold && voteProxyAddress
? {
voteProxyAddress,
hot,
cold
}
: undefined;

const delegate = await fetchDelegate(address, network);

const response: AddressApiResponse = {
isDelegate: !!delegate,
isProxyContract: !!hot,
voteProxyInfo,
delegateInfo: delegate,
address
};

return response;
}
55 changes: 3 additions & 52 deletions modules/address/components/AddressDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import React from 'react';
import { Box, Text, Link as ExternalLink, Flex, Divider } from 'theme-ui';
import { Icon } from '@makerdao/dai-ui-icons';
import { Box, Text, Flex, Divider } from 'theme-ui';
import { getNetwork } from 'lib/maker';
import { getEtherscanLink } from 'lib/utils';
import AddressIcon from './AddressIcon';
import { PollVoteHistoryList } from 'modules/polling/components/PollVoteHistoryList';
import { AddressAPIStats, VoteProxyInfo } from '../types/addressApiResponse';
import Tooltip from 'modules/app/components/Tooltip';
import { PollingParticipationOverview } from 'modules/polling/components/PollingParticipationOverview';
import { Address } from './Address';
import useSWR from 'swr';
import { fetchJson } from 'lib/fetchJson';
import LastVoted from 'modules/polling/components/LastVoted';
import AddressDelegatedTo from './AddressDelegatedTo';
import { MKRDelegatedToAPIResponse } from 'pages/api/address/[address]/delegated-to';
import SkeletonThemed from 'modules/app/components/SkeletonThemed';
import { AddressMKRDelegatedStats } from './AddressMKRDelegatedStats';
import AddressIconBox from './AddressIconBox';

type PropTypes = {
address: string;
Expand Down Expand Up @@ -43,19 +39,6 @@ export function AddressDetail({ address, voteProxyInfo }: PropTypes): React.Reac
}
);

const tooltipLabel = voteProxyInfo ? (
<Box sx={{ p: 2 }}>
<Text as="p">
<Text sx={{ fontWeight: 'bold' }}>Contract:</Text> {voteProxyInfo.voteProxyAddress}
</Text>
<Text as="p">
<Text sx={{ fontWeight: 'bold' }}>Hot:</Text> {voteProxyInfo.hot}
</Text>
<Text as="p">
<Text sx={{ fontWeight: 'bold' }}>Cold:</Text> {voteProxyInfo.cold}
</Text>
</Box>
) : null;
return (
<Box sx={{ variant: 'cards.primary', p: [0, 0] }}>
<Flex
Expand All @@ -66,39 +49,7 @@ export function AddressDetail({ address, voteProxyInfo }: PropTypes): React.Reac
p: [3, 4]
}}
>
<Flex>
<Box sx={{ width: '52px', mr: 2 }}>
<AddressIcon address={address} width="52px" />
</Box>
<Flex
sx={{
ml: 2,
width: '100%',
flexDirection: 'column',
justifyContent: 'center'
}}
>
<ExternalLink
title="View on etherscan"
href={getEtherscanLink(getNetwork(), address, 'address')}
target="_blank"
>
<Text as="p" sx={{ fontSize: [1, 3], ml: 2 }}>
<Address address={address} />
</Text>
</ExternalLink>
{voteProxyInfo && (
<Flex>
<Text sx={{ color: 'textSecondary', ml: 2, fontSize: [1, 2] }}>Proxy Contract</Text>{' '}
<Tooltip label={tooltipLabel}>
<Box>
<Icon name="question" ml={2} mt={['2px', '4px']} />
</Box>
</Tooltip>{' '}
</Flex>
)}
</Flex>
</Flex>
<AddressIconBox address={address} voteProxyInfo={voteProxyInfo} showExternalLink />

<Box sx={{ pt: [2, 0] }}>
<LastVoted expired={false} date={statsData?.lastVote?.blockTimestamp || ''} />
Expand Down
78 changes: 78 additions & 0 deletions modules/address/components/AddressIconBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from 'react';
import AddressIcon from './AddressIcon';
import { Box, Text, Link as ExternalLink, Flex } from 'theme-ui';
import { Icon } from '@makerdao/dai-ui-icons';
import { getNetwork } from 'lib/maker';
import { getEtherscanLink } from 'lib/utils';
import { Address } from './Address';
import Tooltip from 'modules/app/components/Tooltip';
import { VoteProxyInfo } from '../types/addressApiResponse';

type PropTypes = {
address: string;
voteProxyInfo?: VoteProxyInfo;
showExternalLink: boolean;
};

export default function AddressIconBox({
address,
voteProxyInfo,
showExternalLink
}: PropTypes): React.ReactElement {
const tooltipLabel = voteProxyInfo ? (
<Box sx={{ p: 2 }}>
<Text as="p">
<Text sx={{ fontWeight: 'bold' }}>Contract:</Text> {voteProxyInfo.voteProxyAddress}
</Text>
<Text as="p">
<Text sx={{ fontWeight: 'bold' }}>Hot:</Text> {voteProxyInfo.hot}
</Text>
<Text as="p">
<Text sx={{ fontWeight: 'bold' }}>Cold:</Text> {voteProxyInfo.cold}
</Text>
</Box>
) : null;

return (
<Flex>
<Box sx={{ width: '41px', mr: 2 }}>
<AddressIcon address={address} width="41px" />
</Box>
<Flex
sx={{
ml: 2,
width: '100%',
flexDirection: 'column',
justifyContent: 'center'
}}
>
<Flex>
<Text>
<Address address={address} />
</Text>
{showExternalLink && (
<ExternalLink
title="View on etherscan"
href={getEtherscanLink(getNetwork(), address, 'address')}
target="_blank"
>
<Text as="p" sx={{ fontSize: [1, 3], ml: 1 }}>
<Icon ml={2} name="arrowTopRight" size={2} />
</Text>
</ExternalLink>
)}
</Flex>
{voteProxyInfo && (
<Flex>
<Text sx={{ color: 'textSecondary', ml: 2, fontSize: [1, 2] }}>Proxy Contract</Text>{' '}
<Tooltip label={tooltipLabel}>
<Box>
<Icon name="question" ml={2} mt={['2px', '4px']} />
</Box>
</Tooltip>{' '}
</Flex>
)}
</Flex>
</Flex>
);
}
13 changes: 13 additions & 0 deletions modules/app/components/Icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,19 @@ const icons = {
</g>
),
viewBox: '0 0 12 11'
},
comment: {
viewBox: '0 0 12 12',
path: (
<g>
<path
d="M8.95379 1.02542H3.59317C2.18598 1.02542 1.04688 2.1646 1.04688 3.57171V6.65407C1.04688 7.9674 2.05199 9.05295 3.32511 9.18697L3.35194 10.9828C3.35194 11.09 3.41897 11.1704 3.49937 11.2239C3.53956 11.2373 3.57976 11.2508 3.61996 11.2508C3.67352 11.2508 3.74055 11.2374 3.78075 11.1972L6.36725 9.20034H8.95375C10.3609 9.20034 11.5 8.06116 11.5 6.65404V3.57169C11.5 2.1645 10.361 1.02539 8.95375 1.02539L8.95379 1.02542ZM10.964 6.65407C10.964 7.7664 10.0661 8.66431 8.95379 8.66431H6.27348C6.21992 8.66431 6.15289 8.67767 6.11269 8.71787L3.88801 10.4333L3.86118 8.93232C3.86118 8.7849 3.74059 8.66431 3.59317 8.66431C2.48084 8.66431 1.58294 7.76641 1.58294 6.65408V3.57172C1.58294 2.45939 2.48084 1.56149 3.59317 1.56149H8.95379C10.0661 1.56149 10.964 2.45939 10.964 3.57172L10.964 6.65407Z"
fill="#1AAB9B"
stroke="#1AAB9B"
strokeWidth="0.7"
/>
</g>
)
}
};

Expand Down
1 change: 1 addition & 0 deletions modules/app/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
30 changes: 3 additions & 27 deletions modules/app/stores/accounts.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import create from 'zustand';
import getMaker from 'lib/maker';
import oldVoteProxyFactoryAbi from 'lib/abis/oldVoteProxyFactoryAbi.json';
import { getNetwork } from 'lib/maker';
import { oldVoteProxyFactoryAddress, SupportedNetworks } from 'lib/constants';
import getMaker, { getNetwork } from 'lib/maker';
import { Account } from 'modules/app/types/account';
import { OldVoteProxyContract, VoteProxyContract } from 'modules/app/types/voteProxyContract';
import { VoteDelegateContract } from 'modules/delegates/types/voteDelegateContract';

export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
import { getOldProxyStatus } from 'modules/mkr/lib/getOldProxyStatus';

type Store = {
currentAccount?: Account;
Expand All @@ -19,26 +15,6 @@ type Store = {
disconnectAccount: () => Promise<void>;
};

const getOldProxyStatus = async (address, maker) => {
if (getNetwork() === SupportedNetworks.GOERLI) {
return { role: '', address: '' };
}
try {
const oldFactory = maker
.service('smartContract')
.getContractByAddressAndAbi(oldVoteProxyFactoryAddress[getNetwork()], oldVoteProxyFactoryAbi);
const [proxyAddressCold, proxyAddressHot] = await Promise.all([
oldFactory.coldMap(address),
oldFactory.hotMap(address)
]);
if (proxyAddressCold !== ZERO_ADDRESS) return { role: 'cold', address: proxyAddressCold };
if (proxyAddressHot !== ZERO_ADDRESS) return { role: 'hot', address: proxyAddressHot };
} catch (err) {
console.log(err);
}
return { role: '', address: '' };
};

const [useAccountsStore, accountsApi] = create<Store>((set, get) => ({
currentAccount: undefined,
proxies: {},
Expand All @@ -55,7 +31,7 @@ const [useAccountsStore, accountsApi] = create<Store>((set, get) => ({
const { address } = account;
const [{ hasProxy, voteProxy }, oldProxy] = await Promise.all([
maker.service('voteProxy').getVoteProxy(address),
getOldProxyStatus(address, maker)
getOldProxyStatus(address, maker, getNetwork())
]);

await get().setVoteDelegate(address);
Expand Down
8 changes: 0 additions & 8 deletions modules/app/stores/uiFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ type Store = {
resetPollFilters: () => void;
executiveSortBy: 'Date Posted' | 'MKR Amount';
setExecutiveSortBy: (method: 'Date Posted' | 'MKR Amount') => void;
commentSortBy: 'Latest' | 'Oldest' | 'MKR Amount';
setCommentSortBy: (address: 'Latest' | 'Oldest' | 'MKR Amount') => void;
};

const [useUiFiltersStore] = create<Store>((set, get) => ({
Expand Down Expand Up @@ -84,12 +82,6 @@ const [useUiFiltersStore] = create<Store>((set, get) => ({

setExecutiveSortBy: sortMethod => {
set({ executiveSortBy: sortMethod });
},

commentSortBy: 'Latest',

setCommentSortBy: (sortMethod: 'Latest' | 'Oldest' | 'MKR Amount') => {
set({ commentSortBy: sortMethod });
}
}));

Expand Down
7 changes: 0 additions & 7 deletions modules/app/types/comment.d.ts

This file was deleted.

46 changes: 46 additions & 0 deletions modules/comments/api/getExecutiveComments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { connectToDatabase } from 'lib/api/utils';
import { SupportedNetworks } from 'lib/constants';
import invariant from 'tiny-invariant';

import uniqBy from 'lodash/uniqBy';
import { ExecutiveComment, ExecutiveCommentFromDB } from '../types/executiveComment';
import { getAddressInfo } from 'modules/address/api/getAddressInfo';
import { ExecutiveCommentsAPIResponseItem } from '../types/comments';

export async function getExecutiveComments(
spellAddress: string,
network: SupportedNetworks
): Promise<ExecutiveCommentsAPIResponseItem[]> {
const { db, client } = await connectToDatabase();

invariant(await client.isConnected(), 'mongo client failed to connect');

const collection = db.collection('executiveComments');
// decending sort
const commentsFromDB: ExecutiveCommentFromDB[] = await collection
.find({ spellAddress, network })
.sort({ date: -1 })
.toArray();

const comments: ExecutiveComment[] = commentsFromDB.map(comment => {
const { _id, ...rest } = comment;
return rest;
});

// only return the latest comment from each address
const uniqueComments = uniqBy(comments, 'voterAddress');

const promises = uniqueComments.map(async comment => {
return {
comment,
address: await getAddressInfo(
comment.delegateAddress ? comment.delegateAddress : comment.voterAddress,
network
)
};
});

const response = await Promise.all(promises);

return response as ExecutiveCommentsAPIResponseItem[];
}
Loading

0 comments on commit c5e911a

Please sign in to comment.